Index: include/llvm/CodeGen/GlobalISel/Combiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/Combiner.h +++ include/llvm/CodeGen/GlobalISel/Combiner.h @@ -35,7 +35,7 @@ MachineRegisterInfo *MRI = nullptr; const TargetPassConfig *TPC; - MachineIRBuilder Builder; + MachineIRBuilderState BuilderState; }; } // End namespace llvm. Index: include/llvm/CodeGen/GlobalISel/IRTranslator.h =================================================================== --- include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -442,10 +442,12 @@ // I.e., compared to regular MIBuilder, this one also inserts the instruction // in the current block, it can creates block, etc., basically a kind of // IRBuilder, but for Machine IR. + MachineIRBuilderState CurBuilderState; MachineIRBuilder CurBuilder; // Builder set to the entry block (just after ABI lowering instructions). Used // as a convenient location for Constants. + MachineIRBuilderState EntryBuilderState; MachineIRBuilder EntryBuilder; // The MachineFunction currently being translated. Index: include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -23,14 +23,15 @@ namespace llvm { class LegalizationArtifactCombiner { - MachineIRBuilder &Builder; + MachineIRBuilder Builder; MachineRegisterInfo &MRI; const LegalizerInfo &LI; public: - LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, - const LegalizerInfo &LI) - : Builder(B), MRI(MRI), LI(LI) {} + LegalizationArtifactCombiner(MachineIRBuilderState &State, + MachineRegisterInfo &MRI, + const LegalizerInfo &LI) + : Builder(State), MRI(MRI), LI(LI) {} bool tryCombineAnyExt(MachineInstr &MI, SmallVectorImpl &DeadInsts) { Index: include/llvm/CodeGen/GlobalISel/LegalizerHelper.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -88,6 +88,7 @@ /// Expose MIRBuilder so clients can set their own RecordInsertInstruction /// functions + MachineIRBuilderState MIRBuilderState; MachineIRBuilder MIRBuilder; /// Expose LegalizerInfo so the clients can re-use. Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -36,7 +36,7 @@ extern cl::opt DisableGISelLegalityCheck; class MachineInstr; -class MachineIRBuilder; +struct MachineIRBuilderState; class MachineRegisterInfo; class MCInstrInfo; @@ -947,9 +947,8 @@ bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const; - virtual bool legalizeCustom(MachineInstr &MI, - MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const; + virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilderState &MIRBuilderState) const; private: /// Determine what action should be taken to legalize the given generic Index: include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h =================================================================== --- include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -51,6 +51,13 @@ /// @} std::function InsertedInstr; + + void recordInsertions(std::function InsertedInstr); + void stopRecordingInsertions(); + + void setMF(MachineFunction &MF); + void setMBB(MachineBasicBlock &MBB); + void setInstr(MachineInstr &MI); }; /// Helper class to build MachineInstr. @@ -59,7 +66,7 @@ /// This information can be modify via the related setters. class MachineIRBuilderBase { - MachineIRBuilderState State; + MachineIRBuilderState &State; const TargetInstrInfo &getTII() { assert(State.TII && "TargetInstrInfo is not set"); return *State.TII; @@ -99,13 +106,17 @@ public: /// Some constructors for easy use. - MachineIRBuilderBase() = default; - MachineIRBuilderBase(MachineFunction &MF) { setMF(MF); } - MachineIRBuilderBase(MachineInstr &MI) : MachineIRBuilderBase(*MI.getMF()) { + MachineIRBuilderBase() = delete; + MachineIRBuilderBase(MachineFunction &MF, MachineIRBuilderState &State) + : State(State) { + setMF(MF); + } + MachineIRBuilderBase(MachineInstr &MI, MachineIRBuilderState &State) + : MachineIRBuilderBase(*MI.getMF(), State) { setInstr(MI); } - MachineIRBuilderBase(const MachineIRBuilderState &BState) : State(BState) {} + MachineIRBuilderBase(MachineIRBuilderState &BState) : State(BState) {} /// Getter for the function we currently build. MachineFunction &getMF() { @@ -140,15 +151,15 @@ /// \name Setters for the insertion point. /// @{ /// Set the MachineFunction where to build instructions. - void setMF(MachineFunction &); + void setMF(MachineFunction &MF) { State.setMF(MF); } /// Set the insertion point to the end of \p MBB. /// \pre \p MBB must be contained by getMF(). - void setMBB(MachineBasicBlock &MBB); + void setMBB(MachineBasicBlock &MBB) { State.setMBB(MBB); }; /// Set the insertion point to before MI. /// \pre MI must be in getMF(). - void setInstr(MachineInstr &MI); + void setInstr(MachineInstr &MI) { State.setInstr(MI); } /// @} /// \name Control where instructions we create are recorded (typically for Index: include/llvm/CodeGen/GlobalISel/RegBankSelect.h =================================================================== --- include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -505,6 +505,7 @@ std::unique_ptr MORE; /// Helper class used for every code morphing. + MachineIRBuilderState MIRBuilderState; MachineIRBuilder MIRBuilder; /// Optimization mode of the pass. Index: lib/CodeGen/GlobalISel/Combiner.cpp =================================================================== --- lib/CodeGen/GlobalISel/Combiner.cpp +++ lib/CodeGen/GlobalISel/Combiner.cpp @@ -38,6 +38,7 @@ return false; MRI = &MF.getRegInfo(); + MachineIRBuilder Builder(BuilderState); Builder.setMF(MF); LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n'); Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -100,7 +100,9 @@ ORE.emit(R); } -IRTranslator::IRTranslator() : MachineFunctionPass(ID) { +IRTranslator::IRTranslator() + : MachineFunctionPass(ID), CurBuilder(CurBuilderState), + EntryBuilder(EntryBuilderState) { initializeIRTranslatorPass(*PassRegistry::getPassRegistry()); } @@ -1561,8 +1563,8 @@ // 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(); + EntryBuilderState = MachineIRBuilderState(); + CurBuilderState = MachineIRBuilderState(); } bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { Index: lib/CodeGen/GlobalISel/Legalizer.cpp =================================================================== --- lib/CodeGen/GlobalISel/Legalizer.cpp +++ lib/CodeGen/GlobalISel/Legalizer.cpp @@ -103,7 +103,7 @@ InstList.insert(&MI); } } - Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) { + Helper.MIRBuilderState.recordInsertions([&](MachineInstr *MI) { // Only legalize pre-isel generic instructions. // Legalization process could generate Target specific pseudo // instructions with generic types. Don't record them @@ -116,7 +116,8 @@ LLVM_DEBUG(dbgs() << ".. .. New MI: " << *MI;); }); const LegalizerInfo &LInfo(Helper.getLegalizerInfo()); - LegalizationArtifactCombiner ArtCombiner(Helper.MIRBuilder, MF.getRegInfo(), LInfo); + LegalizationArtifactCombiner ArtCombiner(Helper.MIRBuilderState, + MF.getRegInfo(), LInfo); auto RemoveDeadInstFromLists = [&InstList, &ArtifactList](MachineInstr *DeadMI) { InstList.remove(DeadMI); @@ -138,7 +139,7 @@ // Error out if we couldn't legalize this instruction. We may want to // fall back to DAG ISel instead in the future. if (Res == LegalizerHelper::UnableToLegalize) { - Helper.MIRBuilder.stopRecordingInsertions(); + Helper.MIRBuilderState.stopRecordingInsertions(); reportGISelFailure(MF, TPC, MORE, "gisel-legalize", "unable to legalize instruction", MI); return false; Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -30,13 +30,14 @@ using namespace LegalizeActions; LegalizerHelper::LegalizerHelper(MachineFunction &MF) - : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()) { - MIRBuilder.setMF(MF); + : MIRBuilder(MIRBuilderState), MRI(MF.getRegInfo()), + LI(*MF.getSubtarget().getLegalizerInfo()) { + MIRBuilderState.setMF(MF); } LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI) - : MRI(MF.getRegInfo()), LI(LI) { - MIRBuilder.setMF(MF); + : MIRBuilder(MIRBuilderState), MRI(MF.getRegInfo()), LI(LI) { + MIRBuilderState.setMF(MF); } LegalizerHelper::LegalizeResult LegalizerHelper::legalizeInstrStep(MachineInstr &MI) { @@ -64,8 +65,8 @@ return fewerElementsVector(MI, Step.TypeIdx, Step.NewType); case Custom: LLVM_DEBUG(dbgs() << ".. Custom legalization\n"); - return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized - : UnableToLegalize; + return LI.legalizeCustom(MI, MRI, MIRBuilderState) ? Legalized + : UnableToLegalize; default: LLVM_DEBUG(dbgs() << ".. Unable to legalize\n"); return UnableToLegalize; Index: lib/CodeGen/GlobalISel/LegalizerInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -375,8 +375,9 @@ return getAction(MI, MRI).Action == Legal; } -bool LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { +bool LegalizerInfo::legalizeCustom( + MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilderState &MIRBuilderState) const { return false; } Index: lib/CodeGen/GlobalISel/MachineIRBuilder.cpp =================================================================== --- lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -22,27 +22,26 @@ using namespace llvm; -void MachineIRBuilderBase::setMF(MachineFunction &MF) { - State.MF = &MF; - State.MBB = nullptr; - State.MRI = &MF.getRegInfo(); - State.TII = MF.getSubtarget().getInstrInfo(); - State.DL = DebugLoc(); - State.II = MachineBasicBlock::iterator(); - State.InsertedInstr = nullptr; +void MachineIRBuilderState::setMF(MachineFunction &MF) { + this->MF = &MF; + MBB = nullptr; + MRI = &MF.getRegInfo(); + TII = MF.getSubtarget().getInstrInfo(); + DL = DebugLoc(); + II = MachineBasicBlock::iterator(); + InsertedInstr = nullptr; } -void MachineIRBuilderBase::setMBB(MachineBasicBlock &MBB) { - State.MBB = &MBB; - State.II = MBB.end(); - assert(&getMF() == MBB.getParent() && - "Basic block is in a different function"); +void MachineIRBuilderState::setMBB(MachineBasicBlock &MBB) { + this->MBB = &MBB; + II = MBB.end(); + assert(MF == MBB.getParent() && "Basic block is in a different function"); } -void MachineIRBuilderBase::setInstr(MachineInstr &MI) { +void MachineIRBuilderState::setInstr(MachineInstr &MI) { assert(MI.getParent() && "Instruction is not part of a basic block"); setMBB(*MI.getParent()); - State.II = MI.getIterator(); + II = MI.getIterator(); } void MachineIRBuilderBase::setInsertPt(MachineBasicBlock &MBB, @@ -58,6 +57,15 @@ State.InsertedInstr(InsertedInstr); } +void MachineIRBuilderState::recordInsertions( + std::function Inserted) { + InsertedInstr = std::move(Inserted); +} + +void MachineIRBuilderState::stopRecordingInsertions() { + InsertedInstr = nullptr; +} + void MachineIRBuilderBase::recordInsertions( std::function Inserted) { State.InsertedInstr = std::move(Inserted); Index: lib/CodeGen/GlobalISel/RegBankSelect.cpp =================================================================== --- lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -71,7 +71,8 @@ false) RegBankSelect::RegBankSelect(Mode RunningMode) - : MachineFunctionPass(ID), OptMode(RunningMode) { + : MachineFunctionPass(ID), MIRBuilder(MIRBuilderState), + OptMode(RunningMode) { initializeRegBankSelectPass(*PassRegistry::getPassRegistry()); if (RegBankSelectMode.getNumOccurrences() != 0) { OptMode = RegBankSelectMode; Index: lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- lib/Target/AArch64/AArch64InstructionSelector.cpp +++ lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -665,7 +665,8 @@ MachineBasicBlock &MBB = *I.getParent(); MachineFunction &MF = *MBB.getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); - MachineIRBuilder MIB(I); + MachineIRBuilderState State; + MachineIRBuilder MIB(I, State); auto MovZ = MIB.buildInstr(AArch64::MOVZXi, &AArch64::GPR64RegClass); MovZ->addOperand(MF, I.getOperand(1)); Index: lib/Target/AArch64/AArch64LegalizerInfo.h =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.h +++ lib/Target/AArch64/AArch64LegalizerInfo.h @@ -28,11 +28,11 @@ AArch64LegalizerInfo(const AArch64Subtarget &ST); bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const override; + MachineIRBuilderState &) const override; private: bool legalizeVaArg(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const; + MachineIRBuilderState &State) const; }; } // End llvm namespace. #endif Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -391,13 +391,13 @@ bool AArch64LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilderState &State) const { switch (MI.getOpcode()) { default: // No idea what to do. return false; case TargetOpcode::G_VAARG: - return legalizeVaArg(MI, MRI, MIRBuilder); + return legalizeVaArg(MI, MRI, State); } llvm_unreachable("expected switch to return"); @@ -405,7 +405,8 @@ bool AArch64LegalizerInfo::legalizeVaArg(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilderState &State) const { + MachineIRBuilder MIRBuilder(State); MIRBuilder.setInstr(MI); MachineFunction &MF = MIRBuilder.getMF(); unsigned Align = MI.getOperand(2).getImm(); Index: lib/Target/ARM/ARMLegalizerInfo.h =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.h +++ lib/Target/ARM/ARMLegalizerInfo.h @@ -29,7 +29,7 @@ ARMLegalizerInfo(const ARMSubtarget &ST); bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const override; + MachineIRBuilderState &MIRBuilderState) const override; private: void setFCmpLibcallsGNU(); Index: lib/Target/ARM/ARMLegalizerInfo.cpp =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.cpp +++ lib/Target/ARM/ARMLegalizerInfo.cpp @@ -300,11 +300,12 @@ llvm_unreachable("Unsupported size for FCmp predicate"); } -bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI, - MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { +bool ARMLegalizerInfo::legalizeCustom( + MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilderState &MIRBuilderState) const { using namespace TargetOpcode; + MachineIRBuilder MIRBuilder(MIRBuilderState); MIRBuilder.setInstr(MI); LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext(); Index: tools/llvm-exegesis/lib/Assembler.cpp =================================================================== --- tools/llvm-exegesis/lib/Assembler.cpp +++ tools/llvm-exegesis/lib/Assembler.cpp @@ -119,7 +119,8 @@ if (TII->getReturnOpcode() < TII->getNumOpcodes()) { llvm::BuildMI(MBB, DL, TII->get(TII->getReturnOpcode())); } else { - llvm::MachineIRBuilder MIB(MF); + llvm::MachineIRBuilderState State; + llvm::MachineIRBuilder MIB(MF, State); MIB.setMBB(*MBB); MF.getSubtarget().getCallLowering()->lowerReturn(MIB, nullptr, 0); } Index: unittests/CodeGen/GlobalISel/LegalizerHelperTest.h =================================================================== --- unittests/CodeGen/GlobalISel/LegalizerHelperTest.h +++ unittests/CodeGen/GlobalISel/LegalizerHelperTest.h @@ -123,7 +123,7 @@ class LegalizerHelperTest : public ::testing::Test { protected: - LegalizerHelperTest() : ::testing::Test() { + LegalizerHelperTest() : ::testing::Test(), B(State) { TM = createTargetMachine(); if (!TM) return; @@ -143,6 +143,7 @@ SmallVector Copies; MachineBasicBlock *EntryMBB; MachineIRBuilder B; + MachineIRBuilderState State; MachineRegisterInfo *MRI; }; Index: unittests/CodeGen/GlobalISel/PatternMatchTest.cpp =================================================================== --- unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -131,7 +131,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); auto MIBCst = B.buildConstant(LLT::scalar(64), 42); @@ -152,7 +153,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); LLT s64 = LLT::scalar(64); @@ -257,7 +259,7 @@ // Try one of the other constructors of MachineIRBuilder to make sure it's // compatible. - ConstantFoldingMIRBuilder CFB1(*MF); + ConstantFoldingMIRBuilder CFB1(*MF, State); CFB1.setInsertPt(*EntryMBB, EntryMBB->end()); auto MIBCSub = CFB1.buildInstr(TargetOpcode::G_SUB, s32, CFB1.buildConstant(s32, 1), @@ -279,7 +281,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); @@ -350,7 +353,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); LLT s64 = LLT::scalar(64); @@ -406,7 +410,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); @@ -453,7 +458,8 @@ SmallVector Copies; collectCopies(Copies, MF); MachineBasicBlock *EntryMBB = &*MF->begin(); - MachineIRBuilder B(*MF); + MachineIRBuilderState State; + MachineIRBuilder B(*MF, State); MachineRegisterInfo &MRI = MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); LLT s64 = LLT::scalar(64);