[mips] Expand pseudo instructions before they are emitted in
authorAkira Hatanaka <ahatanaka@mips.com>
Mon, 11 Feb 2013 22:35:40 +0000 (22:35 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Mon, 11 Feb 2013 22:35:40 +0000 (22:35 +0000)
MipsCodeEmitter.cpp.

JALR and NOP are expanded by function emitPseudoExpansionLowering, which is not
called when the old JIT is used.

This fixes the following tests which have been failing on
llvm-mips-linux builder:

LLVM :: ExecutionEngine__2003-01-04-LoopTest.ll
LLVM :: ExecutionEngine__2003-05-06-LivenessClobber.ll
LLVM :: ExecutionEngine__2003-06-04-bzip2-bug.ll
LLVM :: ExecutionEngine__2005-12-02-TailCallBug.ll
LLVM :: ExecutionEngine__2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll
LLVM :: ExecutionEngine__hello2.ll
LLVM :: ExecutionEngine__stubs.ll
LLVM :: ExecutionEngine__test-branch.ll
LLVM :: ExecutionEngine__test-call.ll
LLVM :: ExecutionEngine__test-common-symbols.ll
LLVM :: ExecutionEngine__test-loadstore.ll
LLVM :: ExecutionEngine__test-loop.ll

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

lib/Target/Mips/MipsCodeEmitter.cpp

index ab3bfd970c6c71dc2b02dd1093daa76beabd0ebe..df877b65484800167d026c07a1fd5b9ce74b9730 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/Passes.h"
@@ -80,7 +81,8 @@ public:
   /// machine instructions.
   uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
 
-  void emitInstruction(const MachineInstr &MI);
+  void emitInstruction(MachineBasicBlock::instr_iterator MI,
+                       MachineBasicBlock &MBB);
 
 private:
 
@@ -112,6 +114,10 @@ private:
 
   void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
                                   int Offset) const;
+
+  /// \brief Expand pseudo instruction. Return true if MI was expanded.
+  bool expandPseudos(MachineBasicBlock::instr_iterator &MI,
+                     MachineBasicBlock &MBB) const;
 };
 }
 
@@ -140,8 +146,8 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
         MBB != E; ++MBB){
       MCE.StartMachineBasicBlock(MBB);
       for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(),
-           E = MBB->instr_end(); I != E; ++I)
-        emitInstruction(*I);
+           E = MBB->instr_end(); I != E;)
+        emitInstruction(*I++, *MBB);
     }
   } while (MCE.finishFunction(MF));
 
@@ -266,19 +272,21 @@ void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
                                              Reloc, BB));
 }
 
-void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
-  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
-
-  MCE.processDebugLoc(MI.getDebugLoc(), true);
+void MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
+                                      MachineBasicBlock &MBB) {
+  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);
 
-  // Skip pseudo instructions.
-  if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
+  // Expand pseudo instruction. Skip if MI was not expanded.
+  if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) &&
+      !expandPseudos(MI, MBB))
     return;
 
-  emitWord(getBinaryCodeForInstr(MI));
+  MCE.processDebugLoc(MI->getDebugLoc(), true);
+
+  emitWord(getBinaryCodeForInstr(*MI));
   ++NumEmitted;  // Keep track of the # of mi's emitted
 
-  MCE.processDebugLoc(MI.getDebugLoc(), false);
+  MCE.processDebugLoc(MI->getDebugLoc(), false);
 }
 
 void MipsCodeEmitter::emitWord(unsigned Word) {
@@ -290,6 +298,25 @@ void MipsCodeEmitter::emitWord(unsigned Word) {
     MCE.emitWordBE(Word);
 }
 
+bool MipsCodeEmitter::expandPseudos(MachineBasicBlock::instr_iterator &MI,
+                                    MachineBasicBlock &MBB) const {
+  switch (MI->getOpcode()) {
+  case Mips::NOP:
+    BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::SLL), Mips::ZERO)
+      .addReg(Mips::ZERO).addImm(0);
+    break;
+  case Mips::JALRPseudo:
+    BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::JALR), Mips::RA)
+      .addReg(MI->getOperand(0).getReg());
+    break;
+  default:
+    return false;
+  }
+
+  (MI--)->eraseFromBundle();
+  return true;
+}
+
 /// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
 /// code to the specified MCE object.
 FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,