diff options
7 files changed, 1 insertions, 517 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 4d804d0d0d2..d122e67b87b 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -49,7 +49,6 @@ public: }; LegalizerHelper(MachineFunction &MF); - LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI); /// Replace \p MI by a sequence of legal instructions that can implement the /// same operation. Note that this means \p MI may be deleted, so any iterator @@ -113,8 +112,6 @@ private: void extractParts(unsigned Reg, LLT Ty, int NumParts, SmallVectorImpl<unsigned> &VRegs); - LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty); - MachineRegisterInfo &MRI; const LegalizerInfo &LI; }; diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 2732a18d569..9e80c78dfa0 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -668,11 +668,6 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1); - template <typename DstTy, typename... UseArgsTy> - MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, DstTy &&Dst, - UseArgsTy &&... UseArgs) { - return buildICmp(Pred, getDestFromArg(Dst), getRegFromArg(UseArgs)...); - } /// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1 /// @@ -701,10 +696,6 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildSelect(unsigned Res, unsigned Tst, unsigned Op0, unsigned Op1); - template <typename DstTy, typename... UseArgsTy> - MachineInstrBuilder buildSelect(DstTy &&Dst, UseArgsTy &&... UseArgs) { - return buildSelect(getDestFromArg(Dst), getRegFromArg(UseArgs)...); - } /// Build and insert \p Res = G_INSERT_VECTOR_ELT \p Val, /// \p Elt, \p Idx diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index a3d310cfe1c..d487759a485 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -83,11 +83,6 @@ def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>; def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>; def : GINodeEquiv<G_BR, br>; def : GINodeEquiv<G_BSWAP, bswap>; -def : GINodeEquiv<G_CTLZ, ctlz>; -def : GINodeEquiv<G_CTTZ, cttz>; -def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>; -def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>; -def : GINodeEquiv<G_CTPOP, ctpop>; // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some // complications that tablegen must take care of. For example, Predicates such diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index e639be874db..87086af121b 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -17,13 +17,12 @@ #include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" + #define DEBUG_TYPE "legalizer" using namespace llvm; @@ -34,10 +33,6 @@ LegalizerHelper::LegalizerHelper(MachineFunction &MF) MIRBuilder.setMF(MF); } -LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI) - : MRI(MF.getRegInfo()), LI(LI) { - MIRBuilder.setMF(MF); -} LegalizerHelper::LegalizeResult LegalizerHelper::legalizeInstrStep(MachineInstr &MI) { LLVM_DEBUG(dbgs() << "Legalizing: "; MI.print(dbgs())); @@ -989,12 +984,6 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) { return UnableToLegalize; } - case TargetOpcode::G_CTLZ_ZERO_UNDEF: - case TargetOpcode::G_CTTZ_ZERO_UNDEF: - case TargetOpcode::G_CTLZ: - case TargetOpcode::G_CTTZ: - case TargetOpcode::G_CTPOP: - return lowerBitCount(MI, TypeIdx, Ty); } } @@ -1035,112 +1024,3 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, } } } - -LegalizerHelper::LegalizeResult -LegalizerHelper::lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty) { - unsigned Opc = MI.getOpcode(); - auto &TII = *MI.getMF()->getSubtarget().getInstrInfo(); - auto isLegalOrCustom = [this](const LegalityQuery &Q) { - auto QAction = LI.getAction(Q).Action; - return QAction == Legal || QAction == Custom; - }; - switch (Opc) { - default: - return UnableToLegalize; - case TargetOpcode::G_CTLZ_ZERO_UNDEF: { - // This trivially expands to CTLZ. - MI.setDesc(TII.get(TargetOpcode::G_CTLZ)); - MIRBuilder.recordInsertion(&MI); - return Legalized; - } - case TargetOpcode::G_CTLZ: { - unsigned SrcReg = MI.getOperand(1).getReg(); - unsigned Len = Ty.getSizeInBits(); - if (isLegalOrCustom({TargetOpcode::G_CTLZ_ZERO_UNDEF, {Ty}})) { - // If CTLZ_ZERO_UNDEF is legal or custom, emit that and a select with - // zero. - auto MIBCtlzZU = - MIRBuilder.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, Ty, SrcReg); - auto MIBZero = MIRBuilder.buildConstant(Ty, 0); - auto MIBLen = MIRBuilder.buildConstant(Ty, Len); - auto MIBICmp = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1), - SrcReg, MIBZero); - MIRBuilder.buildSelect(MI.getOperand(0).getReg(), MIBICmp, MIBLen, - MIBCtlzZU); - MI.eraseFromParent(); - return Legalized; - } - // for now, we do this: - // NewLen = NextPowerOf2(Len); - // x = x | (x >> 1); - // x = x | (x >> 2); - // ... - // x = x | (x >>16); - // x = x | (x >>32); // for 64-bit input - // Upto NewLen/2 - // return Len - popcount(x); - // - // Ref: "Hacker's Delight" by Henry Warren - unsigned Op = SrcReg; - unsigned NewLen = PowerOf2Ceil(Len); - for (unsigned i = 0; (1U << i) <= (NewLen / 2); ++i) { - auto MIBShiftAmt = MIRBuilder.buildConstant(Ty, 1ULL << i); - auto MIBOp = MIRBuilder.buildInstr( - TargetOpcode::G_OR, Ty, Op, - MIRBuilder.buildInstr(TargetOpcode::G_LSHR, Ty, Op, MIBShiftAmt)); - Op = MIBOp->getOperand(0).getReg(); - } - auto MIBPop = MIRBuilder.buildInstr(TargetOpcode::G_CTPOP, Ty, Op); - MIRBuilder.buildInstr(TargetOpcode::G_SUB, MI.getOperand(0).getReg(), - MIRBuilder.buildConstant(Ty, Len), MIBPop); - MI.eraseFromParent(); - return Legalized; - } - case TargetOpcode::G_CTTZ_ZERO_UNDEF: { - // This trivially expands to CTTZ. - MI.setDesc(TII.get(TargetOpcode::G_CTTZ)); - MIRBuilder.recordInsertion(&MI); - return Legalized; - } - case TargetOpcode::G_CTTZ: { - unsigned SrcReg = MI.getOperand(1).getReg(); - unsigned Len = Ty.getSizeInBits(); - if (isLegalOrCustom({TargetOpcode::G_CTTZ_ZERO_UNDEF, {Ty}})) { - // If CTTZ_ZERO_UNDEF is legal or custom, emit that and a select with - // zero. - auto MIBCttzZU = - MIRBuilder.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, Ty, SrcReg); - auto MIBZero = MIRBuilder.buildConstant(Ty, 0); - auto MIBLen = MIRBuilder.buildConstant(Ty, Len); - auto MIBICmp = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1), - SrcReg, MIBZero); - MIRBuilder.buildSelect(MI.getOperand(0).getReg(), MIBICmp, MIBLen, - MIBCttzZU); - MI.eraseFromParent(); - return Legalized; - } - // for now, we use: { return popcount(~x & (x - 1)); } - // unless the target has ctlz but not ctpop, in which case we use: - // { return 32 - nlz(~x & (x-1)); } - // Ref: "Hacker's Delight" by Henry Warren - auto MIBCstNeg1 = MIRBuilder.buildConstant(Ty, -1); - auto MIBNot = - MIRBuilder.buildInstr(TargetOpcode::G_XOR, Ty, SrcReg, MIBCstNeg1); - auto MIBTmp = MIRBuilder.buildInstr( - TargetOpcode::G_AND, Ty, MIBNot, - MIRBuilder.buildInstr(TargetOpcode::G_ADD, Ty, SrcReg, MIBCstNeg1)); - if (!isLegalOrCustom({TargetOpcode::G_CTPOP, {Ty}}) && - isLegalOrCustom({TargetOpcode::G_CTLZ, {Ty}})) { - MIRBuilder.buildInstr( - TargetOpcode::G_SUB, MI.getOperand(0).getReg(), - MIRBuilder.buildConstant(Ty, Len), - MIRBuilder.buildInstr(TargetOpcode::G_CTLZ, Ty, MIBTmp)); - MI.eraseFromParent(); - return Legalized; - } - MI.setDesc(TII.get(TargetOpcode::G_CTPOP)); - MI.getOperand(1).setReg(MIBTmp->getOperand(0).getReg()); - return Legalized; - } - } -} diff --git a/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt b/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt index 60566cb2d59..85f5dcd6d04 100644 --- a/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt +++ b/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt @@ -12,5 +12,4 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(GlobalISelTests LegalizerInfoTest.cpp PatternMatchTest.cpp - LegalizerHelperTest.cpp ) diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp deleted file mode 100644 index 292281a09a5..00000000000 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//===- PatternMatchTest.cpp -----------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LegalizerHelperTest.h" - -namespace { - -// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom, -// in which case it becomes CTTZ_ZERO_UNDEF with select. -TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ0) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo( - A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); }); - // Build Instr - auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - // Perform Legalization - ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0 - CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 - CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] - CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} - -// CTTZ expansion in terms of CTLZ -TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ1) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo(A, - { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); }); - // Build Instr - auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - // Perform Legalization - ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 - CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] - CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] - CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ - CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 - CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_ - CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_ - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} - -// CTTZ expansion in terms of CTPOP -TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ2) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo( - A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); }); - // Build - auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1 - CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]] - CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]] - CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_ - CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]] - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} - -// CTTZ_ZERO_UNDEF expansion in terms of CTTZ -TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ3) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo(A, - { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); }); - // Build - auto MIBCTTZ = - B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, LLT::scalar(64), Copies[0]); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: CTTZ - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} - -// CTLZ expansion in terms of CTLZ_ZERO_UNDEF -TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ0) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo( - A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); }); - // Build - auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0 - CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64 - CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]] - CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]] - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} - -// CTLZ expansion -TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ1) { - if (!TM) - return; - - // Declare your legalization info - DefineLegalizerInfo(A, - { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); }); - // Build - // Trunc it to s8. - LLT s8{LLT::scalar(8)}; - auto MIBTrunc = B.buildTrunc(s8, Copies[0]); - auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, s8, MIBTrunc); - AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); - ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) == - LegalizerHelper::LegalizeResult::Legalized); - - auto CheckStr = R"( - CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC - CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 - CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_ - CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_ - CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2 - CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_ - CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_ - CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4 - CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_ - CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_ - CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_ - CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 - CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_ - )"; - - // Check - ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); -} -} // namespace diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h deleted file mode 100644 index ca1aed544d2..00000000000 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h +++ /dev/null @@ -1,190 +0,0 @@ -//===- LegalizerHelperTest.h -//-----------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" -#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" -#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" -#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" -#include "llvm/CodeGen/GlobalISel/Utils.h" -#include "llvm/CodeGen/MIRParser/MIRParser.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/TargetFrameLowering.h" -#include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/Support/FileCheck.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "gtest/gtest.h" - -using namespace llvm; -using namespace MIPatternMatch; - -void initLLVM() { - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmPrinters(); - InitializeAllAsmParsers(); - - PassRegistry *Registry = PassRegistry::getPassRegistry(); - initializeCore(*Registry); - initializeCodeGen(*Registry); -} - -/// Create a TargetMachine. As we lack a dedicated always available target for -/// unittests, we go for "AArch64". -std::unique_ptr<TargetMachine> createTargetMachine() { - Triple TargetTriple("aarch64--"); - std::string Error; - const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); - if (!T) - return nullptr; - - TargetOptions Options; - return std::unique_ptr<TargetMachine>(T->createTargetMachine( - "AArch64", "", "", Options, None, None, CodeGenOpt::Aggressive)); -} - -std::unique_ptr<Module> parseMIR(LLVMContext &Context, - std::unique_ptr<MIRParser> &MIR, - const TargetMachine &TM, StringRef MIRCode, - const char *FuncName, MachineModuleInfo &MMI) { - SMDiagnostic Diagnostic; - std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode); - MIR = createMIRParser(std::move(MBuffer), Context); - if (!MIR) - return nullptr; - - std::unique_ptr<Module> M = MIR->parseIRModule(); - if (!M) - return nullptr; - - M->setDataLayout(TM.createDataLayout()); - - if (MIR->parseMachineFunctions(*M, MMI)) - return nullptr; - - return M; -} - -std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>> -createDummyModule(LLVMContext &Context, const TargetMachine &TM, - StringRef MIRFunc) { - SmallString<512> S; - StringRef MIRString = (Twine(R"MIR( ---- -... -name: func -registers: - - { id: 0, class: _ } - - { id: 1, class: _ } - - { id: 2, class: _ } - - { id: 3, class: _ } -body: | - bb.1: - %0(s64) = COPY $x0 - %1(s64) = COPY $x1 - %2(s64) = COPY $x2 -)MIR") + Twine(MIRFunc) + Twine("...\n")) - .toNullTerminatedStringRef(S); - std::unique_ptr<MIRParser> MIR; - auto MMI = make_unique<MachineModuleInfo>(&TM); - std::unique_ptr<Module> M = - parseMIR(Context, MIR, TM, MIRString, "func", *MMI); - return make_pair(std::move(M), std::move(MMI)); -} - -static MachineFunction *getMFFromMMI(const Module *M, - const MachineModuleInfo *MMI) { - Function *F = M->getFunction("func"); - auto *MF = MMI->getMachineFunction(*F); - return MF; -} - -static void collectCopies(SmallVectorImpl<unsigned> &Copies, - MachineFunction *MF) { - for (auto &MBB : *MF) - for (MachineInstr &MI : MBB) { - if (MI.getOpcode() == TargetOpcode::COPY) - Copies.push_back(MI.getOperand(0).getReg()); - } -} - -class LegalizerHelperTest : public ::testing::Test { -protected: - LegalizerHelperTest() : ::testing::Test() { - TM = createTargetMachine(); - if (!TM) - return; - ModuleMMIPair = createDummyModule(Context, *TM, ""); - MF = getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get()); - collectCopies(Copies, MF); - EntryMBB = &*MF->begin(); - B.setMF(*MF); - MRI = &MF->getRegInfo(); - B.setInsertPt(*EntryMBB, EntryMBB->end()); - } - LLVMContext Context; - std::unique_ptr<TargetMachine> TM; - MachineFunction *MF; - std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>> - ModuleMMIPair; - SmallVector<unsigned, 4> Copies; - MachineBasicBlock *EntryMBB; - MachineIRBuilder B; - MachineRegisterInfo *MRI; -}; - -#define DefineLegalizerInfo(Name, SettingUpActionsBlock) \ - class Name##Info : public LegalizerInfo { \ - public: \ - Name##Info(const TargetSubtargetInfo &ST) { \ - using namespace TargetOpcode; \ - const LLT s8 = LLT::scalar(8); \ - (void)s8; \ - const LLT s16 = LLT::scalar(16); \ - (void)s16; \ - const LLT s32 = LLT::scalar(32); \ - (void)s32; \ - const LLT s64 = LLT::scalar(64); \ - (void)s64; \ - do \ - SettingUpActionsBlock while (0); \ - computeTables(); \ - verify(*ST.getInstrInfo()); \ - } \ - }; - -static bool CheckMachineFunction(const MachineFunction &MF, - StringRef CheckStr) { - SmallString<512> Msg; - raw_svector_ostream OS(Msg); - MF.print(OS); - auto OutputBuf = MemoryBuffer::getMemBuffer(Msg, "Output", false); - auto CheckBuf = MemoryBuffer::getMemBuffer(CheckStr, ""); - SmallString<4096> CheckFileBuffer; - FileCheckRequest Req; - FileCheck FC(Req); - StringRef CheckFileText = - FC.CanonicalizeFile(*CheckBuf.get(), CheckFileBuffer); - SourceMgr SM; - SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"), - SMLoc()); - Regex PrefixRE = FC.buildCheckPrefixRegex(); - std::vector<FileCheckString> CheckStrings; - FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings); - auto OutBuffer = OutputBuf->getBuffer(); - SM.AddNewSourceBuffer(std::move(OutputBuf), SMLoc()); - return FC.CheckInput(SM, OutBuffer, CheckStrings); -} |