aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetInstrInfo.h10
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp6
-rw-r--r--lib/CodeGen/VirtRegMap.cpp3
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp25
-rw-r--r--lib/Target/X86/X86InstrInfo.h1
5 files changed, 42 insertions, 3 deletions
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 2571db4e01..e221466606 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -298,6 +298,16 @@ public:
return 0;
}
+ /// isOtherReMaterializableLoad - If the specified machine instruction is a
+ /// direct load that is trivially rematerializable, not counting loads from
+ /// stack slots, return true. If not, return false. This predicate must
+ /// return false if the instruction has any side effects other than
+ /// producing the value from the load, or if it requres any address
+ /// registers that are not always available.
+ virtual bool isOtherReMaterializableLoad(MachineInstr *MI) const {
+ return false;
+ }
+
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
/// may be able to convert a two-address instruction into one or moretrue
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index eadd47b009..aae27bb882 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -336,12 +336,14 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// time we see a vreg.
if (interval.empty()) {
// Remember if the definition can be rematerialized. All load's from fixed
- // stack slots are re-materializable.
+ // stack slots are re-materializable. The target may permit other loads to
+ // be re-materialized as well.
int FrameIdx = 0;
if (vi.DefInst &&
(tii_->isReMaterializable(vi.DefInst->getOpcode()) ||
(tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) &&
- mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx))))
+ mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)) ||
+ tii_->isOtherReMaterializableLoad(vi.DefInst)))
interval.remat = vi.DefInst;
// Get the Idx of the defining instructions.
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index 9ae38ac901..95453b0e3d 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -664,7 +664,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// If this instruction is being rematerialized, just remove it!
int FrameIdx;
if ((TID->Flags & M_REMATERIALIZIBLE) ||
- TII->isLoadFromStackSlot(&MI, FrameIdx)) {
+ TII->isLoadFromStackSlot(&MI, FrameIdx) ||
+ TII->isOtherReMaterializableLoad(&MI)) {
bool Remove = true;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 57282d471f..f06827522c 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -112,6 +112,31 @@ unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI,
}
+bool X86InstrInfo::isOtherReMaterializableLoad(MachineInstr *MI) const {
+ switch (MI->getOpcode()) {
+ default: break;
+ case X86::MOV8rm:
+ case X86::MOV16rm:
+ case X86::MOV16_rm:
+ case X86::MOV32rm:
+ case X86::MOV32_rm:
+ case X86::MOV64rm:
+ case X86::FpLD64m:
+ case X86::MOVSSrm:
+ case X86::MOVSDrm:
+ case X86::MOVAPSrm:
+ case X86::MOVAPDrm:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ return MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate() &&
+ MI->getOperand(3).isRegister() && MI->getOperand(4).isConstantPoolIndex() &&
+ MI->getOperand(1).getReg() == 0 &&
+ MI->getOperand(2).getImmedValue() == 1 &&
+ MI->getOperand(3).getReg() == 0;
+ }
+ return false;
+}
+
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
/// may be able to convert a two-address instruction into a true
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 7f5a16b3e0..3d3952a6ee 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -239,6 +239,7 @@ public:
unsigned& destReg) const;
unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
+ bool isOtherReMaterializableLoad(MachineInstr *MI) const;
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target