diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86.td | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FixupLEAs.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86SchedPredicates.td | 49 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Schedule.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ScheduleBtVer2.td | 35 |
7 files changed, 89 insertions, 14 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index a9d3af3870d..d030f26d98d 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -39,6 +39,7 @@ using namespace llvm; #include "X86GenRegisterInfo.inc" #define GET_INSTRINFO_MC_DESC +#define GET_GENINSTRINFO_MC_HELPERS #include "X86GenInstrInfo.inc" #define GET_SUBTARGETINFO_MC_DESC diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h index 300a74bfedd..595c26d31e3 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h @@ -134,6 +134,7 @@ unsigned getX86SubSuperRegisterOrZero(unsigned, unsigned, // Defines symbolic names for the X86 instructions. // #define GET_INSTRINFO_ENUM +#define GET_GENINSTRINFO_MC_DECL #include "X86GenInstrInfo.inc" #define GET_SUBTARGETINFO_ENUM diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index d92fd677829..63c2dc4da6c 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -402,6 +402,7 @@ include "X86RegisterBanks.td" include "X86Schedule.td" include "X86InstrInfo.td" +include "X86SchedPredicates.td" def X86InstrInfo : InstrInfo; diff --git a/llvm/lib/Target/X86/X86FixupLEAs.cpp b/llvm/lib/Target/X86/X86FixupLEAs.cpp index 157b07d819b..d85389a0a7f 100644 --- a/llvm/lib/Target/X86/X86FixupLEAs.cpp +++ b/llvm/lib/Target/X86/X86FixupLEAs.cpp @@ -286,6 +286,8 @@ static inline bool isRegOperand(const MachineOperand &Op) { } /// hasIneffecientLEARegs - LEA that uses base and index registers /// where the base is EBP, RBP, or R13 +// TODO: use a variant scheduling class to model the latency profile +// of LEA instructions, and implement this logic as a scheduling predicate. static inline bool hasInefficientLEABaseReg(const MachineOperand &Base, const MachineOperand &Index) { return Base.isReg() && isInefficientLEAReg(Base.getReg()) && @@ -296,13 +298,6 @@ static inline bool hasLEAOffset(const MachineOperand &Offset) { return (Offset.isImm() && Offset.getImm() != 0) || Offset.isGlobal(); } -// LEA instruction that has all three operands: offset, base and index -static inline bool isThreeOperandsLEA(const MachineOperand &Base, - const MachineOperand &Index, - const MachineOperand &Offset) { - return isRegOperand(Base) && isRegOperand(Index) && hasLEAOffset(Offset); -} - static inline int getADDrrFromLEA(int LEAOpcode) { switch (LEAOpcode) { default: @@ -477,7 +472,7 @@ FixupLEAPass::processInstrForSlow3OpLEA(MachineInstr &MI, const MachineOperand &Offset = MI.getOperand(4); const MachineOperand &Segment = MI.getOperand(5); - if (!(isThreeOperandsLEA(Base, Index, Offset) || + if (!(TII->isThreeOperandsLEA(MI) || hasInefficientLEABaseReg(Base, Index)) || !TII->isSafeToClobberEFLAGS(*MFI, MI) || Segment.getReg() != X86::NoRegister) diff --git a/llvm/lib/Target/X86/X86SchedPredicates.td b/llvm/lib/Target/X86/X86SchedPredicates.td new file mode 100644 index 00000000000..27aaeb19358 --- /dev/null +++ b/llvm/lib/Target/X86/X86SchedPredicates.td @@ -0,0 +1,49 @@ +//===-- X86SchedPredicates.td - X86 Scheduling Predicates --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines scheduling predicate definitions that are common to +// all X86 subtargets. +// +//===----------------------------------------------------------------------===// + +// A predicate used to identify dependency-breaking instructions that clear the +// content of the destination register. Note that this predicate only checks if +// input registers are the same. This predicate doesn't make any assumptions on +// the expected instruction opcodes, because different processors may implement +// different zero-idioms. +def ZeroIdiomPredicate : CheckSameRegOperand<1, 2>; + +// A predicate used to check if an instruction is a LEA, and if it uses all +// three source operands: base, index, and offset. +def IsThreeOperandsLEAPredicate: CheckAll<[ + CheckOpcode<[LEA32r, LEA64r, LEA64_32r, LEA16r]>, + + // isRegOperand(Base) + CheckIsRegOperand<1>, + CheckNot<CheckInvalidRegOperand<1>>, + + // isRegOperand(Index) + CheckIsRegOperand<3>, + CheckNot<CheckInvalidRegOperand<3>>, + + // hasLEAOffset(Offset) + CheckAny<[ + CheckAll<[ + CheckIsImmOperand<4>, + CheckNot<CheckZeroOperand<4>> + ]>, + CheckNonPortable<"MI.getOperand(4).isGlobal()"> + ]> +]>; + +// This predicate evaluates to true only if the input machine instruction is a +// 3-operands LEA. Tablegen automatically generates a new method for it in +// X86GenInstrInfo. +def IsThreeOperandsLEAFn : + TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEAPredicate>; diff --git a/llvm/lib/Target/X86/X86Schedule.td b/llvm/lib/Target/X86/X86Schedule.td index f5f1bb96de4..270acb3c398 100644 --- a/llvm/lib/Target/X86/X86Schedule.td +++ b/llvm/lib/Target/X86/X86Schedule.td @@ -618,11 +618,6 @@ def SchedWriteFShuffleSizes : X86SchedWriteSizes<SchedWriteFShuffle, SchedWriteFShuffle>; //===----------------------------------------------------------------------===// -// Common MCInstPredicate definitions used by variant scheduling classes. - -def ZeroIdiomPredicate : CheckSameRegOperand<1, 2>; - -//===----------------------------------------------------------------------===// // Generic Processor Scheduler Models. // IssueWidth is analogous to the number of decode units. Core and its diff --git a/llvm/lib/Target/X86/X86ScheduleBtVer2.td b/llvm/lib/Target/X86/X86ScheduleBtVer2.td index 177aa01f1d4..d539a7f668d 100644 --- a/llvm/lib/Target/X86/X86ScheduleBtVer2.td +++ b/llvm/lib/Target/X86/X86ScheduleBtVer2.td @@ -187,7 +187,6 @@ def : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>; def : WriteRes<WriteLAHFSAHF, [JALU01]>; // This is for simple LEAs with one or two input operands. -// FIXME: SAGU 3-operand LEA def : WriteRes<WriteLEA, [JALU01]>; // Bit counts. @@ -664,4 +663,38 @@ def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr, PCMPGTDrr, VPCMPGTDrr, PCMPGTQrr, VPCMPGTQrr, PCMPGTWrr, VPCMPGTWrr)>; + +// This write is used for slow LEA instructions. +def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> { + let Latency = 2; +} + +// On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA +// with a `Scale` value different than 1. +def JSlowLEAPredicate : MCSchedPredicate< + CheckAny<[ + // A 3-operand LEA (base, index, offset). + IsThreeOperandsLEAFn, + // An LEA with a "Scale" different than 1. + CheckAll<[ + CheckIsImmOperand<2>, + CheckNot<CheckImmOperand<2, 1>> + ]> + ]> +>; + +def JWriteLEA : SchedWriteVariant<[ + SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>, + SchedVar<MCSchedPredicate<TruePred>, [WriteLEA]> +]>; + +def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>; + +def JSlowLEA16r : SchedWriteRes<[JALU01]> { + let Latency = 3; + let ResourceCycles = [4]; +} + +def : InstRW<[JSlowLEA16r], (instrs LEA16r)>; + } // SchedModel |