diff options
author | Tim Northover <tnorthover@apple.com> | 2016-08-25 17:37:32 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-08-25 17:37:32 +0000 |
commit | 042ca5a33ab5acf8405024643a31cf006b5298b5 (patch) | |
tree | d306b730b015aec8f43473eb73d941394d4dc990 | |
parent | bbdb9c7d9b214b535b8c4ef9fe9a4ab1889a7652 (diff) | |
download | llvm-042ca5a33ab5acf8405024643a31cf006b5298b5.tar.gz |
GlobalISel: perform multi-step legalization
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279758 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 11 | ||||
-rw-r--r-- | include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp | 29 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64MachineLegalizer.cpp | 18 | ||||
-rw-r--r-- | test/CodeGen/AArch64/GlobalISel/legalize-add.mir | 3 | ||||
-rw-r--r-- | test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir | 6 |
7 files changed, 81 insertions, 3 deletions
diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index a067262bd682..cdd2c84f5934 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -21,6 +21,8 @@ #include "llvm/CodeGen/LowLevelType.h" #include "llvm/IR/DebugLoc.h" +#include <queue> + namespace llvm { // Forward declarations. @@ -47,6 +49,8 @@ class MachineIRBuilder { bool Before; /// @} + std::function<void(MachineInstr *)> InsertedInstr; + const TargetInstrInfo &getTII() { assert(TII && "TargetInstrInfo is not set"); return *TII; @@ -86,6 +90,13 @@ public: void setInstr(MachineInstr &MI, bool Before = true); /// @} + /// Control where instructions we create are recorded (typically for + /// visiting again later during legalization). + /// @{ + void recordInsertions(std::function<void(MachineInstr *)> InsertedInstr); + void stopRecordingInsertions(); + /// @} + /// Set the debug location to \p DL for all the next build instructions. void setDebugLoc(const DebugLoc &DL) { this->DL = DL; } diff --git a/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h b/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h index 9252dd94f0de..d2b1d88d5308 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h +++ b/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h @@ -55,6 +55,9 @@ public: /// /// Considered as an opaque blob, the legal code will use and define the same /// registers as \p MI. + LegalizeResult legalizeInstrStep(MachineInstr &MI, + const MachineLegalizer &Legalizer); + LegalizeResult legalizeInstr(MachineInstr &MI, const MachineLegalizer &Legalizer); diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 2cb7e6696e57..50896abbb0e9 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -26,6 +26,7 @@ void MachineIRBuilder::setMF(MachineFunction &MF) { this->TII = MF.getSubtarget().getInstrInfo(); this->DL = DebugLoc(); this->MI = nullptr; + this->InsertedInstr = nullptr; } void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) { @@ -53,6 +54,15 @@ MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() { return Before ? getMBB().begin() : getMBB().end(); } +void MachineIRBuilder::recordInsertions( + std::function<void(MachineInstr *)> Inserted) { + InsertedInstr = Inserted; +} + +void MachineIRBuilder::stopRecordingInsertions() { + InsertedInstr = nullptr; +} + //------------------------------------------------------------------------------ // Build instruction variants. //------------------------------------------------------------------------------ @@ -69,6 +79,8 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode, assert(!isPreISelGenericOpcode(Opcode) && "Generic instruction must have a type"); getMBB().insert(getInsertPt(), MIB); + if (InsertedInstr) + InsertedInstr(MIB); return MIB; } @@ -181,6 +193,8 @@ MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<LLT> ResTys, MIB.addImm(Idx); getMBB().insert(getInsertPt(), MIB); + if (InsertedInstr) + InsertedInstr(MIB); return MIB; } diff --git a/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index c7d30cf1f824..66b71668820b 100644 --- a/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -31,8 +31,9 @@ MachineLegalizeHelper::MachineLegalizeHelper(MachineFunction &MF) MIRBuilder.setMF(MF); } -MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr( - MachineInstr &MI, const MachineLegalizer &Legalizer) { +MachineLegalizeHelper::LegalizeResult +MachineLegalizeHelper::legalizeInstrStep(MachineInstr &MI, + const MachineLegalizer &Legalizer) { auto Action = Legalizer.getAction(MI); switch (std::get<0>(Action)) { case MachineLegalizer::Legal: @@ -48,6 +49,30 @@ MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr( } } +MachineLegalizeHelper::LegalizeResult +MachineLegalizeHelper::legalizeInstr(MachineInstr &MI, + const MachineLegalizer &Legalizer) { + std::queue<MachineInstr *> WorkList; + MIRBuilder.recordInsertions([&](MachineInstr *MI) { WorkList.push(MI); }); + WorkList.push(&MI); + + bool Changed = false; + LegalizeResult Res; + do { + Res = legalizeInstrStep(*WorkList.front(), Legalizer); + if (Res == UnableToLegalize) { + MIRBuilder.stopRecordingInsertions(); + return UnableToLegalize; + } + Changed |= Res == Legalized; + WorkList.pop(); + } while (!WorkList.empty()); + + MIRBuilder.stopRecordingInsertions(); + + return Changed ? Legalized : AlreadyLegal; +} + void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, SmallVectorImpl<unsigned> &VRegs) { unsigned Size = Ty.getSizeInBits(); diff --git a/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/lib/Target/AArch64/AArch64MachineLegalizer.cpp index f6bdbfb018d7..e6012aa1cef4 100644 --- a/lib/Target/AArch64/AArch64MachineLegalizer.cpp +++ b/lib/Target/AArch64/AArch64MachineLegalizer.cpp @@ -48,6 +48,10 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() { for (auto Ty : {s32, s64}) setAction({BinOp, Ty}, Legal); + for (auto Op : { G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULO, G_UMULO }) + for (auto Ty : { s32, s64 }) + setAction({Op, Ty}, Legal); + for (auto BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) for (auto Ty : {s32, s64}) setAction({BinOp, Ty}, Legal); @@ -99,6 +103,20 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() { setAction({G_ANYEXT, 1, Ty}, Legal); } + // Truncations + for (auto Ty : { s16, s32 }) + setAction({G_FPTRUNC, Ty}, Legal); + + for (auto Ty : { s32, s64 }) + setAction({G_FPTRUNC, 1, Ty}, Legal); + + for (auto Ty : { s1, s8, s16, s32 }) + setAction({G_TRUNC, Ty}, Legal); + + for (auto Ty : { s8, s16, s32, s64 }) + setAction({G_TRUNC, 1, Ty}, Legal); + + // Control-flow setAction({G_BR, LLT::unsized()}, Legal); setAction({G_BRCOND, s32}, Legal); diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-add.mir b/test/CodeGen/AArch64/GlobalISel/legalize-add.mir index 2184eb3ebc2c..924f758e58e5 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-add.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-add.mir @@ -29,7 +29,8 @@ body: | ; CHECK-LABEL: name: test_scalar_add_big ; CHECK-DAG: [[LHS_LO:%.*]](64), [[LHS_HI:%.*]](64) = G_EXTRACT { s64, s64, s128 } %0, 0, 64 ; CHECK-DAG: [[RHS_LO:%.*]](64), [[RHS_HI:%.*]](64) = G_EXTRACT { s64, s64, s128 } %1, 0, 64 - ; CHECK-DAG: [[CARRY0:%.*]](1) = G_CONSTANT s1 0 + ; CHECK-DAG: [[CARRY0_32:%.*]](32) = G_CONSTANT s32 0 + ; CHECK-DAG: [[CARRY0:%[0-9]+]](1) = G_TRUNC { s1, s32 } [[CARRY0_32]] ; CHECK: [[RES_LO:%.*]](64), [[CARRY:%.*]](1) = G_UADDE s64 [[LHS_LO]], [[RHS_LO]], [[CARRY0]] ; CHECK: [[RES_HI:%.*]](64), {{%.*}}(1) = G_UADDE s64 [[LHS_HI]], [[RHS_HI]], [[CARRY]] ; CHECK: %2(128) = G_SEQUENCE { s128, s64, s64 } [[RES_LO]], 0, [[RES_HI]], 64 diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir b/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir index d2be05a7849b..a73e5caf26db 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir @@ -20,6 +20,7 @@ registers: - { id: 5, class: _ } - { id: 6, class: _ } - { id: 7, class: _ } + - { id: 8, class: _ } body: | bb.0.entry: liveins: %x0, %x1, %x2, %x3 @@ -48,4 +49,9 @@ body: | ; CHECK: %7(32) = G_ICMP { s32, s32 } intpred(sle), [[LHS32]], [[RHS32]] %7(32) = G_ICMP { s32, s8 } intpred(sle), %2, %3 + ; CHECK: [[LHS32:%[0-9]+]](32) = G_ZEXT { s32, s8 } %2 + ; CHECK: [[RHS32:%[0-9]+]](32) = G_ZEXT { s32, s8 } %3 + ; CHECK: [[TST32:%[0-9]+]](32) = G_ICMP { s32, s32 } intpred(ult), [[LHS32]], [[RHS32]] + ; CHECK: %8(1) = G_TRUNC { s1, s32 } [[TST32]] + %8(1) = G_ICMP { s1, s8 } intpred(ult), %2, %3 ... |