summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-09-19 15:57:45 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-09-19 15:57:45 +0000
commit8b6c314be1924c474fecdddca199fc8e702e273a (patch)
tree61eb37b98494368ab099eacbeb4034f6bc9727cc /llvm/lib/Target
parent4fd2e2a4980d3a0512524b8352669ef4aa9258a9 (diff)
downloadbcm5719-llvm-8b6c314be1924c474fecdddca199fc8e702e273a.tar.gz
bcm5719-llvm-8b6c314be1924c474fecdddca199fc8e702e273a.zip
[TableGen][SubtargetEmitter] Add the ability for processor models to describe dependency breaking instructions.
This patch adds the ability for processor models to describe dependency breaking instructions. Different processors may specify a different set of dependency-breaking instructions. That means, we cannot assume that all processors of the same target would use the same rules to classify dependency breaking instructions. The main goal of this patch is to provide the means to describe dependency breaking instructions directly via tablegen, and have the following TargetSubtargetInfo hooks redefined in overrides by tabegen'd XXXGenSubtargetInfo classes (here, XXX is a Target name). ``` virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { return false; } virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { return isZeroIdiom(MI); } ``` An instruction MI is a dependency-breaking instruction if a call to method isDependencyBreaking(MI) on the STI (TargetSubtargetInfo object) evaluates to true. Similarly, an instruction MI is a special case of zero-idiom dependency breaking instruction if a call to STI.isZeroIdiom(MI) returns true. The extra APInt is used for those targets that may want to select which machine operands have their dependency broken (see comments in code). Note that by default, subtargets don't know about the existence of dependency-breaking. In the absence of external information, those method calls would always return false. A new tablegen class named STIPredicate has been added by this patch to let processor models classify instructions that have properties in common. The idea is that, a MCInstrPredicate definition can be used to "generate" an instruction equivalence class, with the idea that instructions of a same class all have a property in common. STIPredicate definitions are essentially a collection of instruction equivalence classes. Also, different processor models can specify a different variant of the same STIPredicate with different rules (i.e. predicates) to classify instructions. Tablegen backends (in this particular case, the SubtargetEmitter) will be able to process STIPredicate definitions, and automatically generate functions in XXXGenSubtargetInfo. This patch introduces two special kind of STIPredicate classes named IsZeroIdiomFunction and IsDepBreakingFunction in tablegen. It also adds a definition for those in the BtVer2 scheduling model only. This patch supersedes the one committed at r338372 (phabricator review: D49310). The main advantages are: - We can describe subtarget predicates via tablegen using STIPredicates. - We can describe zero-idioms / dep-breaking instructions directly via tablegen in the scheduling models. In future, the STIPredicates framework can be used for solving other problems. Examples of future developments are: - Teach how to identify optimizable register-register moves - Teach how to identify slow LEA instructions (each subtarget defining its own concept of "slow" LEA). - Teach how to identify instructions that have undocumented false dependencies on the output registers on some processors only. It is also (in my opinion) an elegant way to expose knowledge to both external tools like llvm-mca, and codegen passes. For example, machine schedulers in LLVM could reuse that information when internally constructing the data dependency graph for a code region. This new design feature is also an "opt-in" feature. Processor models don't have to use the new STIPredicates. It has all been designed to be as unintrusive as possible. Differential Revision: https://reviews.llvm.org/D52174 llvm-svn: 342555
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp78
-rw-r--r--llvm/lib/Target/X86/X86ScheduleBtVer2.td62
2 files changed, 67 insertions, 73 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index bc682263975..362ca96ac09 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -380,8 +380,9 @@ class X86MCInstrAnalysis : public MCInstrAnalysis {
public:
X86MCInstrAnalysis(const MCInstrInfo *MCII) : MCInstrAnalysis(MCII) {}
- bool isDependencyBreaking(const MCSubtargetInfo &STI,
- const MCInst &Inst) const override;
+#define GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS
+#include "X86GenSubtargetInfo.inc"
+
bool clearsSuperRegisters(const MCRegisterInfo &MRI, const MCInst &Inst,
APInt &Mask) const override;
std::vector<std::pair<uint64_t, uint64_t>>
@@ -390,77 +391,8 @@ public:
const Triple &TargetTriple) const override;
};
-bool X86MCInstrAnalysis::isDependencyBreaking(const MCSubtargetInfo &STI,
- const MCInst &Inst) const {
- if (STI.getCPU() == "btver2") {
- // Reference: Agner Fog's microarchitecture.pdf - Section 20 "AMD Bobcat and
- // Jaguar pipeline", subsection 8 "Dependency-breaking instructions".
- switch (Inst.getOpcode()) {
- default:
- return false;
- case X86::SUB32rr:
- case X86::SUB64rr:
- case X86::SBB32rr:
- case X86::SBB64rr:
- case X86::XOR32rr:
- case X86::XOR64rr:
- case X86::XORPSrr:
- case X86::XORPDrr:
- case X86::VXORPSrr:
- case X86::VXORPDrr:
- case X86::ANDNPSrr:
- case X86::VANDNPSrr:
- case X86::ANDNPDrr:
- case X86::VANDNPDrr:
- case X86::PXORrr:
- case X86::VPXORrr:
- case X86::PANDNrr:
- case X86::VPANDNrr:
- case X86::PSUBBrr:
- case X86::PSUBWrr:
- case X86::PSUBDrr:
- case X86::PSUBQrr:
- case X86::VPSUBBrr:
- case X86::VPSUBWrr:
- case X86::VPSUBDrr:
- case X86::VPSUBQrr:
- case X86::PCMPEQBrr:
- case X86::PCMPEQWrr:
- case X86::PCMPEQDrr:
- case X86::PCMPEQQrr:
- case X86::VPCMPEQBrr:
- case X86::VPCMPEQWrr:
- case X86::VPCMPEQDrr:
- case X86::VPCMPEQQrr:
- case X86::PCMPGTBrr:
- case X86::PCMPGTWrr:
- case X86::PCMPGTDrr:
- case X86::PCMPGTQrr:
- case X86::VPCMPGTBrr:
- case X86::VPCMPGTWrr:
- case X86::VPCMPGTDrr:
- case X86::VPCMPGTQrr:
- case X86::MMX_PXORirr:
- case X86::MMX_PANDNirr:
- case X86::MMX_PSUBBirr:
- case X86::MMX_PSUBDirr:
- case X86::MMX_PSUBQirr:
- case X86::MMX_PSUBWirr:
- case X86::MMX_PCMPGTBirr:
- case X86::MMX_PCMPGTDirr:
- case X86::MMX_PCMPGTWirr:
- case X86::MMX_PCMPEQBirr:
- case X86::MMX_PCMPEQDirr:
- case X86::MMX_PCMPEQWirr:
- return Inst.getOperand(1).getReg() == Inst.getOperand(2).getReg();
- case X86::CMP32rr:
- case X86::CMP64rr:
- return Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg();
- }
- }
-
- return false;
-}
+#define GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS
+#include "X86GenSubtargetInfo.inc"
bool X86MCInstrAnalysis::clearsSuperRegisters(const MCRegisterInfo &MRI,
const MCInst &Inst,
diff --git a/llvm/lib/Target/X86/X86ScheduleBtVer2.td b/llvm/lib/Target/X86/X86ScheduleBtVer2.td
index 9b1a45467e2..af5ce7bbfe8 100644
--- a/llvm/lib/Target/X86/X86ScheduleBtVer2.td
+++ b/llvm/lib/Target/X86/X86ScheduleBtVer2.td
@@ -687,4 +687,66 @@ def JSlowLEA16r : SchedWriteRes<[JALU01]> {
def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
+///////////////////////////////////////////////////////////////////////////////
+// Dependency breaking instructions.
+///////////////////////////////////////////////////////////////////////////////
+
+def : IsZeroIdiomFunction<[
+ // GPR Zero-idioms.
+ DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
+
+ // MMX Zero-idioms.
+ DepBreakingClass<[
+ MMX_PXORirr, MMX_PANDNirr, MMX_PSUBBirr,
+ MMX_PSUBDirr, MMX_PSUBQirr, MMX_PSUBWirr,
+ MMX_PCMPGTBirr, MMX_PCMPGTDirr, MMX_PCMPGTWirr
+ ], ZeroIdiomPredicate>,
+
+ // SSE Zero-idioms.
+ DepBreakingClass<[
+ // fp variants.
+ XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
+
+ // int variants.
+ PXORrr, PANDNrr,
+ PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
+ PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
+ ], ZeroIdiomPredicate>,
+
+ // AVX Zero-idioms.
+ DepBreakingClass<[
+ // xmm fp variants.
+ VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
+
+ // xmm int variants.
+ VPXORrr, VPANDNrr,
+ VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
+ VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
+
+ // ymm variants.
+ VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
+ ], ZeroIdiomPredicate>
+]>;
+
+def : IsDepBreakingFunction<[
+ // GPR
+ DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
+ DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
+
+ // MMX
+ DepBreakingClass<[
+ MMX_PCMPEQBirr, MMX_PCMPEQDirr, MMX_PCMPEQWirr
+ ], ZeroIdiomPredicate>,
+
+ // SSE
+ DepBreakingClass<[
+ PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
+ ], ZeroIdiomPredicate>,
+
+ // AVX
+ DepBreakingClass<[
+ VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
+ ], ZeroIdiomPredicate>
+]>;
+
} // SchedModel
OpenPOWER on IntegriCloud