From c101e95cb6aae1fd6a0727ba4b518a7894ae3089 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 14 Jun 2007 20:50:44 +0000 Subject: [PATCH] Add a target hook to allow loads from constant pools to be rematerialized, and an implementation for x86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37576 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetInstrInfo.h | 10 ++++++++++ lib/CodeGen/LiveIntervalAnalysis.cpp | 6 ++++-- lib/CodeGen/VirtRegMap.cpp | 3 ++- lib/Target/X86/X86InstrInfo.cpp | 25 +++++++++++++++++++++++++ lib/Target/X86/X86InstrInfo.h | 1 + 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 2571db4e01a..e221466606b 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 eadd47b009b..aae27bb882d 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 9ae38ac9013..95453b0e3d5 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 57282d471fc..f06827522c3 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 7f5a16b3e0d..3d3952a6ee3 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