summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86MacroFusion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86MacroFusion.cpp')
-rw-r--r--llvm/lib/Target/X86/X86MacroFusion.cpp183
1 files changed, 12 insertions, 171 deletions
diff --git a/llvm/lib/Target/X86/X86MacroFusion.cpp b/llvm/lib/Target/X86/X86MacroFusion.cpp
index c6da4b09dd60..b19d1263e0c9 100644
--- a/llvm/lib/Target/X86/X86MacroFusion.cpp
+++ b/llvm/lib/Target/X86/X86MacroFusion.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "MCTargetDesc/X86BaseInfo.h"
#include "X86MacroFusion.h"
#include "X86Subtarget.h"
#include "llvm/CodeGen/MacroFusion.h"
@@ -18,160 +19,13 @@
using namespace llvm;
-namespace {
-
-// The classification for the first instruction.
-enum class FirstInstrKind { Test, Cmp, And, ALU, IncDec, Invalid };
-
-// The classification for the second instruction (jump).
-enum class JumpKind {
- // JE, JL, JG and variants.
- ELG,
- // JA, JB and variants.
- AB,
- // JS, JP, JO and variants.
- SPO,
- // Not a fusable jump.
- Invalid,
-};
-
-} // namespace
-
-static FirstInstrKind classifyFirst(const MachineInstr &MI) {
- switch (MI.getOpcode()) {
- default:
- return FirstInstrKind::Invalid;
- case X86::TEST8rr:
- case X86::TEST16rr:
- case X86::TEST32rr:
- case X86::TEST64rr:
- case X86::TEST8ri:
- case X86::TEST16ri:
- case X86::TEST32ri:
- case X86::TEST64ri32:
- case X86::TEST8mr:
- case X86::TEST16mr:
- case X86::TEST32mr:
- case X86::TEST64mr:
- return FirstInstrKind::Test;
- case X86::AND16ri:
- case X86::AND16ri8:
- case X86::AND16rm:
- case X86::AND16rr:
- case X86::AND32ri:
- case X86::AND32ri8:
- case X86::AND32rm:
- case X86::AND32rr:
- case X86::AND64ri32:
- case X86::AND64ri8:
- case X86::AND64rm:
- case X86::AND64rr:
- case X86::AND8ri:
- case X86::AND8rm:
- case X86::AND8rr:
- return FirstInstrKind::And;
- case X86::CMP16ri:
- case X86::CMP16ri8:
- case X86::CMP16rm:
- case X86::CMP16rr:
- case X86::CMP16mr:
- case X86::CMP32ri:
- case X86::CMP32ri8:
- case X86::CMP32rm:
- case X86::CMP32rr:
- case X86::CMP32mr:
- case X86::CMP64ri32:
- case X86::CMP64ri8:
- case X86::CMP64rm:
- case X86::CMP64rr:
- case X86::CMP64mr:
- case X86::CMP8ri:
- case X86::CMP8rm:
- case X86::CMP8rr:
- case X86::CMP8mr:
- return FirstInstrKind::Cmp;
- case X86::ADD16ri:
- case X86::ADD16ri8:
- case X86::ADD16ri8_DB:
- case X86::ADD16ri_DB:
- case X86::ADD16rm:
- case X86::ADD16rr:
- case X86::ADD16rr_DB:
- case X86::ADD32ri:
- case X86::ADD32ri8:
- case X86::ADD32ri8_DB:
- case X86::ADD32ri_DB:
- case X86::ADD32rm:
- case X86::ADD32rr:
- case X86::ADD32rr_DB:
- case X86::ADD64ri32:
- case X86::ADD64ri32_DB:
- case X86::ADD64ri8:
- case X86::ADD64ri8_DB:
- case X86::ADD64rm:
- case X86::ADD64rr:
- case X86::ADD64rr_DB:
- case X86::ADD8ri:
- case X86::ADD8ri_DB:
- case X86::ADD8rm:
- case X86::ADD8rr:
- case X86::ADD8rr_DB:
- case X86::SUB16ri:
- case X86::SUB16ri8:
- case X86::SUB16rm:
- case X86::SUB16rr:
- case X86::SUB32ri:
- case X86::SUB32ri8:
- case X86::SUB32rm:
- case X86::SUB32rr:
- case X86::SUB64ri32:
- case X86::SUB64ri8:
- case X86::SUB64rm:
- case X86::SUB64rr:
- case X86::SUB8ri:
- case X86::SUB8rm:
- case X86::SUB8rr:
- return FirstInstrKind::ALU;
- case X86::INC16r:
- case X86::INC32r:
- case X86::INC64r:
- case X86::INC8r:
- case X86::DEC16r:
- case X86::DEC32r:
- case X86::DEC64r:
- case X86::DEC8r:
- return FirstInstrKind::IncDec;
- }
+static X86::FirstMacroFusionInstKind classifyFirst(const MachineInstr &MI) {
+ return X86::classifyFirstOpcodeInMacroFusion(MI.getOpcode());
}
-static JumpKind classifySecond(const MachineInstr &MI) {
+static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) {
X86::CondCode CC = X86::getCondFromBranch(MI);
- if (CC == X86::COND_INVALID)
- return JumpKind::Invalid;
-
- switch (CC) {
- default:
- return JumpKind::Invalid;
- case X86::COND_E:
- case X86::COND_NE:
- case X86::COND_L:
- case X86::COND_LE:
- case X86::COND_G:
- case X86::COND_GE:
- return JumpKind::ELG;
- case X86::COND_B:
- case X86::COND_BE:
- case X86::COND_A:
- case X86::COND_AE:
- return JumpKind::AB;
- case X86::COND_S:
- case X86::COND_NS:
- case X86::COND_P:
- case X86::COND_NP:
- case X86::COND_O:
- case X86::COND_NO:
- return JumpKind::SPO;
- }
+ return X86::classifySecondCondCodeInMacroFusion(CC);
}
/// Check if the instr pair, FirstMI and SecondMI, should be fused
@@ -187,40 +41,27 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
if (!(ST.hasBranchFusion() || ST.hasMacroFusion()))
return false;
- const JumpKind BranchKind = classifySecond(SecondMI);
+ const X86::SecondMacroFusionInstKind BranchKind = classifySecond(SecondMI);
- if (BranchKind == JumpKind::Invalid)
+ if (BranchKind == X86::SecondMacroFusionInstKind::Invalid)
return false; // Second cannot be fused with anything.
if (FirstMI == nullptr)
return true; // We're only checking whether Second can be fused at all.
- const FirstInstrKind TestKind = classifyFirst(*FirstMI);
+ const X86::FirstMacroFusionInstKind TestKind = classifyFirst(*FirstMI);
if (ST.hasBranchFusion()) {
// Branch fusion can merge CMP and TEST with all conditional jumps.
- return (TestKind == FirstInstrKind::Cmp ||
- TestKind == FirstInstrKind::Test);
+ return (TestKind == X86::FirstMacroFusionInstKind::Cmp ||
+ TestKind == X86::FirstMacroFusionInstKind::Test);
}
if (ST.hasMacroFusion()) {
- // Macro Fusion rules are a bit more complex. See Agner Fog's
- // Microarchitecture table 9.2 "Instruction Fusion".
- switch (TestKind) {
- case FirstInstrKind::Test:
- case FirstInstrKind::And:
- return true;
- case FirstInstrKind::Cmp:
- case FirstInstrKind::ALU:
- return BranchKind == JumpKind::ELG || BranchKind == JumpKind::AB;
- case FirstInstrKind::IncDec:
- return BranchKind == JumpKind::ELG;
- case FirstInstrKind::Invalid:
- return false;
- }
+ return X86::isMacroFused(TestKind, BranchKind);
}
- llvm_unreachable("unknown branch fusion type");
+ llvm_unreachable("unknown fusion type");
}
namespace llvm {