From 85e08ed8a4f5b390c79227238d2ec5e1f7369dcd Mon Sep 17 00:00:00 2001 From: Jozef Kolek Date: Fri, 13 Feb 2015 17:51:27 +0000 Subject: [PATCH] [mips][microMIPS] Delay slot filler: Replace the microMIPS JR with the JRC This patch adds functionality in MIPS delay slot filler such as if delay slot filler have to put NOP instruction into the delay slot of microMIPS JR instruction, then instead of emitting NOP this instruction is replaced by compact jump instruction JRC. Differential Revision: http://reviews.llvm.org/D7522 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229128 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsDelaySlotFiller.cpp | 53 ++++++++++++++++---- test/CodeGen/Mips/longbranch.ll | 3 +- test/CodeGen/Mips/micromips-compact-jump.ll | 11 ++++ test/CodeGen/Mips/micromips-delay-slot-jr.ll | 6 +-- 4 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 test/CodeGen/Mips/micromips-compact-jump.ll diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index 8c2040d5c16..ac03c0bd3dd 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -199,6 +199,9 @@ namespace { Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, DebugLoc DL); + Iter replaceWithCompactJump(MachineBasicBlock &MBB, + Iter Jump, DebugLoc DL); + /// This function checks if it is valid to move Candidate to the delay slot /// and returns true if it isn't. It also updates memory and register /// dependence information. @@ -515,6 +518,24 @@ Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, return Branch; } +// Replace Jumps with the compact jump instruction. +Iter Filler::replaceWithCompactJump(MachineBasicBlock &MBB, + Iter Jump, DebugLoc DL) { + const MipsInstrInfo *TII = + MBB.getParent()->getSubtarget().getInstrInfo(); + + const MCInstrDesc &NewDesc = TII->get(Mips::JRC16_MM); + MachineInstrBuilder MIB = BuildMI(MBB, Jump, DL, NewDesc); + + MIB.addReg(Jump->getOperand(0).getReg()); + + Iter tmpIter = Jump; + Jump = std::prev(Jump); + MBB.erase(tmpIter); + + return Jump; +} + // For given opcode returns opcode of corresponding instruction with short // delay slot. static int getEquivalentCallShort(int Opcode) { @@ -582,17 +603,29 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // adding NOP replace this instruction with the corresponding compact // branch instruction, i.e. BEQZC or BNEZC. unsigned Opcode = I->getOpcode(); - if (InMicroMipsMode && - (Opcode == Mips::BEQ || Opcode == Mips::BNE) && - ((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { - - I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); - - } else { - // Bundle the NOP to the instruction with the delay slot. - BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); - MIBundleBuilder(MBB, I, std::next(I, 2)); + if (InMicroMipsMode) { + switch (Opcode) { + case Mips::BEQ: + case Mips::BNE: + if (((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { + I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); + continue; + } + break; + case Mips::JR: + case Mips::PseudoReturn: + case Mips::PseudoIndirectBranch: + // For microMIPS the PseudoReturn and PseudoIndirectBranch are allways + // expanded to JR_MM, so they can be replaced with JRC16_MM. + I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); + continue; + default: + break; + } } + // Bundle the NOP to the instruction with the delay slot. + BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); + MIBundleBuilder(MBB, I, std::next(I, 2)); } return Changed; diff --git a/test/CodeGen/Mips/longbranch.ll b/test/CodeGen/Mips/longbranch.ll index 821ced8e7b8..f61b250491e 100644 --- a/test/CodeGen/Mips/longbranch.ll +++ b/test/CodeGen/Mips/longbranch.ll @@ -126,8 +126,7 @@ end: ; MICROMIPS: li16 $[[R2:[0-9]+]], 1 ; MICROMIPS: sw16 $[[R2]], 0($[[R1]]) ; MICROMIPS: $[[BB2]]: -; MICROMIPS: jr $ra -; MICROMIPS: nop +; MICROMIPS: jrc $ra ; Check the NaCl version. Check that sp change is not in the branch delay slot diff --git a/test/CodeGen/Mips/micromips-compact-jump.ll b/test/CodeGen/Mips/micromips-compact-jump.ll new file mode 100644 index 00000000000..70cff84e967 --- /dev/null +++ b/test/CodeGen/Mips/micromips-compact-jump.ll @@ -0,0 +1,11 @@ +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \ +; RUN: -disable-mips-delay-filler -O3 < %s | FileCheck %s + +define i32 @foo(i32 signext %a) #0 { +entry: + ret i32 0 +} + +declare i32 @bar(i32 signext) #1 + +; CHECK: jrc diff --git a/test/CodeGen/Mips/micromips-delay-slot-jr.ll b/test/CodeGen/Mips/micromips-delay-slot-jr.ll index df593b35e2a..09a98c2a7d1 100644 --- a/test/CodeGen/Mips/micromips-delay-slot-jr.ll +++ b/test/CodeGen/Mips/micromips-delay-slot-jr.ll @@ -29,8 +29,7 @@ declare i32 @puts(i8* nocapture readonly) #1 !3 = !{!"omnipotent char", !4, i64 0} !4 = !{!"Simple C/C++ TBAA"} -; CHECK: jr -; CHECK-NEXT: nop +; CHECK: jrc %struct.foostruct = type { [3 x float] } %struct.barstruct = type { %struct.foostruct, float } @@ -43,6 +42,5 @@ define float* @spooky(i32 signext %i) #0 { } ; CHECK: spooky: -; CHECK: jr $ra -; CHECK-NEXT: nop +; CHECK: jrc $ra -- 2.34.1