forked from OSchip/llvm-project
[GlobalISel] Preserve IR block layout.
It makes the output function layout more predictable; the layout has an effect on performance, we don't want it to be at the mercy of the translator's visitation order and such. The predictable output is also easier to digest. getOrCreateBB isn't appropriately named anymore, as it never needs to create anything. Rename it and extract the MBB creation logic out of it. A couple tests were sensitive to the order. Update them. llvm-svn: 297868
This commit is contained in:
parent
d8319e99d8
commit
a61c214f51
|
@ -388,8 +388,8 @@ private:
|
|||
|
||||
/// Get the MachineBasicBlock that represents \p BB. Specifically, the block
|
||||
/// returned will be the head of the translated block (suitable for branch
|
||||
/// destinations). If such basic block does not exist, it is created.
|
||||
MachineBasicBlock &getOrCreateBB(const BasicBlock &BB);
|
||||
/// destinations).
|
||||
MachineBasicBlock &getMBB(const BasicBlock &BB);
|
||||
|
||||
/// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
|
||||
/// to `Edge.first` at the IR level. This is used when IRTranslation creates
|
||||
|
@ -405,7 +405,7 @@ private:
|
|||
auto RemappedEdge = MachinePreds.find(Edge);
|
||||
if (RemappedEdge != MachinePreds.end())
|
||||
return RemappedEdge->second;
|
||||
return SmallVector<MachineBasicBlock *, 4>(1, &getOrCreateBB(*Edge.first));
|
||||
return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -420,10 +420,10 @@ public:
|
|||
// CallLowering = MF.subtarget.getCallLowering()
|
||||
// F = MF.getParent()
|
||||
// MIRBuilder.reset(MF)
|
||||
// MIRBuilder.getOrCreateBB(F.getEntryBB())
|
||||
// getMBB(F.getEntryBB())
|
||||
// CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
|
||||
// for each bb in F
|
||||
// MIRBuilder.getOrCreateBB(bb)
|
||||
// getMBB(bb)
|
||||
// for each inst in bb
|
||||
// if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
|
||||
// report_fatal_error("Don't know how to translate input");
|
||||
|
|
|
@ -140,15 +140,9 @@ unsigned IRTranslator::getMemOpAlignment(const Instruction &I) {
|
|||
return Alignment ? Alignment : DL->getABITypeAlignment(ValTy);
|
||||
}
|
||||
|
||||
MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock &BB) {
|
||||
MachineBasicBlock &IRTranslator::getMBB(const BasicBlock &BB) {
|
||||
MachineBasicBlock *&MBB = BBToMBB[&BB];
|
||||
if (!MBB) {
|
||||
MBB = MF->CreateMachineBasicBlock(&BB);
|
||||
MF->push_back(MBB);
|
||||
|
||||
if (BB.hasAddressTaken())
|
||||
MBB->setHasAddressTaken();
|
||||
}
|
||||
assert(MBB && "BasicBlock was not encountered before");
|
||||
return *MBB;
|
||||
}
|
||||
|
||||
|
@ -221,18 +215,18 @@ bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) {
|
|||
// We want a G_BRCOND to the true BB followed by an unconditional branch.
|
||||
unsigned Tst = getOrCreateVReg(*BrInst.getCondition());
|
||||
const BasicBlock &TrueTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ++));
|
||||
MachineBasicBlock &TrueBB = getOrCreateBB(TrueTgt);
|
||||
MachineBasicBlock &TrueBB = getMBB(TrueTgt);
|
||||
MIRBuilder.buildBrCond(Tst, TrueBB);
|
||||
}
|
||||
|
||||
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ));
|
||||
MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
|
||||
MachineBasicBlock &TgtBB = getMBB(BrTgt);
|
||||
MIRBuilder.buildBr(TgtBB);
|
||||
|
||||
// Link successors.
|
||||
MachineBasicBlock &CurBB = MIRBuilder.getMBB();
|
||||
for (const BasicBlock *Succ : BrInst.successors())
|
||||
CurBB.addSuccessor(&getOrCreateBB(*Succ));
|
||||
CurBB.addSuccessor(&getMBB(*Succ));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -256,7 +250,7 @@ bool IRTranslator::translateSwitch(const User &U,
|
|||
MIRBuilder.buildICmp(CmpInst::ICMP_EQ, Tst, CaseValueReg, SwCondValue);
|
||||
MachineBasicBlock &CurMBB = MIRBuilder.getMBB();
|
||||
const BasicBlock *TrueBB = CaseIt.getCaseSuccessor();
|
||||
MachineBasicBlock &TrueMBB = getOrCreateBB(*TrueBB);
|
||||
MachineBasicBlock &TrueMBB = getMBB(*TrueBB);
|
||||
|
||||
MIRBuilder.buildBrCond(Tst, TrueMBB);
|
||||
CurMBB.addSuccessor(&TrueMBB);
|
||||
|
@ -272,7 +266,7 @@ bool IRTranslator::translateSwitch(const User &U,
|
|||
}
|
||||
// handle default case
|
||||
const BasicBlock *DefaultBB = SwInst.getDefaultDest();
|
||||
MachineBasicBlock &DefaultMBB = getOrCreateBB(*DefaultBB);
|
||||
MachineBasicBlock &DefaultMBB = getMBB(*DefaultBB);
|
||||
MIRBuilder.buildBr(DefaultMBB);
|
||||
MachineBasicBlock &CurMBB = MIRBuilder.getMBB();
|
||||
CurMBB.addSuccessor(&DefaultMBB);
|
||||
|
@ -291,7 +285,7 @@ bool IRTranslator::translateIndirectBr(const User &U,
|
|||
// Link successors.
|
||||
MachineBasicBlock &CurBB = MIRBuilder.getMBB();
|
||||
for (const BasicBlock *Succ : BrInst.successors())
|
||||
CurBB.addSuccessor(&getOrCreateBB(*Succ));
|
||||
CurBB.addSuccessor(&getMBB(*Succ));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -823,8 +817,8 @@ bool IRTranslator::translateInvoke(const User &U,
|
|||
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
|
||||
|
||||
// FIXME: track probabilities.
|
||||
MachineBasicBlock &EHPadMBB = getOrCreateBB(*EHPadBB),
|
||||
&ReturnMBB = getOrCreateBB(*ReturnBB);
|
||||
MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
|
||||
&ReturnMBB = getMBB(*ReturnBB);
|
||||
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
|
||||
MIRBuilder.getMBB().addSuccessor(&ReturnMBB);
|
||||
MIRBuilder.getMBB().addSuccessor(&EHPadMBB);
|
||||
|
@ -1128,13 +1122,25 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
|
|||
// Release the per-function state when we return, whether we succeeded or not.
|
||||
auto FinalizeOnReturn = make_scope_exit([this]() { finalizeFunction(); });
|
||||
|
||||
// Setup a separate basic-block for the arguments and constants, falling
|
||||
// through to the IR-level Function's entry block.
|
||||
// Setup a separate basic-block for the arguments and constants
|
||||
MachineBasicBlock *EntryBB = MF->CreateMachineBasicBlock();
|
||||
MF->push_back(EntryBB);
|
||||
EntryBB->addSuccessor(&getOrCreateBB(F.front()));
|
||||
EntryBuilder.setMBB(*EntryBB);
|
||||
|
||||
// Create all blocks, in IR order, to preserve the layout.
|
||||
for (const BasicBlock &BB: F) {
|
||||
auto *&MBB = BBToMBB[&BB];
|
||||
|
||||
MBB = MF->CreateMachineBasicBlock(&BB);
|
||||
MF->push_back(MBB);
|
||||
|
||||
if (BB.hasAddressTaken())
|
||||
MBB->setHasAddressTaken();
|
||||
}
|
||||
|
||||
// Make our arguments/constants entry block fallthrough to the IR entry block.
|
||||
EntryBB->addSuccessor(&getMBB(F.front()));
|
||||
|
||||
// Lower the actual args into this basic block.
|
||||
SmallVector<unsigned, 8> VRegArgs;
|
||||
for (const Argument &Arg: F.args())
|
||||
|
@ -1150,7 +1156,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
|
|||
|
||||
// And translate the function!
|
||||
for (const BasicBlock &BB: F) {
|
||||
MachineBasicBlock &MBB = getOrCreateBB(BB);
|
||||
MachineBasicBlock &MBB = getMBB(BB);
|
||||
// Set the insertion point of all the following translations to
|
||||
// the end of this basic block.
|
||||
CurBuilder.setMBB(MBB);
|
||||
|
|
|
@ -117,33 +117,35 @@ false:
|
|||
; CHECK: G_BRCOND %[[regicmp100]](s1), %[[BB_CASE100]]
|
||||
; CHECK: G_BR %[[BB_NOTCASE100_CHECKNEXT]]
|
||||
;
|
||||
; CHECK: [[BB_DEFAULT:bb.[0-9]+.default]]:
|
||||
; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+.return]](0x80000000)
|
||||
; CHECK: %[[regretdefault:[0-9]+]](s32) = G_ADD %0, %[[reg0]]
|
||||
; CHECK: G_BR %[[BB_RET]]
|
||||
;
|
||||
; CHECK: [[BB_CASE100]]:
|
||||
; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+.return]](0x80000000)
|
||||
; CHECK: %[[regretc100:[0-9]+]](s32) = G_ADD %0, %[[reg1]]
|
||||
; CHECK: G_BR %[[BB_RET]]
|
||||
; CHECK: [[BB_NOTCASE100_CHECKNEXT]]:
|
||||
; CHECK-NEXT: successors: %[[BB_CASE200:bb.[0-9]+.case200]](0x40000000), %[[BB_NOTCASE200_CHECKNEXT:bb.[0-9]+.entry]](0x40000000)
|
||||
; CHECK: %[[regicmp200:[0-9]+]](s1) = G_ICMP intpred(eq), %[[reg200]](s32), %0
|
||||
; CHECK: G_BRCOND %[[regicmp200]](s1), %[[BB_CASE200]]
|
||||
; CHECK: G_BR %[[BB_NOTCASE200_CHECKNEXT]]
|
||||
;
|
||||
; CHECK: [[BB_CASE200]]:
|
||||
; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+.return]](0x80000000)
|
||||
; CHECK: %[[regretc200:[0-9]+]](s32) = G_ADD %0, %[[reg2]]
|
||||
; CHECK: G_BR %[[BB_RET]]
|
||||
; CHECK: [[BB_NOTCASE200_CHECKNEXT]]:
|
||||
; CHECK-NEXT: successors: %[[BB_DEFAULT:bb.[0-9]+.default]](0x80000000)
|
||||
; CHECK: G_BR %[[BB_DEFAULT]]
|
||||
;
|
||||
; CHECK: [[BB_DEFAULT]]:
|
||||
; CHECK: [[BB_CASE200:bb.[0-9]+.case200]]:
|
||||
; CHECK-NEXT: successors: %[[BB_RET]](0x80000000)
|
||||
; CHECK: %[[regretdefault:[0-9]+]](s32) = G_ADD %0, %[[reg0]]
|
||||
; CHECK: %[[regretc200:[0-9]+]](s32) = G_ADD %0, %[[reg2]]
|
||||
; CHECK: G_BR %[[BB_RET]]
|
||||
;
|
||||
; CHECK: [[BB_RET]]:
|
||||
; CHECK-NEXT: %[[regret:[0-9]+]](s32) = PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
|
||||
; CHECK: %w0 = COPY %[[regret]](s32)
|
||||
; CHECK: RET_ReallyLR implicit %w0
|
||||
;
|
||||
; CHECK: [[BB_NOTCASE100_CHECKNEXT]]:
|
||||
; CHECK-NEXT: successors: %[[BB_CASE200]](0x40000000), %[[BB_NOTCASE200_CHECKNEXT:bb.[0-9]+.entry]](0x40000000)
|
||||
; CHECK: %[[regicmp200:[0-9]+]](s1) = G_ICMP intpred(eq), %[[reg200]](s32), %0
|
||||
; CHECK: G_BRCOND %[[regicmp200]](s1), %[[BB_CASE200]]
|
||||
; CHECK: G_BR %[[BB_NOTCASE200_CHECKNEXT]]
|
||||
;
|
||||
; CHECK: [[BB_NOTCASE200_CHECKNEXT]]:
|
||||
; CHECK-NEXT: successors: %[[BB_DEFAULT]](0x80000000)
|
||||
; CHECK: G_BR %[[BB_DEFAULT]]
|
||||
define i32 @switch(i32 %argc) {
|
||||
entry:
|
||||
switch i32 %argc, label %default [
|
||||
|
@ -172,13 +174,12 @@ return:
|
|||
; %entry block is no longer a predecessor for the phi instruction. We need to
|
||||
; use the correct lowered MachineBasicBlock instead.
|
||||
; CHECK-LABEL: name: test_cfg_remap
|
||||
; CHECK: [[PHI_BLOCK:bb.[0-9]+.phi.block]]:
|
||||
; CHECK-NEXT: PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+.entry]], %{{.*}}(s32),
|
||||
|
||||
; CHECK: bb.5.entry:
|
||||
; CHECK-NEXT: successors: %[[PHI_BLOCK:bb.[0-9]+.phi.block]]
|
||||
; CHECK: [[NOTCASE57_BLOCK]]:
|
||||
; CHECK-NEXT: successors: %[[PHI_BLOCK]]
|
||||
; CHECK: G_BR %[[PHI_BLOCK]]
|
||||
|
||||
; CHECK: [[PHI_BLOCK]]:
|
||||
; CHECK-NEXT: PHI %{{.*}}(s32), %bb.5.entry
|
||||
define i32 @test_cfg_remap(i32 %in) {
|
||||
entry:
|
||||
switch i32 %in, label %phi.block [i32 1, label %next
|
||||
|
@ -378,11 +379,11 @@ define i64* @trivial_bitcast(i8* %a) {
|
|||
; CHECK: [[A:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: G_BR %[[CAST:bb\.[0-9]+.cast]]
|
||||
|
||||
; CHECK: [[END:bb\.[0-9]+.end]]:
|
||||
|
||||
; CHECK: [[CAST]]:
|
||||
; CHECK: {{%[0-9]+}}(p0) = COPY [[A]]
|
||||
; CHECK: G_BR %[[END:bb\.[0-9]+.end]]
|
||||
|
||||
; CHECK: [[END]]:
|
||||
; CHECK: G_BR %[[END]]
|
||||
define i64* @trivial_bitcast_with_copy(i8* %a) {
|
||||
br label %cast
|
||||
|
||||
|
|
Loading…
Reference in New Issue