summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp1
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h1
-rw-r--r--llvm/lib/Target/X86/X86.td1
-rw-r--r--llvm/lib/Target/X86/X86FixupLEAs.cpp11
-rw-r--r--llvm/lib/Target/X86/X86SchedPredicates.td49
-rw-r--r--llvm/lib/Target/X86/X86Schedule.td5
-rw-r--r--llvm/lib/Target/X86/X86ScheduleBtVer2.td35
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
OpenPOWER on IntegriCloud