Index: include/llvm/CodeGen/GlobalISel/Combiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/Combiner.h +++ include/llvm/CodeGen/GlobalISel/Combiner.h @@ -24,16 +24,6 @@ class TargetPassConfig; class MachineFunction; -class CombinerChangeObserver { -public: - virtual ~CombinerChangeObserver() {} - - /// An instruction was erased. - virtual void erasedInstr(MachineInstr &MI) = 0; - /// An instruction was created and inseerted into the function. - virtual void createdInstr(MachineInstr &MI) = 0; -}; - class Combiner { public: Combiner(CombinerInfo &CombinerInfo, const TargetPassConfig *TPC); Index: include/llvm/CodeGen/GlobalISel/CombinerHelper.h =================================================================== --- include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -20,7 +20,7 @@ namespace llvm { -class CombinerChangeObserver; +class GISelChangeObserver; class MachineIRBuilder; class MachineRegisterInfo; class MachineInstr; @@ -28,13 +28,13 @@ class CombinerHelper { MachineIRBuilder &Builder; MachineRegisterInfo &MRI; - CombinerChangeObserver &Observer; + GISelChangeObserver &Observer; void eraseInstr(MachineInstr &MI); void scheduleForVisit(MachineInstr &MI); public: - CombinerHelper(CombinerChangeObserver &Observer, MachineIRBuilder &B); + CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B); /// If \p MI is COPY, try to combine it. /// Returns true if MI changed. Index: include/llvm/CodeGen/GlobalISel/CombinerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/CombinerInfo.h +++ include/llvm/CodeGen/GlobalISel/CombinerInfo.h @@ -17,7 +17,7 @@ #include namespace llvm { -class CombinerChangeObserver; +class GISelChangeObserver; class LegalizerInfo; class MachineInstr; class MachineIRBuilder; @@ -43,7 +43,7 @@ /// illegal ops that are created. bool LegalizeIllegalOps; // TODO: Make use of this. const LegalizerInfo *LInfo; - virtual bool combine(CombinerChangeObserver &Observer, MachineInstr &MI, + virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B) const = 0; }; } // namespace llvm Index: include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h =================================================================== --- /dev/null +++ include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h @@ -0,0 +1,39 @@ +//== ----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h --------------------- +//== // +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// This contains common code to allow clients to notify changes to machine +/// instr. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H +#define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H + +namespace llvm { +/// Abstract class that contains various methods for clients to notify about +/// changes. This should be the preferred way for APIs to notify changes. +/// Typically calling erasedInstr/createdInstr multiple times should not affect +/// the result. The observer would likely need to check if it was already +/// notified earlier (consider using GISelWorkList). +class MachineInstr; +class GISelChangeObserver { +public: + virtual ~GISelChangeObserver() {} + + /// An instruction was erased. + virtual void erasedInstr(MachineInstr &MI) = 0; + /// An instruction was created and inserted into the function. + virtual void createdInstr(MachineInstr &MI) = 0; + + /// This instruction was mutated in some way. + virtual void changedInstr(MachineInstr &MI) = 0; +}; + +} // namespace llvm +#endif Index: include/llvm/CodeGen/GlobalISel/LegalizerHelper.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -32,6 +32,7 @@ class LegalizerInfo; class Legalizer; class MachineRegisterInfo; +class GISelChangeObserver; class LegalizerHelper { public: @@ -48,8 +49,9 @@ UnableToLegalize, }; - LegalizerHelper(MachineFunction &MF); - LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI); + LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer); + LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI, + GISelChangeObserver &Observer); /// 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 @@ -117,6 +119,8 @@ MachineRegisterInfo &MRI; const LegalizerInfo &LI; + /// To keep track of changes made by the LegalizerHelper. + GISelChangeObserver &Observer; }; /// Helper function that creates the given libcall. Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -39,6 +39,7 @@ class MachineIRBuilder; class MachineRegisterInfo; class MCInstrInfo; +class GISelChangeObserver; namespace LegalizeActions { enum LegalizeAction : std::uint8_t { @@ -949,9 +950,9 @@ 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, + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) 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 @@ -30,6 +30,7 @@ class MachineFunction; class MachineInstr; class TargetInstrInfo; +class GISelChangeObserver; /// Class which stores all the state required in a MachineIRBuilder. /// Since MachineIRBuilders will only store state in this object, it allows @@ -50,7 +51,7 @@ MachineBasicBlock::iterator II; /// @} - std::function InsertedInstr; + GISelChangeObserver *Observer; }; /// Helper class to build MachineInstr. @@ -61,6 +62,7 @@ MachineIRBuilderState State; void validateTruncExt(unsigned Dst, unsigned Src, bool IsExtend); + void recordInsertion(MachineInstr *MI) const; protected: unsigned getDestFromArg(unsigned Reg) { return Reg; } @@ -151,12 +153,8 @@ void setInstr(MachineInstr &MI); /// @} - /// \name Control where instructions we create are recorded (typically for - /// visiting again later during legalization). - /// @{ - void recordInsertion(MachineInstr *InsertedInstr) const; - void recordInsertions(std::function InsertedInstr); - void stopRecordingInsertions(); + void setChangeObserver(GISelChangeObserver &Observer); + void stopObservingChanges(); /// @} /// Set the debug location to \p DL for all the next build instructions. Index: lib/CodeGen/GlobalISel/Combiner.cpp =================================================================== --- lib/CodeGen/GlobalISel/Combiner.cpp +++ lib/CodeGen/GlobalISel/Combiner.cpp @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" -#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" -#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/GISelWorkList.h" -#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" @@ -34,7 +35,7 @@ /// instruction creation will schedule that instruction for a future visit. /// Other Combiner implementations may require more complex behaviour from /// their CombinerChangeObserver subclass. -class WorkListMaintainer : public CombinerChangeObserver { +class WorkListMaintainer : public GISelChangeObserver { using WorkListTy = GISelWorkList<512>; WorkListTy &WorkList; @@ -50,6 +51,11 @@ LLVM_DEBUG(dbgs() << "Created: "; MI.print(dbgs()); dbgs() << "\n"); WorkList.insert(&MI); } + // Currently changed conservatively assumes erased. + void changedInstr(MachineInstr &MI) override { + LLVM_DEBUG(dbgs() << "Changed: "; MI.print(dbgs()); dbgs() << "\n"); + WorkList.remove(&MI); + } }; } Index: lib/CodeGen/GlobalISel/CombinerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -6,8 +6,9 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/GlobalISel/Combiner.h" #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" +#include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineInstr.h" @@ -18,7 +19,7 @@ using namespace llvm; -CombinerHelper::CombinerHelper(CombinerChangeObserver &Observer, +CombinerHelper::CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B) : Builder(B), MRI(Builder.getMF().getRegInfo()), Observer(Observer) {} Index: lib/CodeGen/GlobalISel/Legalizer.cpp =================================================================== --- lib/CodeGen/GlobalISel/Legalizer.cpp +++ lib/CodeGen/GlobalISel/Legalizer.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/GlobalISel/Legalizer.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SetVector.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/GISelWorkList.h" #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" @@ -67,6 +68,42 @@ return true; } } +using InstListTy = GISelWorkList<256>; +using ArtifactListTy = GISelWorkList<128>; + +class LegalizerWorkListManager : public GISelChangeObserver { + InstListTy &InstList; + ArtifactListTy &ArtifactList; + +public: + LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts) + : InstList(Insts), ArtifactList(Arts) {} + + void createdInstr(MachineInstr &MI) override { + // Only legalize pre-isel generic instructions. + // Legalization process could generate Target specific pseudo + // instructions with generic types. Don't record them + if (isPreISelGenericOpcode(MI.getOpcode())) { + if (isArtifact(MI)) + ArtifactList.insert(&MI); + else + InstList.insert(&MI); + } + LLVM_DEBUG(dbgs() << ".. .. New MI: " << MI;); + } + + void erasedInstr(MachineInstr &MI) override { + InstList.remove(&MI); + ArtifactList.remove(&MI); + } + + void changedInstr(MachineInstr &MI) override { + // When insts change, we want to revisit them to legalize them again. + // We'll consider them the same as created. + LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI;); + createdInstr(MI); + } +}; bool Legalizer::runOnMachineFunction(MachineFunction &MF) { // If the ISel pipeline failed, do not bother running that pass. @@ -77,14 +114,13 @@ init(MF); const TargetPassConfig &TPC = getAnalysis(); MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); - LegalizerHelper Helper(MF); const size_t NumBlocks = MF.size(); MachineRegisterInfo &MRI = MF.getRegInfo(); // Populate Insts - GISelWorkList<256> InstList; - GISelWorkList<128> ArtifactList; + InstListTy InstList; + ArtifactListTy ArtifactList; ReversePostOrderTraversal RPOT(&MF); // Perform legalization bottom up so we can DCE as we legalize. // Traverse BB in RPOT and within each basic block, add insts top down, @@ -103,24 +139,12 @@ InstList.insert(&MI); } } - Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) { - // Only legalize pre-isel generic instructions. - // Legalization process could generate Target specific pseudo - // instructions with generic types. Don't record them - if (isPreISelGenericOpcode(MI->getOpcode())) { - if (isArtifact(*MI)) - ArtifactList.insert(MI); - else - InstList.insert(MI); - } - LLVM_DEBUG(dbgs() << ".. .. New MI: " << *MI;); - }); + LegalizerWorkListManager WorkListObserver(InstList, ArtifactList); + LegalizerHelper Helper(MF, WorkListObserver); const LegalizerInfo &LInfo(Helper.getLegalizerInfo()); LegalizationArtifactCombiner ArtCombiner(Helper.MIRBuilder, MF.getRegInfo(), LInfo); - auto RemoveDeadInstFromLists = [&InstList, - &ArtifactList](MachineInstr *DeadMI) { - InstList.remove(DeadMI); - ArtifactList.remove(DeadMI); + auto RemoveDeadInstFromLists = [&WorkListObserver](MachineInstr *DeadMI) { + WorkListObserver.erasedInstr(*DeadMI); }; bool Changed = false; do { @@ -138,7 +162,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.MIRBuilder.stopObservingChanges(); 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 @@ -15,6 +15,7 @@ #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetInstrInfo.h" @@ -29,14 +30,19 @@ using namespace llvm; using namespace LegalizeActions; -LegalizerHelper::LegalizerHelper(MachineFunction &MF) - : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()) { +LegalizerHelper::LegalizerHelper(MachineFunction &MF, + GISelChangeObserver &Observer) + : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()), + Observer(Observer) { MIRBuilder.setMF(MF); + MIRBuilder.setChangeObserver(Observer); } -LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI) - : MRI(MF.getRegInfo()), LI(LI) { +LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI, + GISelChangeObserver &Observer) + : MRI(MF.getRegInfo()), LI(LI), Observer(Observer) { MIRBuilder.setMF(MF); + MIRBuilder.setChangeObserver(Observer); } LegalizerHelper::LegalizeResult LegalizerHelper::legalizeInstrStep(MachineInstr &MI) { @@ -64,8 +70,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, MIRBuilder, Observer) ? Legalized + : UnableToLegalize; default: LLVM_DEBUG(dbgs() << ".. Unable to legalize\n"); return UnableToLegalize; @@ -682,7 +688,7 @@ // Make the original instruction a trunc now, and update its source. MI.setDesc(TII.get(TargetOpcode::G_TRUNC)); MI.getOperand(1).setReg(MIBNewOp->getOperand(0).getReg()); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } @@ -698,7 +704,7 @@ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_SHL: @@ -707,7 +713,7 @@ // unsigned integer: widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_SDIV: @@ -715,7 +721,7 @@ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_ASHR: @@ -724,7 +730,7 @@ // unsigned integer: widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_UDIV: @@ -733,7 +739,7 @@ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_SELECT: @@ -745,7 +751,7 @@ widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT); widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_FPTOSI: @@ -753,21 +759,21 @@ if (TypeIdx != 0) return UnableToLegalize; widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_SITOFP: if (TypeIdx != 1) return UnableToLegalize; widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_UITOFP: if (TypeIdx != 1) return UnableToLegalize; widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_INSERT: @@ -775,7 +781,7 @@ return UnableToLegalize; widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_LOAD: @@ -789,7 +795,7 @@ case TargetOpcode::G_SEXTLOAD: case TargetOpcode::G_ZEXTLOAD: widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_STORE: { @@ -798,7 +804,7 @@ return UnableToLegalize; widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ZEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_CONSTANT: { @@ -808,7 +814,7 @@ SrcMO.setCImm(ConstantInt::get(Ctx, Val)); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_FCONSTANT: { @@ -829,12 +835,12 @@ SrcMO.setFPImm(ConstantFP::get(Ctx, Val)); widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_BRCOND: widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_FCMP: @@ -844,7 +850,7 @@ widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT); widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_FPEXT); } - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_ICMP: @@ -858,13 +864,13 @@ widenScalarSrc(MI, WideTy, 2, ExtOpcode); widenScalarSrc(MI, WideTy, 3, ExtOpcode); } - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_GEP: assert(TypeIdx == 1 && "unable to legalize pointer of GEP"); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_PHI: { @@ -879,14 +885,14 @@ MachineBasicBlock &MBB = *MI.getParent(); MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI()); widenScalarDst(MI, WideTy); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_EXTRACT_VECTOR_ELT: if (TypeIdx != 2) return UnableToLegalize; widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } } @@ -1122,7 +1128,7 @@ case TargetOpcode::G_CTLZ_ZERO_UNDEF: { // This trivially expands to CTLZ. MI.setDesc(TII.get(TargetOpcode::G_CTLZ)); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_CTLZ: { @@ -1170,7 +1176,7 @@ case TargetOpcode::G_CTTZ_ZERO_UNDEF: { // This trivially expands to CTTZ. MI.setDesc(TII.get(TargetOpcode::G_CTTZ)); - MIRBuilder.recordInsertion(&MI); + Observer.changedInstr(MI); return Legalized; } case TargetOpcode::G_CTTZ: { Index: lib/CodeGen/GlobalISel/LegalizerInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -375,7 +376,8 @@ } bool LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const { return false; } Index: lib/CodeGen/GlobalISel/MachineIRBuilder.cpp =================================================================== --- lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -10,6 +10,7 @@ /// This file implements the MachineIRBuidler class. //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" @@ -29,7 +30,7 @@ State.TII = MF.getSubtarget().getInstrInfo(); State.DL = DebugLoc(); State.II = MachineBasicBlock::iterator(); - State.InsertedInstr = nullptr; + State.Observer = nullptr; } void MachineIRBuilderBase::setMBB(MachineBasicBlock &MBB) { @@ -54,18 +55,15 @@ } void MachineIRBuilderBase::recordInsertion(MachineInstr *InsertedInstr) const { - if (State.InsertedInstr) - State.InsertedInstr(InsertedInstr); + if (State.Observer) + State.Observer->createdInstr(*InsertedInstr); } -void MachineIRBuilderBase::recordInsertions( - std::function Inserted) { - State.InsertedInstr = std::move(Inserted); +void MachineIRBuilderBase::setChangeObserver(GISelChangeObserver &Observer) { + State.Observer = &Observer; } -void MachineIRBuilderBase::stopRecordingInsertions() { - State.InsertedInstr = nullptr; -} +void MachineIRBuilderBase::stopObservingChanges() { State.Observer = nullptr; } //------------------------------------------------------------------------------ // Build instruction variants. Index: lib/Target/AArch64/AArch64LegalizerInfo.h =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.h +++ lib/Target/AArch64/AArch64LegalizerInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINELEGALIZER_H #define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINELEGALIZER_H +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" namespace llvm { @@ -28,7 +29,8 @@ AArch64LegalizerInfo(const AArch64Subtarget &ST); bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const override; + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const override; private: bool legalizeVaArg(MachineInstr &MI, MachineRegisterInfo &MRI, Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -404,7 +404,8 @@ bool AArch64LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const { switch (MI.getOpcode()) { default: // No idea what to do. Index: lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp =================================================================== --- lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp +++ lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp @@ -32,11 +32,11 @@ AArch64PreLegalizerCombinerInfo() : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, /*LegalizerInfo*/ nullptr) {} - virtual bool combine(CombinerChangeObserver &Observer, MachineInstr &MI, + virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B) const override; }; -bool AArch64PreLegalizerCombinerInfo::combine(CombinerChangeObserver &Observer, +bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B) const { CombinerHelper Helper(Observer, B); Index: lib/Target/ARM/ARMLegalizerInfo.h =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.h +++ lib/Target/ARM/ARMLegalizerInfo.h @@ -15,6 +15,7 @@ #define LLVM_LIB_TARGET_ARM_ARMMACHINELEGALIZER_H #include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/IR/Instructions.h" @@ -29,7 +30,8 @@ ARMLegalizerInfo(const ARMSubtarget &ST); bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const override; + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const override; private: void setFCmpLibcallsGNU(); Index: lib/Target/ARM/ARMLegalizerInfo.cpp =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.cpp +++ lib/Target/ARM/ARMLegalizerInfo.cpp @@ -318,7 +318,8 @@ bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const { using namespace TargetOpcode; MIRBuilder.setInstr(MI); Index: lib/Target/Mips/MipsLegalizerInfo.h =================================================================== --- lib/Target/Mips/MipsLegalizerInfo.h +++ lib/Target/Mips/MipsLegalizerInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_LIB_TARGET_MIPS_MIPSMACHINELEGALIZER_H #define LLVM_LIB_TARGET_MIPS_MIPSMACHINELEGALIZER_H +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" namespace llvm { @@ -26,7 +27,8 @@ MipsLegalizerInfo(const MipsSubtarget &ST); bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const override; + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const override; }; } // end namespace llvm #endif Index: lib/Target/Mips/MipsLegalizerInfo.cpp =================================================================== --- lib/Target/Mips/MipsLegalizerInfo.cpp +++ lib/Target/Mips/MipsLegalizerInfo.cpp @@ -58,7 +58,8 @@ bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &MIRBuilder) const { + MachineIRBuilder &MIRBuilder, + GISelChangeObserver &Observer) const { using namespace TargetOpcode; Index: unittests/CodeGen/GlobalISel/LegalizerHelperTest.h =================================================================== --- unittests/CodeGen/GlobalISel/LegalizerHelperTest.h +++ unittests/CodeGen/GlobalISel/LegalizerHelperTest.h @@ -8,6 +8,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" Index: unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp =================================================================== --- unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -11,6 +11,13 @@ namespace { +class DummyGISelObserver : public GISelChangeObserver { +public: + void changedInstr(MachineInstr &MI) override {} + void createdInstr(MachineInstr &MI) override {} + void erasedInstr(MachineInstr &MI) override {} +}; + // 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) { @@ -23,7 +30,8 @@ // Build Instr auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); // Perform Legalization ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -51,7 +59,8 @@ // Build Instr auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); // Perform Legalization ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -81,7 +90,8 @@ // Build auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -109,7 +119,8 @@ auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -132,7 +143,8 @@ // Build auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -159,7 +171,8 @@ // Build auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) == LegalizerHelper::LegalizeResult::Legalized); @@ -189,7 +202,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); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) == LegalizerHelper::LegalizeResult::Legalized); @@ -228,7 +242,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); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -260,7 +275,8 @@ auto MIBTrunc = B.buildTrunc(s8, Copies[0]); auto MIBCTLZ_ZU = B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, s8, MIBTrunc); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -292,7 +308,8 @@ auto MIBTrunc = B.buildTrunc(s8, Copies[0]); auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, s8, MIBTrunc); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBCTPOP, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -323,7 +340,8 @@ auto MIBCTTZ_ZERO_UNDEF = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, s8, MIBTrunc); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -353,7 +371,8 @@ auto MIBTrunc = B.buildTrunc(s8, Copies[0]); auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, s8, MIBTrunc); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -388,7 +407,8 @@ .addUse(MIBTrunc->getOperand(0).getReg()) .addUse(MIBTrunc->getOperand(0).getReg()); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) == LegalizerHelper::LegalizeResult::Legalized); @@ -426,7 +446,8 @@ .addUse(MIBTrunc->getOperand(0).getReg()) .addUse(MIBTrunc->getOperand(0).getReg()); AInfo Info(MF->getSubtarget()); - LegalizerHelper Helper(*MF, Info); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer); ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) == LegalizerHelper::LegalizeResult::Legalized);