summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-25 22:53:29 +0000
committerDan Gohman <gohman@apple.com>2009-09-25 22:53:29 +0000
commit19778e7558bc161b87920c5be9cc01bb84a08de2 (patch)
treeaba6cd78207de15e1d2e27d56f3cc900f420e2af /lib/CodeGen/MachineSink.cpp
parentd1c37f5b2099233dc337f8b652de70d36e8f3b2c (diff)
downloadllvm-19778e7558bc161b87920c5be9cc01bb84a08de2.tar.gz
llvm-19778e7558bc161b87920c5be9cc01bb84a08de2.tar.bz2
llvm-19778e7558bc161b87920c5be9cc01bb84a08de2.tar.xz
Fix MachineSink to be able to sink instructions that use physical registers
which have no defs anywhere in the function. In particular, this fixes sinking of instructions that reference RIP on x86-64, which is currently being modeled as a register. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82815 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
-rw-r--r--lib/CodeGen/MachineSink.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index f975ad344a..5f555b2f63 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -35,6 +35,7 @@ namespace {
class VISIBILITY_HIDDEN MachineSinking : public MachineFunctionPass {
const TargetMachine *TM;
const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
MachineFunction *CurMF; // Current MachineFunction
MachineRegisterInfo *RegInfo; // Machine register information
MachineDominatorTree *DT; // Machine dominator tree
@@ -95,6 +96,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
CurMF = &MF;
TM = &CurMF->getTarget();
TII = TM->getInstrInfo();
+ TRI = TM->getRegisterInfo();
RegInfo = &CurMF->getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
@@ -176,8 +178,19 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
// If this is a physical register use, we can't move it. If it is a def,
// we can move it, but only if the def is dead.
- if (MO.isUse() || !MO.isDead())
+ if (MO.isUse()) {
+ // If the physreg has no defs anywhere, it's just an ambient register
+ // and we can freely move its uses.
+ if (!RegInfo->def_empty(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))
+ return false;
+ } else if (!MO.isDead()) {
+ // A def that isn't dead. We can't move it.
return false;
+ }
} else {
// Virtual register uses are always safe to sink.
if (MO.isUse()) continue;