aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineSink.cpp
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 /lib/CodeGen/MachineSink.cpp
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
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
-rw-r--r--lib/CodeGen/MachineSink.cpp15
1 files changed, 12 insertions, 3 deletions
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;