1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[globalisel][combine] When placing truncates, handle the case when the BB is empty

GlobalISel uses MIR with implicit fallthrough on each basic block. As a result,
getFirstNonPhi() can return end().

llvm-svn: 343829
This commit is contained in:
Daniel Sanders 2018-10-04 23:47:37 +00:00
parent 6dff1dbb58
commit 9be5c566f7
2 changed files with 87 additions and 15 deletions

View File

@ -110,7 +110,8 @@ PreferredTuple ChoosePreferredUse(PreferredTuple &CurrentUse,
/// want to try harder to find a dominating block.
static void InsertInsnsWithoutSideEffectsBeforeUse(
MachineIRBuilder &Builder, MachineInstr &DefMI, MachineOperand &UseMO,
std::function<void(MachineBasicBlock::iterator)> Inserter) {
std::function<void(MachineBasicBlock *, MachineBasicBlock::iterator)>
Inserter) {
MachineInstr &UseMI = *UseMO.getParent();
MachineBasicBlock *InsertBB = UseMI.getParent();
@ -125,16 +126,26 @@ static void InsertInsnsWithoutSideEffectsBeforeUse(
// the def instead of at the start of the block.
if (InsertBB == DefMI.getParent()) {
MachineBasicBlock::iterator InsertPt = &DefMI;
Inserter(std::next(InsertPt));
Inserter(InsertBB, std::next(InsertPt));
return;
}
// Otherwise we want the start of the BB
Inserter(InsertBB->getFirstNonPHI());
Inserter(InsertBB, InsertBB->getFirstNonPHI());
}
} // end anonymous namespace
bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
struct InsertionPoint {
MachineOperand *UseMO;
MachineBasicBlock *InsertIntoBB;
MachineBasicBlock::iterator InsertBefore;
InsertionPoint(MachineOperand *UseMO, MachineBasicBlock *InsertIntoBB,
MachineBasicBlock::iterator InsertBefore)
: UseMO(UseMO), InsertIntoBB(InsertIntoBB), InsertBefore(InsertBefore) {
}
};
// We match the loads and follow the uses to the extend instead of matching
// the extends and following the def to the load. This is because the load
// must remain in the same position for correctness (unless we also add code
@ -193,7 +204,7 @@ bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
// Rewrite all the uses to fix up the types.
SmallVector<MachineInstr *, 1> ScheduleForErase;
SmallVector<std::pair<MachineOperand *, MachineInstr *>, 4> ScheduleForInsert;
SmallVector<InsertionPoint, 4> ScheduleForInsert;
for (auto &UseMO : MRI.use_operands(LoadValue.getReg())) {
MachineInstr *UseMI = UseMO.getParent();
@ -243,8 +254,9 @@ bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
// ... = ... %3(s64)
InsertInsnsWithoutSideEffectsBeforeUse(
Builder, MI, UseMO,
[&](MachineBasicBlock::iterator InsertBefore) {
ScheduleForInsert.emplace_back(&UseMO, &*InsertBefore);
[&](MachineBasicBlock *InsertIntoBB,
MachineBasicBlock::iterator InsertBefore) {
ScheduleForInsert.emplace_back(&UseMO, InsertIntoBB, InsertBefore);
});
}
continue;
@ -259,27 +271,29 @@ bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
// The use isn't an extend. Truncate back to the type we originally loaded.
// This is free on many targets.
InsertInsnsWithoutSideEffectsBeforeUse(
Builder, MI, UseMO, [&](MachineBasicBlock::iterator InsertBefore) {
ScheduleForInsert.emplace_back(&UseMO, &*InsertBefore);
Builder, MI, UseMO,
[&](MachineBasicBlock *InsertIntoBB,
MachineBasicBlock::iterator InsertBefore) {
ScheduleForInsert.emplace_back(&UseMO, InsertIntoBB, InsertBefore);
});
}
DenseMap<MachineBasicBlock *, MachineInstr *> EmittedInsns;
for (auto &InsertionInfo : ScheduleForInsert) {
MachineOperand *UseMO = InsertionInfo.first;
MachineInstr *InsertBefore = InsertionInfo.second;
MachineOperand *UseMO = InsertionInfo.UseMO;
MachineBasicBlock *InsertIntoBB = InsertionInfo.InsertIntoBB;
MachineBasicBlock::iterator InsertBefore = InsertionInfo.InsertBefore;
MachineInstr *PreviouslyEmitted =
EmittedInsns.lookup(InsertBefore->getParent());
MachineInstr *PreviouslyEmitted = EmittedInsns.lookup(InsertIntoBB);
if (PreviouslyEmitted) {
UseMO->setReg(PreviouslyEmitted->getOperand(0).getReg());
continue;
}
Builder.setInsertPt(*InsertBefore->getParent(), InsertBefore);
Builder.setInsertPt(*InsertIntoBB, InsertBefore);
unsigned NewDstReg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
MachineInstr *NewMI = Builder.buildTrunc(NewDstReg, ChosenDstReg);
EmittedInsns[InsertBefore->getParent()] = NewMI;
EmittedInsns[InsertIntoBB] = NewMI;
UseMO->setReg(NewDstReg);
Observer.createdInstr(*NewMI);
}

View File

@ -35,6 +35,19 @@
ret void
}
define void @sink_to_phi_emptyblock(i8* %addr) {
entry:
br i1 0, label %if, label %else
if:
br label %exit
else:
br label %else2
else2:
br label %exit
exit:
ret void
}
define void @use_doesnt_def_anything(i8* %addr) {
entry:
ret void
@ -44,7 +57,6 @@
entry:
ret void
}
...
---
@ -178,6 +190,52 @@ body: |
$w1 = COPY %9
...
---
name: sink_to_phi_emptyblock
# CHECK-LABEL: name: sink_to_phi_emptyblock
tracksRegLiveness: true
body: |
bb.0.entry:
liveins: $x0, $w1
successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%)
; CHECK: [[T0:%[0-9]+]]:_(s32) = G_SEXTLOAD
%0:_(p0) = COPY $x0
%1:_(s32) = COPY $w1
%2:_(s8) = G_LOAD %0 :: (load 1 from %ir.addr)
%3:_(s32) = G_SEXT %2
%4:_(s32) = G_CONSTANT i32 1
%5:_(s1) = G_ICMP intpred(ne), %1:_(s32), %4:_
G_BRCOND %5:_(s1), %bb.1
G_BR %bb.2.else
bb.1.if:
; CHECK: bb.1.if:
successors: %bb.4(0x80000000)
%10:_(s8) = G_CONSTANT i8 1
; CHECK: [[T1:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32)
%6:_(s8) = G_ADD %2, %10
; CHECK: [[T2:%[0-9]+]]:_(s8) = G_ADD [[T1]], {{.*}}
G_BR %bb.4.exit
bb.2.else:
; CHECK: bb.2.else:
successors: %bb.3(0x80000000)
G_BR %bb.3.else2
bb.3.else2:
; CHECK: bb.3.else2:
successors: %bb.4(0x80000000)
; CHECK: [[T4:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32)
; Fallthrough
bb.4.exit:
; CHECK: bb.4.exit:
%8:_(s8) = G_PHI %6:_(s8), %bb.1, %2:_(s8), %bb.3
; CHECK: [[T5:%[0-9]+]]:_(s8) = G_PHI [[T2]](s8), %bb.1, [[T4]](s8)
%9:_(s32) = G_ZEXT %8
; CHECK: [[T6:%[0-9]+]]:_(s32) = G_ZEXT [[T5]](s8)
; CHECK: $w0 = COPY [[T0]](s32)
; CHECK: $w1 = COPY [[T6]](s32)
$w0 = COPY %3
$w1 = COPY %9
...
---
name: use_doesnt_def_anything
# CHECK-LABEL: name: use_doesnt_def_anything