diff options
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
-rw-r--r-- | lib/CodeGen/MachineLICM.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index bb0d832172..8123d99680 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -43,6 +43,7 @@ namespace { class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { const TargetMachine *TM; const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; // Various analyses that we use... MachineLoopInfo *LI; // Current MachineLoopInfo @@ -135,6 +136,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { Changed = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); + TRI = TM->getRegisterInfo(); RegInfo = &MF.getRegInfo(); // Get our Loop information... @@ -254,8 +256,25 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { if (Reg == 0) continue; // Don't hoist an instruction that uses or defines a physical register. - if (TargetRegisterInfo::isPhysicalRegister(Reg)) - return false; + 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()) { + // 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; + // Otherwise it's safe to move. + continue; + } else if (!MO.isDead()) { + // A def that isn't dead. We can't move it. + return false; + } + } if (!MO.isUse()) continue; |