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
// 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.
// 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);
}
+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
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