[mips] Expand pseudo instructions before they are emitted in

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

llvm-svn: 174912
This commit is contained in:
Akira Hatanaka 2013-02-11 22:35:40 +00:00
parent b1b156b0e8
commit 10788fa4a6

View 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);
void MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
MachineBasicBlock &MBB) {
DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);
MCE.processDebugLoc(MI.getDebugLoc(), true);
// 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,