From ffbe432595c78ba28c8a9d200bf92996eed5e5d9 Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Thu, 21 Feb 2013 04:22:38 +0000 Subject: Expand the sel pseudo/macro. This generates basic blocks where previously there were inline br .+4 instructions. Soon everything can enjoy the full instruction scheduling experience. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175718 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips16InstrInfo.td | 20 ++++++++++ lib/Target/Mips/MipsISelLowering.cpp | 75 +++++++++++++++++++++++++++++++++++- lib/Target/Mips/MipsISelLowering.h | 3 ++ test/CodeGen/Mips/selpat.ll | 6 +-- 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 1cb4a0edfd..9e07b95cc6 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -76,6 +76,10 @@ class F2RI16_ins _op, string asmstr, let Constraints = "$rx_ = $rx"; } +class FRI16_B_ins _op, string asmstr, + InstrItinClass itin>: + FRI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm), + !strconcat(asmstr, "\t$rx, $imm # 16 bit inst"), [], itin>; // // Compare a register and immediate and place result in CC // Implicit use of T8 @@ -362,6 +366,7 @@ class Sel: !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), []> { //let isCodeGenOnly=1; let Constraints = "$rd = $rd_"; + let usesCustomInserter = 1; } // @@ -518,6 +523,14 @@ def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>; def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>; +// +// Format: BEQZ rx, offset MIPS16e +// Purpose: Branch on Equal to Zero +// To test a GPR then do a PC-relative conditional branch. +// +def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; + + // // Format: BEQZ rx, offset MIPS16e // Purpose: Branch on Equal to Zero (Extended) @@ -531,6 +544,13 @@ def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; // def BimmX16: FEXT_I16_ins<0b00010, "b", IIAlu>, branch16; +// +// Format: BNEZ rx, offset MIPS16e +// Purpose: Branch on Not Equal to Zero +// To test a GPR then do a PC-relative conditional branch. +// +def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16; + // // Format: BNEZ rx, offset MIPS16e // Purpose: Branch on Not Equal to Zero (Extended) diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index e0080e6e2c..5605759bd3 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -55,6 +55,12 @@ Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("MIPS: mips16 hard float enable."), cl::init(false)); +static cl::opt DontExpandCondPseudos16( + "mips16-dont-expand-cond-pseudo", + cl::init(false), + cl::desc("Dont expand conditional move related " + "pseudos for Mips 16"), + cl::Hidden); static const uint16_t O32IntRegs[4] = { @@ -1230,11 +1236,74 @@ MipsTargetLowering::EmitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ return Sink; } +MachineBasicBlock *MipsTargetLowering::EmitSel16(unsigned Opc, MachineInstr *MI, + MachineBasicBlock *BB) const { + if (DontExpandCondPseudos16) + return BB; + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + // To "insert" a SELECT_CC instruction, we actually have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // setcc r1, r2, r3 + // bNE r1, r0, copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *thisMBB = BB; + MachineFunction *F = BB->getParent(); + MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, copy0MBB); + F->insert(It, sinkMBB); + + // Transfer the remainder of BB and its successor edges to sinkMBB. + sinkMBB->splice(sinkMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + sinkMBB->transferSuccessorsAndUpdatePHIs(BB); + + // Next, add the true and fallthrough blocks as its successors. + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + BuildMI(BB, dl, TII->get(Opc)).addReg(MI->getOperand(3).getReg()) + .addMBB(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] + // ... + BB = sinkMBB; + + BuildMI(*BB, BB->begin(), dl, + TII->get(Mips::PHI), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB) + .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB); + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return BB; +} + MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { switch (MI->getOpcode()) { - default: llvm_unreachable("Unexpected instr type to insert"); + default: + llvm_unreachable("Unexpected instr type to insert"); case Mips::ATOMIC_LOAD_ADD_I8: case Mips::ATOMIC_LOAD_ADD_I8_P8: return EmitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu); @@ -1340,6 +1409,10 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return EmitAtomicCmpSwap(MI, BB, 8); case Mips::BPOSGE32_PSEUDO: return EmitBPOSGE32(MI, BB); + case Mips::SelBeqZ: + return EmitSel16(Mips::BeqzRxImm16, MI, BB); + case Mips::SelBneZ: + return EmitSel16(Mips::BnezRxImm16, MI, BB); } } diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 3b4635553b..2531a20b0f 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -404,6 +404,9 @@ namespace llvm { MachineBasicBlock *BB, unsigned Size) const; MachineBasicBlock *EmitAtomicCmpSwapPartword(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size) const; + MachineBasicBlock *EmitSel16(unsigned Opc, MachineInstr *MI, + MachineBasicBlock *BB) const; + }; } diff --git a/test/CodeGen/Mips/selpat.ll b/test/CodeGen/Mips/selpat.ll index cda0c96ef4..57cc126bed 100644 --- a/test/CodeGen/Mips/selpat.ll +++ b/test/CodeGen/Mips/selpat.ll @@ -67,7 +67,7 @@ entry: %2 = load i32* @f, align 4 %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: beqz ${{[0-9]+}}, .+4 +; 16: beqz ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %cmp1 = icmp eq i32 %3, 0 @@ -238,7 +238,7 @@ entry: %2 = load i32* @t, align 4 %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: bnez ${{[0-9]+}}, .+4 +; 16: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %cmp1 = icmp ne i32 %3, 0 @@ -260,7 +260,7 @@ entry: %2 = load i32* @t, align 4 %cond = select i1 %tobool, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: bnez ${{[0-9]+}}, .+4 +; 16: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %tobool1 = icmp ne i32 %3, 0 -- cgit v1.2.3-18-g5258