summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-08-25 17:37:32 +0000
committerTim Northover <tnorthover@apple.com>2016-08-25 17:37:32 +0000
commit042ca5a33ab5acf8405024643a31cf006b5298b5 (patch)
treed306b730b015aec8f43473eb73d941394d4dc990
parentbbdb9c7d9b214b535b8c4ef9fe9a4ab1889a7652 (diff)
downloadllvm-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.h11
-rw-r--r--include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h3
-rw-r--r--lib/CodeGen/GlobalISel/MachineIRBuilder.cpp14
-rw-r--r--lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp29
-rw-r--r--lib/Target/AArch64/AArch64MachineLegalizer.cpp18
-rw-r--r--test/CodeGen/AArch64/GlobalISel/legalize-add.mir3
-rw-r--r--test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir6
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
...