DebugLoc dl = MI.getDebugLoc();
unsigned CC = (SPCC::CondCodes)MI.getOperand(3).getImm();
- // 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.
+ // To "insert" a SELECT_CC instruction, we actually have to insert the
+ // triangle 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 the condition code for the branch.
+ //
+ // We produce the following control flow:
+ // ThisMBB
+ // | \
+ // | IfFalseMBB
+ // | /
+ // SinkMBB
const BasicBlock *LLVM_BB = BB->getBasicBlock();
MachineFunction::iterator It = ++BB->getIterator();
- // thisMBB:
- // ...
- // TrueVal = ...
- // [f]bCC copy1MBB
- // fallthrough --> copy0MBB
- MachineBasicBlock *thisMBB = BB;
+ 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,
- std::next(MachineBasicBlock::iterator(MI)),
- BB->end());
- sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
-
- // Add the true and fallthrough blocks as its successors.
- BB->addSuccessor(copy0MBB);
- BB->addSuccessor(sinkMBB);
-
- BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC);
-
- // copy0MBB:
- // %FalseValue = ...
- // # fallthrough to sinkMBB
- BB = copy0MBB;
-
- // Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
-
- // sinkMBB:
- // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
- // ...
- BB = sinkMBB;
- BuildMI(*BB, BB->begin(), dl, TII.get(SP::PHI), MI.getOperand(0).getReg())
- .addReg(MI.getOperand(2).getReg())
- .addMBB(copy0MBB)
+ MachineBasicBlock *IfFalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ F->insert(It, IfFalseMBB);
+ F->insert(It, SinkMBB);
+
+ // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
+ SinkMBB->splice(SinkMBB->begin(), ThisMBB,
+ std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
+ SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);
+
+ // Set the new successors for ThisMBB.
+ ThisMBB->addSuccessor(IfFalseMBB);
+ ThisMBB->addSuccessor(SinkMBB);
+
+ BuildMI(ThisMBB, dl, TII.get(BROpcode))
+ .addMBB(SinkMBB)
+ .addImm(CC);
+
+ // IfFalseMBB just falls through to SinkMBB.
+ IfFalseMBB->addSuccessor(SinkMBB);
+
+ // %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ]
+ BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(SP::PHI),
+ MI.getOperand(0).getReg())
.addReg(MI.getOperand(1).getReg())
- .addMBB(thisMBB);
+ .addMBB(ThisMBB)
+ .addReg(MI.getOperand(2).getReg())
+ .addMBB(IfFalseMBB);
MI.eraseFromParent(); // The pseudo instruction is gone now.
- return BB;
+ return SinkMBB;
}
MachineBasicBlock *