[LLVMdev] splitting a branch within a pseudo
Reed Kotler
rkotler at mips.com
Sun Feb 17 16:53:23 PST 2013
Some stuff did not get pasted in properly.
static MachineBasicBlock* ExpandCondMov(MachineInstr *MI,
MachineBasicBlock *BB,
DebugLoc dl,
const MipsSubtarget *Subtarget,
const TargetInstrInfo *TII,
bool isFPCmp, unsigned Opc) {
// There is no need to expand CMov instructions if target has
// conditional moves.
if (Subtarget->hasCondMov())
return BB;
// 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);
// Emit the right instruction according to the type of the operands
compared
if (isFPCmp)
BuildMI(BB, dl, TII->get(Opc)).addMBB(sinkMBB);
else
BuildMI(BB, dl, TII->get(Opc)).addReg(MI->getOperand(2).getReg())
.addReg(Mips::ZERO).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;
if (isFPCmp)
BuildMI(*BB, BB->begin(), dl,
TII->get(Mips::PHI), MI->getOperand(0).getReg())
.addReg(MI->getOperand(2).getReg()).addMBB(thisMBB)
.addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB);
else
BuildMI(*BB, BB->begin(), dl,
TII->get(Mips::PHI), MI->getOperand(0).getReg())
.addReg(MI->getOperand(3).getReg()).addMBB(thisMBB)
.addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB);
MI->eraseFromParent(); // The pseudo instruction is gone now.
return BB;
}
On 02/17/2013 04:45 PM, Reed Kotler wrote:
> This is the old MIPS I code that sort of does what I need to do. This
> seems really involved to do such a simple thing.
>
> Maybe there are now helper classes for this or some better example I can
> look at. I suppose I can mimick this if people say this just the correct
> way to do this in LLVM.
>
> static MachineBasicBlock* ExpandCondMov(MachineInstr *MI,
> MachineBasicBlock *BB,
> DebugLoc dl,
> const MipsSubtarget *Subtarget,
> const TargetInstrInfo *TII,
> bool isFPCmp, unsigned Opc) {
> // There is no need to expand CMov instructions if target has
> // conditional moves.
> if (Subtarget->hasCondMov())
> return BB;
>
> // 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->a
> On 02/17/2013 12:51 PM, Reed Kotler wrote:
>> After discussions last night, I'm leaning towards going legit with all
>> my pseudo expansions in Mips 16.
>>
>> Some I think I can clearly do by just putting in the proper side effects
>> of implicit registers (T8 the condition code register as used by mips
>> 16).
>>
>> But I'm still left with some pseudos that have jmp .+4 type instructions
>> in them.
>>
>> The original Mips port was to Mips I and Mips I, like Mips 16, has no
>> conditional store instructions.
>>
>> There was some super ugly code there to do a test and then branch around
>> the store instruction if the test was not matched. It was quite a large
>> amount of code and I'm not sure I even believe it works. It's long been
>> commented out since we don't even support Mips I anymore.
>>
>> I avoided that in Mips 16 by writing some patterns that translate to
>> something like:
>>
>> cmp rx, ry ; implicitly set T8
>> btnez foo: ; branch if T8 not zero
>> mov ra, rb
>> foo:....
>>
>> There is a way to do this in Mips asembler without needing to really
>> create a label. There are builtin forward and backward labels you can
>> use for this and that's what I do in some cases and in other cases I
>> think I just do a .+4 or something.
>>
>> SOmething like that. You can see the mips 16 patterns if you want to
>> know the details but they are not important here IMO.
>>
>> In principle I should really make machine basic blocks and do all that
>> book keeping but at least the original way is way too complicated and as
>> I said, I'm not sure I believe it even works in all cases. Too many
>> complex assumptions about the optimizer and such.
>>
>> Any ideas or code pointers for creating the kind of machine basic blocks
>> I would need to do the above without resorting to bundles?
>>
>> I like simple.
>>
>> Simple usually works always and complex always has at least one more
>> bug. :)
>>
>> Tia.
>>
>> Reed
More information about the llvm-dev
mailing list