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:
parent
6dff1dbb58
commit
9be5c566f7
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user