forked from OSchip/llvm-project
If we have a load of a global address that's not modified during the
function, then go ahead and hoist it out of the loop. This is the result: $ cat a.c volatile int G; int A(int N) { for (; N > 0; --N) G++; } $ llc -o - -relocation-model=pic _A: ... LBB1_2: # bb movl L_G$non_lazy_ptr-"L1$pb"(%eax), %esi incl (%esi) incl %edx cmpl %ecx, %edx jne LBB1_2 # bb ... $ llc -o - -relocation-model=pic -machine-licm _A: ... movl L_G$non_lazy_ptr-"L1$pb"(%eax), %eax LBB1_2: # bb incl (%eax) incl %edx cmpl %ecx, %edx jne LBB1_2 # bb ... I'm limiting this to the MOV32rm x86 instruction for now. llvm-svn: 45444
This commit is contained in:
parent
330aaa79e0
commit
7749a9014b
|
@ -144,6 +144,37 @@ bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// isDefinedInEntryBlock - Goes through the entry block to see if the given
|
||||
/// virtual register is indeed defined in the entry block.
|
||||
///
|
||||
bool X86InstrInfo::isDefinedInEntryBlock(const MachineBasicBlock &Entry,
|
||||
unsigned VReg) const {
|
||||
assert(MRegisterInfo::isVirtualRegister(VReg) &&
|
||||
"Map only holds virtual registers!");
|
||||
MachineInstrMap.grow(VReg);
|
||||
if (MachineInstrMap[VReg]) return true;
|
||||
|
||||
MachineBasicBlock::const_iterator I = Entry.begin(), E = Entry.end();
|
||||
|
||||
for (; I != E; ++I) {
|
||||
const MachineInstr &MI = *I;
|
||||
unsigned NumOps = MI.getNumOperands();
|
||||
|
||||
for (unsigned i = 0; i < NumOps; ++i) {
|
||||
const MachineOperand &MO = MI.getOperand(i);
|
||||
|
||||
if(MO.isRegister() && MO.isDef() &&
|
||||
MRegisterInfo::isVirtualRegister(MO.getReg()) &&
|
||||
MO.getReg() == VReg) {
|
||||
MachineInstrMap[VReg] = &MI;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
|
||||
/// method is called to determine if the specific instance of this instruction
|
||||
/// has side effects. This is useful in cases of instructions, like loads, which
|
||||
|
@ -152,10 +183,25 @@ bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const {
|
|||
bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case X86::MOV32rm:
|
||||
if (MI->getOperand(1).isRegister()) {
|
||||
unsigned Reg = MI->getOperand(1).getReg();
|
||||
|
||||
// Loads from global addresses which aren't redefined in the function are
|
||||
// side effect free.
|
||||
if (MRegisterInfo::isVirtualRegister(Reg) &&
|
||||
isDefinedInEntryBlock(MI->getParent()->getParent()->front(), Reg) &&
|
||||
MI->getOperand(2).isImmediate() &&
|
||||
MI->getOperand(3).isRegister() &&
|
||||
MI->getOperand(4).isGlobalAddress() &&
|
||||
MI->getOperand(2).getImmedValue() == 1 &&
|
||||
MI->getOperand(3).getReg() == 0)
|
||||
return true;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case X86::MOV8rm:
|
||||
case X86::MOV16rm:
|
||||
case X86::MOV16_rm:
|
||||
case X86::MOV32rm:
|
||||
case X86::MOV32_rm:
|
||||
case X86::MOV64rm:
|
||||
case X86::LD_Fp64m:
|
||||
|
@ -166,8 +212,10 @@ bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const {
|
|||
case X86::MMX_MOVD64rm:
|
||||
case X86::MMX_MOVQ64rm:
|
||||
// Loads from constant pools have no side effects
|
||||
return MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate() &&
|
||||
MI->getOperand(3).isRegister() && MI->getOperand(4).isConstantPoolIndex() &&
|
||||
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;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "X86RegisterInfo.h"
|
||||
#include "llvm/ADT/IndexedMap.h"
|
||||
#include "llvm/Target/MRegisterInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class X86RegisterInfo;
|
||||
|
@ -223,6 +225,13 @@ namespace X86II {
|
|||
class X86InstrInfo : public TargetInstrInfo {
|
||||
X86TargetMachine &TM;
|
||||
const X86RegisterInfo RI;
|
||||
mutable IndexedMap<const MachineInstr*, VirtReg2IndexFunctor> MachineInstrMap;
|
||||
|
||||
/// isDefinedInEntryBlock - Goes through the entry block to see if the given
|
||||
/// virtual register is indeed defined in the entry block.
|
||||
///
|
||||
bool isDefinedInEntryBlock(const MachineBasicBlock &Entry,
|
||||
unsigned VReg) const;
|
||||
public:
|
||||
X86InstrInfo(X86TargetMachine &tm);
|
||||
|
||||
|
|
Loading…
Reference in New Issue