GlobalISel: perform multi-step legalization

llvm-svn: 279758
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 2cb7e66..50896ab 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -26,6 +26,7 @@
   this->TII = MF.getSubtarget().getInstrInfo();
   this->DL = DebugLoc();
   this->MI = nullptr;
+  this->InsertedInstr = nullptr;
 }
 
 void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) {
@@ -53,6 +54,15 @@
   return Before ? getMBB().begin() : getMBB().end();
 }
 
+void MachineIRBuilder::recordInsertions(
+    std::function<void(MachineInstr *)> Inserted) {
+  InsertedInstr = Inserted;
+}
+
+void MachineIRBuilder::stopRecordingInsertions() {
+  InsertedInstr = nullptr;
+}
+
 //------------------------------------------------------------------------------
 // Build instruction variants.
 //------------------------------------------------------------------------------
@@ -69,6 +79,8 @@
     assert(!isPreISelGenericOpcode(Opcode) &&
            "Generic instruction must have a type");
   getMBB().insert(getInsertPt(), MIB);
+  if (InsertedInstr)
+    InsertedInstr(MIB);
   return MIB;
 }
 
@@ -181,6 +193,8 @@
     MIB.addImm(Idx);
 
   getMBB().insert(getInsertPt(), MIB);
+  if (InsertedInstr)
+    InsertedInstr(MIB);
 
   return MIB;
 }
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index c7d30cf..66b7166 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -31,8 +31,9 @@
   MIRBuilder.setMF(MF);
 }
 
-MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr(
-    MachineInstr &MI, const MachineLegalizer &Legalizer) {
+MachineLegalizeHelper::LegalizeResult
+MachineLegalizeHelper::legalizeInstrStep(MachineInstr &MI,
+                                         const MachineLegalizer &Legalizer) {
   auto Action = Legalizer.getAction(MI);
   switch (std::get<0>(Action)) {
   case MachineLegalizer::Legal:
@@ -48,6 +49,30 @@
   }
 }
 
+MachineLegalizeHelper::LegalizeResult
+MachineLegalizeHelper::legalizeInstr(MachineInstr &MI,
+                                     const MachineLegalizer &Legalizer) {
+  std::queue<MachineInstr *> WorkList;
+  MIRBuilder.recordInsertions([&](MachineInstr *MI) { WorkList.push(MI); });
+  WorkList.push(&MI);
+
+  bool Changed = false;
+  LegalizeResult Res;
+  do {
+    Res = legalizeInstrStep(*WorkList.front(), Legalizer);
+    if (Res == UnableToLegalize) {
+      MIRBuilder.stopRecordingInsertions();
+      return UnableToLegalize;
+    }
+    Changed |= Res == Legalized;
+    WorkList.pop();
+  } while (!WorkList.empty());
+
+  MIRBuilder.stopRecordingInsertions();
+
+  return Changed ? Legalized : AlreadyLegal;
+}
+
 void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
                                          SmallVectorImpl<unsigned> &VRegs) {
   unsigned Size = Ty.getSizeInBits();