1818#include " llvm/ADT/SmallVector.h"
1919#include " llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
2020#include " llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
21+ #include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2122#include " llvm/CodeGen/GlobalISel/Utils.h"
2223#include " llvm/CodeGen/MachineInstrBuilder.h"
2324#include " llvm/CodeGen/MachineOperand.h"
@@ -42,17 +43,33 @@ namespace llvm {
4243template <class TgtExecutor , class PredicateBitset , class ComplexMatcherMemFn ,
4344 class CustomRendererFn >
4445bool GIMatchTableExecutor::executeMatchTable (
45- TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State,
46+ TgtExecutor &Exec, MatcherState &State,
4647 const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
4748 &ExecInfo,
48- const int64_t *MatchTable, const TargetInstrInfo &TII,
49- MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
50- const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
51- CodeGenCoverage *CoverageInfo, GISelChangeObserver *Observer) const {
49+ MachineIRBuilder &Builder, const int64_t *MatchTable,
50+ const TargetInstrInfo &TII, MachineRegisterInfo &MRI,
51+ const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
52+ const PredicateBitset &AvailableFeatures,
53+ CodeGenCoverage *CoverageInfo) const {
54+
55+ // Setup observer
56+ GIMatchTableObserver MTObserver;
57+ GISelObserverWrapper Observer (&MTObserver);
58+ if (auto *CurObs = Builder.getChangeObserver ())
59+ Observer.addObserver (CurObs);
60+
61+ // TODO: Set MF delegate?
62+
63+ // Setup builder.
64+ auto RestoreOldObserver = Builder.setTemporaryChangeObserver (Observer);
5265
5366 uint64_t CurrentIdx = 0 ;
5467 SmallVector<uint64_t , 4 > OnFailResumeAt;
5568
69+ // We also record MachineInstrs manually in this vector so opcodes can address
70+ // them.
71+ SmallVector<MachineInstrBuilder, 4 > OutMIs;
72+
5673 // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
5774 bool NoFPException = !State.MIs [0 ]->getDesc ().mayRaiseFPException ();
5875
@@ -71,14 +88,16 @@ bool GIMatchTableExecutor::executeMatchTable(
7188 return RejectAndResume;
7289 };
7390
74- auto propagateFlags = [=](NewMIVector &OutMIs ) {
75- for (auto MIB : OutMIs ) {
91+ auto propagateFlags = [&]( ) {
92+ for (auto *MI : MTObserver. CreatedInsts ) {
7693 // Set the NoFPExcept flag when no original matched instruction could
7794 // raise an FP exception, but the new instruction potentially might.
7895 uint16_t MIBFlags = Flags;
79- if (NoFPException && MIB ->mayRaiseFPException ())
96+ if (NoFPException && MI ->mayRaiseFPException ())
8097 MIBFlags |= MachineInstr::NoFPExcept;
81- MIB.setMIFlags (MIBFlags);
98+ Observer.changingInstr (*MI);
99+ MI->setFlags (MIBFlags);
100+ Observer.changedInstr (*MI);
82101 }
83102
84103 return true ;
@@ -901,6 +920,7 @@ bool GIMatchTableExecutor::executeMatchTable(
901920 OutMIs[NewInsnID] = MachineInstrBuilder (*State.MIs [OldInsnID]->getMF (),
902921 State.MIs [OldInsnID]);
903922 OutMIs[NewInsnID]->setDesc (TII.get (NewOpcode));
923+ MTObserver.CreatedInsts .insert (OutMIs[NewInsnID]);
904924 DEBUG_WITH_TYPE (TgtExecutor::getName (),
905925 dbgs () << CurrentIdx << " : GIR_MutateOpcode(OutMIs["
906926 << NewInsnID << " ], MIs[" << OldInsnID << " ], "
@@ -914,8 +934,7 @@ bool GIMatchTableExecutor::executeMatchTable(
914934 if (NewInsnID >= OutMIs.size ())
915935 OutMIs.resize (NewInsnID + 1 );
916936
917- OutMIs[NewInsnID] = BuildMI (*State.MIs [0 ]->getParent (), State.MIs [0 ],
918- MIMetadata (*State.MIs [0 ]), TII.get (Opcode));
937+ OutMIs[NewInsnID] = Builder.buildInstr (Opcode);
919938 DEBUG_WITH_TYPE (TgtExecutor::getName (),
920939 dbgs () << CurrentIdx << " : GIR_BuildMI(OutMIs["
921940 << NewInsnID << " ], " << Opcode << " )\n " );
@@ -1239,8 +1258,11 @@ bool GIMatchTableExecutor::executeMatchTable(
12391258 DEBUG_WITH_TYPE (TgtExecutor::getName (),
12401259 dbgs () << CurrentIdx << " : GIR_EraseFromParent(MIs["
12411260 << InsnID << " ])\n " );
1242- if (Observer)
1243- Observer->erasingInstr (*MI);
1261+ // If we're erasing the insertion point, ensure we don't leave a dangling
1262+ // pointer in the builder.
1263+ if (Builder.getInsertPt () == MI)
1264+ Builder.setInsertPt (*MI->getParent (), ++MI->getIterator ());
1265+ Observer.erasingInstr (*MI);
12441266 MI->eraseFromParent ();
12451267 break ;
12461268 }
@@ -1269,11 +1291,9 @@ bool GIMatchTableExecutor::executeMatchTable(
12691291
12701292 Register Old = State.MIs [OldInsnID]->getOperand (OldOpIdx).getReg ();
12711293 Register New = State.MIs [NewInsnID]->getOperand (NewOpIdx).getReg ();
1272- if (Observer)
1273- Observer->changingAllUsesOfReg (MRI, Old);
1294+ Observer.changingAllUsesOfReg (MRI, Old);
12741295 MRI.replaceRegWith (Old, New);
1275- if (Observer)
1276- Observer->finishedChangingAllUsesOfReg ();
1296+ Observer.finishedChangingAllUsesOfReg ();
12771297 break ;
12781298 }
12791299 case GIR_ReplaceRegWithTempReg: {
@@ -1288,11 +1308,9 @@ bool GIMatchTableExecutor::executeMatchTable(
12881308
12891309 Register Old = State.MIs [OldInsnID]->getOperand (OldOpIdx).getReg ();
12901310 Register New = State.TempRegisters [TempRegID];
1291- if (Observer)
1292- Observer->changingAllUsesOfReg (MRI, Old);
1311+ Observer.changingAllUsesOfReg (MRI, Old);
12931312 MRI.replaceRegWith (Old, New);
1294- if (Observer)
1295- Observer->finishedChangingAllUsesOfReg ();
1313+ Observer.finishedChangingAllUsesOfReg ();
12961314 break ;
12971315 }
12981316 case GIR_Coverage: {
@@ -1309,11 +1327,7 @@ bool GIMatchTableExecutor::executeMatchTable(
13091327 case GIR_Done:
13101328 DEBUG_WITH_TYPE (TgtExecutor::getName (),
13111329 dbgs () << CurrentIdx << " : GIR_Done\n " );
1312- if (Observer) {
1313- for (MachineInstr *MI : OutMIs)
1314- Observer->createdInstr (*MI);
1315- }
1316- propagateFlags (OutMIs);
1330+ propagateFlags ();
13171331 return true ;
13181332 default :
13191333 llvm_unreachable (" Unexpected command" );
0 commit comments