summaryrefslogtreecommitdiffstats
path: root/llvm/lib
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
commit2f5bdcb7c254dace9f73ed536b5e61095a917bde (patch)
tree9c8969f9fa8fe8ce2c07cee9a01aa5a0c6c547e3 /llvm/lib
parentbdaaab4671bccb5453837f982e062fb5407d59b4 (diff)
downloadbcm5719-llvm-2f5bdcb7c254dace9f73ed536b5e61095a917bde.tar.gz
bcm5719-llvm-2f5bdcb7c254dace9f73ed536b5e61095a917bde.zip
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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/MachineLICM.cpp15
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp15
2 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index 8123d99680b..61678f1d7c6 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/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/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index 5f555b2f631..636dad8ffb9 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/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;
OpenPOWER on IntegriCloud