[GISel]: Provide standard interface to observe changes in GISel passes
https://reviews.llvm.org/D54980
This provides a standard API across GISel passes to observe and notify
passes about changes (insertions/deletions/mutations) to MachineInstrs.
This patch also removes the recordInsertion method in MachineIRBuilder
and instead provides method to setObserver.
Reviewed by: vkeles.
llvm-svn: 348406
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
index fa49e8c..36a33de 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/llvm/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);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index ee67f90..9f9a1de 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/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.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
index 98c5b98..d73aec9 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
@@ -17,7 +17,7 @@
#include <cassert>
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
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
new file mode 100644
index 0000000..f53cfb1
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
@@ -0,0 +1,38 @@
+//== ----- 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
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 4d804d0..4d3e4a3 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/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.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 755805d..c17253d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/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
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index a837cf0..802e0c9 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/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<void(MachineInstr *)> 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<void(MachineInstr *)> InsertedInstr);
- void stopRecordingInsertions();
+ void setChangeObserver(GISelChangeObserver &Observer);
+ void stopObservingChanges();
/// @}
/// Set the debug location to \p DL for all the next build instructions.
diff --git a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
index f3f075a..8f7431d 100644
--- a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
@@ -12,12 +12,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/Combiner.h"
-#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
-#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
-#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
+#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
+#include "llvm/CodeGen/GlobalISel/GISelWorkList.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);
+ }
};
}
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 557bc88..179c073 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/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) {}
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 9a2aac9..a05ee38 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/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<TargetPassConfig>();
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<MachineFunction *> 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;
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index d3773c6..971721d 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/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: {
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
index ca776de..926af3f 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
+++ b/llvm/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;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index c7b98c6..9f99640 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/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<void(MachineInstr *)> 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.
diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp
index 4b5e10a..5e989a9 100644
--- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp
+++ b/llvm/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.
diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h
index a745b0e..77e8bdc 100644
--- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h
+++ b/llvm/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,
diff --git a/llvm/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp
index 32487b9..5022b62 100644
--- a/llvm/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp
+++ b/llvm/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);
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index 42b164f..b8f5def 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/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);
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.h b/llvm/lib/Target/ARM/ARMLegalizerInfo.h
index 78ab941..527bf87 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.h
+++ b/llvm/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();
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index 6a8688f..02e787f 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/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;
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.h b/llvm/lib/Target/Mips/MipsLegalizerInfo.h
index 96d9574..75fadd6 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.h
+++ b/llvm/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
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index f0527611..9ab5a80 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/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);
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h
index 28af811..0a171a7 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.h
+++ b/llvm/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"