mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-10 05:41:40 +00:00
Do not consider a machine instruction that uses and defines the same
physical register as candidate for common subexpression elimination in MachineCSE. This fixes a bug on PowerPC in MultiSource/Applications/oggenc/oggenc caused by MachineCSE invalidly merging two separate DYNALLOC insns. llvm-svn: 167855
This commit is contained in:
parent
f934185b04
commit
9c5e333c90
@ -84,7 +84,8 @@ namespace {
|
||||
bool hasLivePhysRegDefUses(const MachineInstr *MI,
|
||||
const MachineBasicBlock *MBB,
|
||||
SmallSet<unsigned,8> &PhysRefs,
|
||||
SmallVector<unsigned,2> &PhysDefs) const;
|
||||
SmallVector<unsigned,2> &PhysDefs,
|
||||
bool &PhysUseDef) const;
|
||||
bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
|
||||
SmallSet<unsigned,8> &PhysRefs,
|
||||
SmallVector<unsigned,2> &PhysDefs,
|
||||
@ -194,31 +195,52 @@ MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
|
||||
bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
|
||||
const MachineBasicBlock *MBB,
|
||||
SmallSet<unsigned,8> &PhysRefs,
|
||||
SmallVector<unsigned,2> &PhysDefs) const{
|
||||
MachineBasicBlock::const_iterator I = MI; I = llvm::next(I);
|
||||
SmallVector<unsigned,2> &PhysDefs,
|
||||
bool &PhysUseDef) const{
|
||||
// First, add all uses to PhysRefs.
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = MI->getOperand(i);
|
||||
if (!MO.isReg())
|
||||
if (!MO.isReg() || MO.isDef())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
continue;
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
// If the def is dead, it's ok. But the def may not marked "dead". That's
|
||||
// common since this pass is run before livevariables. We can scan
|
||||
// forward a few instructions and check if it is obviously dead.
|
||||
if (MO.isDef() &&
|
||||
(MO.isDead() || isPhysDefTriviallyDead(Reg, I, MBB->end())))
|
||||
continue;
|
||||
// Reading constant physregs is ok.
|
||||
if (!MRI->isConstantPhysReg(Reg, *MBB->getParent()))
|
||||
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
|
||||
PhysRefs.insert(*AI);
|
||||
if (MO.isDef())
|
||||
}
|
||||
|
||||
// Next, collect all defs into PhysDefs. If any is already in PhysRefs
|
||||
// (which currently contains only uses), set the PhysUseDef flag.
|
||||
PhysUseDef = false;
|
||||
MachineBasicBlock::const_iterator I = MI; I = llvm::next(I);
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = MI->getOperand(i);
|
||||
if (!MO.isReg() || !MO.isDef())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
continue;
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
// Check against PhysRefs even if the def is "dead".
|
||||
if (PhysRefs.count(Reg))
|
||||
PhysUseDef = true;
|
||||
// If the def is dead, it's ok. But the def may not marked "dead". That's
|
||||
// common since this pass is run before livevariables. We can scan
|
||||
// forward a few instructions and check if it is obviously dead.
|
||||
if (!MO.isDead() && !isPhysDefTriviallyDead(Reg, I, MBB->end()))
|
||||
PhysDefs.push_back(Reg);
|
||||
}
|
||||
|
||||
// Finally, add all defs to PhysRefs as well.
|
||||
for (unsigned i = 0, e = PhysDefs.size(); i != e; ++i)
|
||||
for (MCRegAliasIterator AI(PhysDefs[i], TRI, true); AI.isValid(); ++AI)
|
||||
PhysRefs.insert(*AI);
|
||||
|
||||
return !PhysRefs.empty();
|
||||
}
|
||||
|
||||
@ -459,16 +481,22 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
|
||||
bool CrossMBBPhysDef = false;
|
||||
SmallSet<unsigned, 8> PhysRefs;
|
||||
SmallVector<unsigned, 2> PhysDefs;
|
||||
if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs, PhysDefs)) {
|
||||
bool PhysUseDef = false;
|
||||
if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
|
||||
PhysDefs, PhysUseDef)) {
|
||||
FoundCSE = false;
|
||||
|
||||
// ... Unless the CS is local or is in the sole predecessor block
|
||||
// and it also defines the physical register which is not clobbered
|
||||
// in between and the physical register uses were not clobbered.
|
||||
unsigned CSVN = VNT.lookup(MI);
|
||||
MachineInstr *CSMI = Exps[CSVN];
|
||||
if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
|
||||
FoundCSE = true;
|
||||
// This can never be the case if the instruction both uses and
|
||||
// defines the same physical register, which was detected above.
|
||||
if (!PhysUseDef) {
|
||||
unsigned CSVN = VNT.lookup(MI);
|
||||
MachineInstr *CSMI = Exps[CSVN];
|
||||
if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
|
||||
FoundCSE = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FoundCSE) {
|
||||
|
18
test/CodeGen/PowerPC/2012-10-11-dynalloc.ll
Normal file
18
test/CodeGen/PowerPC/2012-10-11-dynalloc.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
define void @test(i64 %n) nounwind {
|
||||
entry:
|
||||
%0 = alloca i8, i64 %n, align 1
|
||||
%1 = alloca i8, i64 %n, align 1
|
||||
call void @use(i8* %0, i8* %1) nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @use(i8*, i8*)
|
||||
|
||||
; Check we actually have two instances of dynamic stack allocation,
|
||||
; identified by the stdux used to update the back-chain link.
|
||||
; CHECK: stdux
|
||||
; CHECK: stdux
|
Loading…
Reference in New Issue
Block a user