mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 18:29:45 +00:00
[mips][micromips] Use call instructions with short delay slots
Differential Revision: http://reviews.llvm.org/D6338 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222752 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
333d5c9f51
commit
137c475805
@ -520,36 +520,66 @@ Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB,
|
|||||||
return Branch;
|
return Branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For given opcode returns opcode of corresponding instruction with short
|
||||||
|
// delay slot.
|
||||||
|
static int getEquivalentCallShort(int Opcode) {
|
||||||
|
switch (Opcode) {
|
||||||
|
case Mips::BGEZAL:
|
||||||
|
return Mips::BGEZALS_MM;
|
||||||
|
case Mips::BLTZAL:
|
||||||
|
return Mips::BLTZALS_MM;
|
||||||
|
case Mips::JAL:
|
||||||
|
return Mips::JALS_MM;
|
||||||
|
case Mips::JALR:
|
||||||
|
return Mips::JALRS_MM;
|
||||||
|
case Mips::JALR16_MM:
|
||||||
|
return Mips::JALRS16_MM;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unexpected call instruction for microMIPS.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
|
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
|
||||||
/// We assume there is only one delay slot per delayed instruction.
|
/// We assume there is only one delay slot per delayed instruction.
|
||||||
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
|
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
bool InMicroMipsMode = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode();
|
bool InMicroMipsMode = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode();
|
||||||
|
const MipsInstrInfo *TII =
|
||||||
|
static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo());
|
||||||
|
|
||||||
for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
|
for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
|
||||||
if (!hasUnoccupiedSlot(&*I))
|
if (!hasUnoccupiedSlot(&*I))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// For microMIPS, at the moment, do not fill delay slots of call
|
++FilledSlots;
|
||||||
// instructions.
|
Changed = true;
|
||||||
//
|
|
||||||
// TODO: Support for replacing regular call instructions with corresponding
|
|
||||||
// short delay slot instructions should be implemented.
|
|
||||||
if (!InMicroMipsMode || !I->isCall()) {
|
|
||||||
++FilledSlots;
|
|
||||||
Changed = true;
|
|
||||||
|
|
||||||
// Delay slot filling is disabled at -O0.
|
// Delay slot filling is disabled at -O0.
|
||||||
if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) {
|
if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) {
|
||||||
if (searchBackward(MBB, I))
|
bool Filled = false;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (I->isTerminator()) {
|
if (searchBackward(MBB, I)) {
|
||||||
if (searchSuccBBs(MBB, I))
|
Filled = true;
|
||||||
continue;
|
} else if (I->isTerminator()) {
|
||||||
} else if (searchForward(MBB, I)) {
|
if (searchSuccBBs(MBB, I)) {
|
||||||
continue;
|
Filled = true;
|
||||||
}
|
}
|
||||||
|
} else if (searchForward(MBB, I)) {
|
||||||
|
Filled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Filled) {
|
||||||
|
// Get instruction with delay slot.
|
||||||
|
MachineBasicBlock::instr_iterator DSI(I);
|
||||||
|
|
||||||
|
if (InMicroMipsMode && TII->GetInstSizeInBytes(std::next(DSI)) == 2 &&
|
||||||
|
DSI->isCall()) {
|
||||||
|
// If instruction in delay slot is 16b change opcode to
|
||||||
|
// corresponding instruction with short delay slot.
|
||||||
|
DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,8 +595,6 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Bundle the NOP to the instruction with the delay slot.
|
// Bundle the NOP to the instruction with the delay slot.
|
||||||
const MipsInstrInfo *TII = static_cast<const MipsInstrInfo *>(
|
|
||||||
TM.getSubtargetImpl()->getInstrInfo());
|
|
||||||
BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
|
BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
|
||||||
MIBundleBuilder(MBB, I, std::next(I, 2));
|
MIBundleBuilder(MBB, I, std::next(I, 2));
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \
|
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \
|
||||||
; RUN: -relocation-model=pic -O3 < %s | FileCheck %s
|
; RUN: -relocation-model=static -O2 < %s | FileCheck %s
|
||||||
|
|
||||||
; Function Attrs: nounwind uwtable
|
; Function Attrs: nounwind
|
||||||
define i32 @foo(i32 %a) #0 {
|
define i32 @foo(i32 signext %a) #0 {
|
||||||
entry:
|
entry:
|
||||||
%a.addr = alloca i32, align 4
|
%a.addr = alloca i32, align 4
|
||||||
store i32 %a, i32* %a.addr, align 4
|
store i32 %a, i32* %a.addr, align 4
|
||||||
%0 = load i32* %a.addr, align 4
|
%0 = load i32* %a.addr, align 4
|
||||||
%shl = shl i32 %0, 2
|
%shl = shl i32 %0, 2
|
||||||
%call = call i32 @bar(i32 %shl)
|
%call = call i32 @bar(i32 signext %shl)
|
||||||
ret i32 %call
|
ret i32 %call
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @bar(i32) #1
|
declare i32 @bar(i32 signext) #1
|
||||||
|
|
||||||
; CHECK: nop
|
|
||||||
|
|
||||||
|
; CHECK: jals
|
||||||
|
; CHECK-NEXT: sll16
|
||||||
|
Loading…
Reference in New Issue
Block a user