diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 105 |
1 files changed, 72 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 4db5d1c2ea1..95f6274aa06 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/LowLevelType.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -75,11 +76,16 @@ using namespace llvm; +static cl::opt<bool> + EnableCSEInIRTranslator("enable-cse-in-irtranslator", + cl::desc("Should enable CSE in irtranslator"), + cl::Optional, cl::init(false)); char IRTranslator::ID = 0; INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI", false, false) INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass) INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI", false, false) @@ -108,18 +114,21 @@ IRTranslator::IRTranslator() : MachineFunctionPass(ID) { namespace { /// Verify that every instruction created has the same DILocation as the /// instruction being translated. -class DILocationVerifier : MachineFunction::Delegate { - MachineFunction &MF; +class DILocationVerifier : public GISelChangeObserver { const Instruction *CurrInst = nullptr; public: - DILocationVerifier(MachineFunction &MF) : MF(MF) { MF.setDelegate(this); } - ~DILocationVerifier() { MF.resetDelegate(this); } + DILocationVerifier() = default; + ~DILocationVerifier() = default; const Instruction *getCurrentInst() const { return CurrInst; } void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; } - void MF_HandleInsertion(const MachineInstr &MI) override { + void erasingInstr(MachineInstr &MI) override {} + void changingInstr(MachineInstr &MI) override {} + void changedInstr(MachineInstr &MI) override {} + + void createdInstr(MachineInstr &MI) override { assert(getCurrentInst() && "Inserted instruction without a current MI"); // Only print the check message if we're actually checking it. @@ -130,7 +139,6 @@ public: assert(CurrInst->getDebugLoc() == MI.getDebugLoc() && "Line info was not transferred to all instructions"); } - void MF_HandleRemoval(const MachineInstr &MI) override {} }; } // namespace #endif // ifndef NDEBUG @@ -139,6 +147,7 @@ public: void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<StackProtector>(); AU.addRequired<TargetPassConfig>(); + AU.addRequired<GISelCSEAnalysisWrapperPass>(); getSelectionDAGFallbackAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU); } @@ -1553,12 +1562,14 @@ bool IRTranslator::translateAtomicRMW(const User &U, void IRTranslator::finishPendingPhis() { #ifndef NDEBUG - DILocationVerifier Verifier(*MF); + DILocationVerifier Verifier; + GISelObserverWrapper WrapperObserver(&Verifier); + RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver); #endif // ifndef NDEBUG for (auto &Phi : PendingPHIs) { const PHINode *PI = Phi.first; ArrayRef<MachineInstr *> ComponentPHIs = Phi.second; - EntryBuilder.setDebugLoc(PI->getDebugLoc()); + EntryBuilder->setDebugLoc(PI->getDebugLoc()); #ifndef NDEBUG Verifier.setCurrentInst(PI); #endif // ifndef NDEBUG @@ -1599,11 +1610,12 @@ bool IRTranslator::valueIsSplit(const Value &V, } bool IRTranslator::translate(const Instruction &Inst) { - CurBuilder.setDebugLoc(Inst.getDebugLoc()); - EntryBuilder.setDebugLoc(Inst.getDebugLoc()); + CurBuilder->setDebugLoc(Inst.getDebugLoc()); + EntryBuilder->setDebugLoc(Inst.getDebugLoc()); switch(Inst.getOpcode()) { -#define HANDLE_INST(NUM, OPCODE, CLASS) \ - case Instruction::OPCODE: return translate##OPCODE(Inst, CurBuilder); +#define HANDLE_INST(NUM, OPCODE, CLASS) \ + case Instruction::OPCODE: \ + return translate##OPCODE(Inst, *CurBuilder.get()); #include "llvm/IR/Instruction.def" default: return false; @@ -1612,11 +1624,11 @@ bool IRTranslator::translate(const Instruction &Inst) { bool IRTranslator::translate(const Constant &C, unsigned Reg) { if (auto CI = dyn_cast<ConstantInt>(&C)) - EntryBuilder.buildConstant(Reg, *CI); + EntryBuilder->buildConstant(Reg, *CI); else if (auto CF = dyn_cast<ConstantFP>(&C)) - EntryBuilder.buildFConstant(Reg, *CF); + EntryBuilder->buildFConstant(Reg, *CF); else if (isa<UndefValue>(C)) - EntryBuilder.buildUndef(Reg); + EntryBuilder->buildUndef(Reg); else if (isa<ConstantPointerNull>(C)) { // As we are trying to build a constant val of 0 into a pointer, // insert a cast to make them correct with respect to types. @@ -1624,9 +1636,9 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { auto *ZeroTy = Type::getIntNTy(C.getContext(), NullSize); auto *ZeroVal = ConstantInt::get(ZeroTy, 0); unsigned ZeroReg = getOrCreateVReg(*ZeroVal); - EntryBuilder.buildCast(Reg, ZeroReg); + EntryBuilder->buildCast(Reg, ZeroReg); } else if (auto GV = dyn_cast<GlobalValue>(&C)) - EntryBuilder.buildGlobalValue(Reg, GV); + EntryBuilder->buildGlobalValue(Reg, GV); else if (auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) { if (!CAZ->getType()->isVectorTy()) return false; @@ -1638,7 +1650,7 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { Constant &Elt = *CAZ->getElementValue(i); Ops.push_back(getOrCreateVReg(Elt)); } - EntryBuilder.buildBuildVector(Reg, Ops); + EntryBuilder->buildBuildVector(Reg, Ops); } else if (auto CV = dyn_cast<ConstantDataVector>(&C)) { // Return the scalar if it is a <1 x Ty> vector. if (CV->getNumElements() == 1) @@ -1648,11 +1660,12 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { Constant &Elt = *CV->getElementAsConstant(i); Ops.push_back(getOrCreateVReg(Elt)); } - EntryBuilder.buildBuildVector(Reg, Ops); + EntryBuilder->buildBuildVector(Reg, Ops); } else if (auto CE = dyn_cast<ConstantExpr>(&C)) { switch(CE->getOpcode()) { -#define HANDLE_INST(NUM, OPCODE, CLASS) \ - case Instruction::OPCODE: return translate##OPCODE(*CE, EntryBuilder); +#define HANDLE_INST(NUM, OPCODE, CLASS) \ + case Instruction::OPCODE: \ + return translate##OPCODE(*CE, *EntryBuilder.get()); #include "llvm/IR/Instruction.def" default: return false; @@ -1664,9 +1677,9 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { for (unsigned i = 0; i < CV->getNumOperands(); ++i) { Ops.push_back(getOrCreateVReg(*CV->getOperand(i))); } - EntryBuilder.buildBuildVector(Reg, Ops); + EntryBuilder->buildBuildVector(Reg, Ops); } else if (auto *BA = dyn_cast<BlockAddress>(&C)) { - EntryBuilder.buildBlockAddress(Reg, BA); + EntryBuilder->buildBlockAddress(Reg, BA); } else return false; @@ -1683,8 +1696,8 @@ void IRTranslator::finalizeFunction() { // MachineIRBuilder::DebugLoc can outlive the DILocation it holds. Clear it // to avoid accessing free’d memory (in runOnMachineFunction) and to avoid // destroying it twice (in ~IRTranslator() and ~LLVMContext()) - EntryBuilder = MachineIRBuilder(); - CurBuilder = MachineIRBuilder(); + EntryBuilder.reset(); + CurBuilder.reset(); } bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { @@ -1692,12 +1705,30 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { const Function &F = MF->getFunction(); if (F.empty()) return false; + GISelCSEAnalysisWrapper &Wrapper = + getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper(); + // Set the CSEConfig and run the analysis. + GISelCSEInfo *CSEInfo = nullptr; + TPC = &getAnalysis<TargetPassConfig>(); + bool IsO0 = TPC->getOptLevel() == CodeGenOpt::Level::None; + // Disable CSE for O0. + bool EnableCSE = !IsO0 && EnableCSEInIRTranslator; + if (EnableCSE) { + EntryBuilder = make_unique<CSEMIRBuilder>(CurMF); + std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>(); + CSEInfo = &Wrapper.get(std::move(Config)); + EntryBuilder->setCSEInfo(CSEInfo); + CurBuilder = make_unique<CSEMIRBuilder>(CurMF); + CurBuilder->setCSEInfo(CSEInfo); + } else { + EntryBuilder = make_unique<MachineIRBuilder>(); + CurBuilder = make_unique<MachineIRBuilder>(); + } CLI = MF->getSubtarget().getCallLowering(); - CurBuilder.setMF(*MF); - EntryBuilder.setMF(*MF); + CurBuilder->setMF(*MF); + EntryBuilder->setMF(*MF); MRI = &MF->getRegInfo(); DL = &F.getParent()->getDataLayout(); - TPC = &getAnalysis<TargetPassConfig>(); ORE = llvm::make_unique<OptimizationRemarkEmitter>(&F); assert(PendingPHIs.empty() && "stale PHIs"); @@ -1716,7 +1747,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { // Setup a separate basic-block for the arguments and constants MachineBasicBlock *EntryBB = MF->CreateMachineBasicBlock(); MF->push_back(EntryBB); - EntryBuilder.setMBB(*EntryBB); + EntryBuilder->setMBB(*EntryBB); // Create all blocks, in IR order, to preserve the layout. for (const BasicBlock &BB: F) { @@ -1753,7 +1784,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { } } - if (!CLI->lowerFormalArguments(EntryBuilder, F, VRegArgs)) { + if (!CLI->lowerFormalArguments(*EntryBuilder.get(), F, VRegArgs)) { OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", F.getSubprogram(), &F.getEntryBlock()); R << "unable to lower arguments: " << ore::NV("Prototype", F.getType()); @@ -1770,22 +1801,27 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { assert(VRegs.empty() && "VRegs already populated?"); VRegs.push_back(VArg); } else { - unpackRegs(*ArgIt, VArg, EntryBuilder); + unpackRegs(*ArgIt, VArg, *EntryBuilder.get()); } ArgIt++; } // Need to visit defs before uses when translating instructions. + GISelObserverWrapper WrapperObserver; + if (EnableCSE && CSEInfo) + WrapperObserver.addObserver(CSEInfo); { ReversePostOrderTraversal<const Function *> RPOT(&F); #ifndef NDEBUG - DILocationVerifier Verifier(*MF); + DILocationVerifier Verifier; + WrapperObserver.addObserver(&Verifier); #endif // ifndef NDEBUG + RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver); for (const BasicBlock *BB : RPOT) { MachineBasicBlock &MBB = getMBB(*BB); // Set the insertion point of all the following translations to // the end of this basic block. - CurBuilder.setMBB(MBB); + CurBuilder->setMBB(MBB); for (const Instruction &Inst : *BB) { #ifndef NDEBUG @@ -1810,6 +1846,9 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { return false; } } +#ifndef NDEBUG + WrapperObserver.removeObserver(&Verifier); +#endif } finishPendingPhis(); |