Add target hook for pseudo instruction expansion.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 25 Sep 2011 19:21:35 +0000 (19:21 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 25 Sep 2011 19:21:35 +0000 (19:21 +0000)
Many targets use pseudo instructions to help register allocation.  Like
the COPY instruction, these pseudos can be expanded after register
allocation.  The early expansion can make life easier for PEI and the
post-ra scheduler.

This patch adds a hook that is called for all remaining pseudo
instructions from the ExpandPostRAPseudos pass.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140472 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCInstrDesc.h
include/llvm/Target/TargetInstrInfo.h
lib/CodeGen/ExpandPostRAPseudos.cpp
utils/TableGen/InstrInfoEmitter.cpp

index 7061fcb0128404586d94e5a8d493f8e53d126599..aafa800c1ac86c7cd2d83efbd00304b1b1ec534c 100644 (file)
@@ -97,6 +97,7 @@ namespace MCID {
   enum {
     Variadic = 0,
     HasOptionalDef,
+    Pseudo,
     Return,
     Call,
     Barrier,
@@ -275,6 +276,13 @@ public:
     return Size;
   }
 
+  /// isPseudo - Return true if this is a pseudo instruction that doesn't
+  /// correspond to a real machine instruction.
+  ///
+  bool isPseudo() const {
+    return Flags & (1 << MCID::Pseudo);
+  }
+
   bool isReturn() const {
     return Flags & (1 << MCID::Return);
   }
index e6e963c03e2e7f4c7ba5da5b7ce6cbf985cde028..bbe58978210a46fc0c1d31251a9fa87e57dc4d62 100644 (file)
@@ -386,6 +386,16 @@ public:
   assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
   }
 
+  /// expandPostRAPseudo - This function is called for all pseudo instructions
+  /// that remain after register allocation. Many pseudo instructions are
+  /// created to help register allocation. This is the place to convert them
+  /// into real instructions. The target can edit MI in place, or it can insert
+  /// new instructions and erase MI. The function should return true if
+  /// anything was changed.
+  bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
+    return false;
+  }
+
   /// emitFrameIndexDebugValue - Emit a target-dependent form of
   /// DBG_VALUE encoding the address of a frame index.  Addresses would
   /// normally be lowered the same way as other addresses on the target,
index 78382f548cbf73d0977da2000f2443bd654a70c7..623b67ddcd67a0481db35a53932e7c63a61a6110 100644 (file)
@@ -202,17 +202,26 @@ bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) {
        mbbi != mbbe; ++mbbi) {
     for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
          mi != me;) {
-      MachineBasicBlock::iterator nmi = llvm::next(mi);
       MachineInstr *MI = mi;
-      assert(!MI->isInsertSubreg() && "INSERT_SUBREG should no longer appear");
-      assert(MI->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
-             "EXTRACT_SUBREG should no longer appear");
-      if (MI->isSubregToReg()) {
+      // Advance iterator here because MI may be erased.
+      ++mi;
+      switch (MI->getOpcode()) {
+      case TargetOpcode::SUBREG_TO_REG:
         MadeChange |= LowerSubregToReg(MI);
-      } else if (MI->isCopy()) {
+        break;
+      case TargetOpcode::COPY:
         MadeChange |= LowerCopy(MI);
+        break;
+      case TargetOpcode::DBG_VALUE:
+        continue;
+      case TargetOpcode::INSERT_SUBREG:
+      case TargetOpcode::EXTRACT_SUBREG:
+        llvm_unreachable("Sub-register pseudos should have been eliminated.");
+      default:
+        if (MI->getDesc().isPseudo())
+          MadeChange |= TII->expandPostRAPseudo(MI);
+        break;
       }
-      mi = nmi;
     }
   }
 
index 1cf7c90496280111aa2a67b5fe0fc5e8aa2ecf96..35fe728f9e43d6a0b1728e60d3164d392ea04acc 100644 (file)
@@ -268,6 +268,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
      << Inst.TheDef->getName() << "\", 0";
 
   // Emit all of the target indepedent flags...
+  if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)";
   if (Inst.isReturn)           OS << "|(1<<MCID::Return)";
   if (Inst.isBranch)           OS << "|(1<<MCID::Branch)";
   if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)";