aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-26 02:34:00 +0000
committerDan Gohman <gohman@apple.com>2009-09-26 02:34:00 +0000
commit45094e34bcbb133aa0bbe55710e25369df0e02ed (patch)
tree02c3bbb0b3a6c27fd49d3d5277a04a6b2cc2a928
parent22cb6579b3ab33610f166b264833fa945e8e2ade (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82834 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/MachineLICM.cpp15
-rw-r--r--lib/CodeGen/MachineSink.cpp15
2 files changed, 24 insertions, 6 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index 8123d99680..61678f1d7c 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -44,6 +44,7 @@ namespace {
const TargetMachine *TM;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
+ BitVector AllocatableSet;
// Various analyses that we use...
MachineLoopInfo *LI; // Current MachineLoopInfo
@@ -138,6 +139,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
TII = TM->getInstrInfo();
TRI = TM->getRegisterInfo();
RegInfo = &MF.getRegInfo();
+ AllocatableSet = TRI->getAllocatableSet(MF);
// Get our Loop information...
LI = &getAnalysis<MachineLoopInfo>();
@@ -261,13 +263,20 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
// we can move it, but only if the def is dead.
if (MO.isUse()) {
// 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))
return false;
+ if (AllocatableSet.test(Reg))
+ return false;
// Check for a def among the register's aliases too.
- for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
- if (!RegInfo->def_empty(*Alias))
+ for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
+ unsigned AliasReg = *Alias;
+ if (!RegInfo->def_empty(AliasReg))
+ return false;
+ if (AllocatableSet.test(AliasReg))
return false;
+ }
// Otherwise it's safe to move.
continue;
} else if (!MO.isDead()) {
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index 5f555b2f63..636dad8ffb 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -39,6 +39,7 @@ namespace {
MachineFunction *CurMF; // Current MachineFunction
MachineRegisterInfo *RegInfo; // Machine register information
MachineDominatorTree *DT; // Machine dominator tree
+ BitVector AllocatableSet; // Which physregs are allocatable?
public:
static char ID; // Pass identification
@@ -99,6 +100,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
TRI = TM->getRegisterInfo();
RegInfo = &CurMF->getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
+ AllocatableSet = TRI->getAllocatableSet(*CurMF);
bool EverMadeChange = false;
@@ -180,13 +182,20 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// we can move it, but only if the def is dead.
if (MO.isUse()) {
// 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))
return false;
+ if (AllocatableSet.test(Reg))
+ return false;
// Check for a def among the register's aliases too.
- for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
- if (!RegInfo->def_empty(*Alias))
+ for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
+ unsigned AliasReg = *Alias;
+ if (!RegInfo->def_empty(AliasReg))
+ return false;
+ if (AllocatableSet.test(AliasReg))
return false;
+ }
} else if (!MO.isDead()) {
// A def that isn't dead. We can't move it.
return false;