Skip to content
Snippets Groups Projects
Commit 2f5bdcb7 authored by Dan Gohman's avatar Dan Gohman
Browse files

Don't hoist or sink instructions with physreg uses if the physreg is

allocatable. Even if it doesn't appear to have any defs, it may latter
on after register allocation.

llvm-svn: 82834
parent bdaaab46
No related branches found
No related tags found
No related merge requests found
...@@ -44,6 +44,7 @@ namespace { ...@@ -44,6 +44,7 @@ namespace {
const TargetMachine *TM; const TargetMachine *TM;
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI; const TargetRegisterInfo *TRI;
BitVector AllocatableSet;
// Various analyses that we use... // Various analyses that we use...
MachineLoopInfo *LI; // Current MachineLoopInfo MachineLoopInfo *LI; // Current MachineLoopInfo
...@@ -138,6 +139,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { ...@@ -138,6 +139,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
TII = TM->getInstrInfo(); TII = TM->getInstrInfo();
TRI = TM->getRegisterInfo(); TRI = TM->getRegisterInfo();
RegInfo = &MF.getRegInfo(); RegInfo = &MF.getRegInfo();
AllocatableSet = TRI->getAllocatableSet(MF);
// Get our Loop information... // Get our Loop information...
LI = &getAnalysis<MachineLoopInfo>(); LI = &getAnalysis<MachineLoopInfo>();
...@@ -261,13 +263,20 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { ...@@ -261,13 +263,20 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
// we can move it, but only if the def is dead. // we can move it, but only if the def is dead.
if (MO.isUse()) { if (MO.isUse()) {
// If the physreg has no defs anywhere, it's just an ambient register // If the physreg has no defs anywhere, it's just an ambient register
// and we can freely move its uses. // and we can freely move its uses. Alternatively, if it's allocatable,
// it could get allocated to something with a def during allocation.
if (!RegInfo->def_empty(Reg)) if (!RegInfo->def_empty(Reg))
return false; return false;
if (AllocatableSet.test(Reg))
return false;
// Check for a def among the register's aliases too. // Check for a def among the register's aliases too.
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
if (!RegInfo->def_empty(*Alias)) unsigned AliasReg = *Alias;
if (!RegInfo->def_empty(AliasReg))
return false;
if (AllocatableSet.test(AliasReg))
return false; return false;
}
// Otherwise it's safe to move. // Otherwise it's safe to move.
continue; continue;
} else if (!MO.isDead()) { } else if (!MO.isDead()) {
......
...@@ -39,6 +39,7 @@ namespace { ...@@ -39,6 +39,7 @@ namespace {
MachineFunction *CurMF; // Current MachineFunction MachineFunction *CurMF; // Current MachineFunction
MachineRegisterInfo *RegInfo; // Machine register information MachineRegisterInfo *RegInfo; // Machine register information
MachineDominatorTree *DT; // Machine dominator tree MachineDominatorTree *DT; // Machine dominator tree
BitVector AllocatableSet; // Which physregs are allocatable?
public: public:
static char ID; // Pass identification static char ID; // Pass identification
...@@ -99,6 +100,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) { ...@@ -99,6 +100,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
TRI = TM->getRegisterInfo(); TRI = TM->getRegisterInfo();
RegInfo = &CurMF->getRegInfo(); RegInfo = &CurMF->getRegInfo();
DT = &getAnalysis<MachineDominatorTree>(); DT = &getAnalysis<MachineDominatorTree>();
AllocatableSet = TRI->getAllocatableSet(*CurMF);
bool EverMadeChange = false; bool EverMadeChange = false;
...@@ -180,13 +182,20 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { ...@@ -180,13 +182,20 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// we can move it, but only if the def is dead. // we can move it, but only if the def is dead.
if (MO.isUse()) { if (MO.isUse()) {
// If the physreg has no defs anywhere, it's just an ambient register // If the physreg has no defs anywhere, it's just an ambient register
// and we can freely move its uses. // and we can freely move its uses. Alternatively, if it's allocatable,
// it could get allocated to something with a def during allocation.
if (!RegInfo->def_empty(Reg)) if (!RegInfo->def_empty(Reg))
return false; return false;
if (AllocatableSet.test(Reg))
return false;
// Check for a def among the register's aliases too. // Check for a def among the register's aliases too.
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
if (!RegInfo->def_empty(*Alias)) unsigned AliasReg = *Alias;
if (!RegInfo->def_empty(AliasReg))
return false;
if (AllocatableSet.test(AliasReg))
return false; return false;
}
} else if (!MO.isDead()) { } else if (!MO.isDead()) {
// A def that isn't dead. We can't move it. // A def that isn't dead. We can't move it.
return false; return false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment