Any x86 instruction that reads from an invariant location is invariant.

This allows us to sink things like:
	cvtsi2sd	32(%esp), %xmm1
when reading from the argument area, for example.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45895 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-01-12 00:35:08 +00:00
parent aad193a7e9
commit 828bb6c978

View File

@ -758,54 +758,35 @@ bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const {
/// only return true of *all* loads the instruction does are invariant (if it
/// does multiple loads).
bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const {
// FIXME: This should work with any X86 instruction that does a load, for
// example, all load+op instructions.
switch (MI->getOpcode()) {
default: break;
case X86::MOV32rm:
// Loads from stubs of global addresses are invariant.
if (MI->getOperand(1).isReg() &&
MI->getOperand(2).isImm() && MI->getOperand(3).isReg() &&
MI->getOperand(4).isGlobal() &&
TM.getSubtarget<X86Subtarget>().GVRequiresExtraLoad
(MI->getOperand(4).getGlobal(), TM, false) &&
MI->getOperand(2).getImm() == 1 &&
MI->getOperand(3).getReg() == 0)
return true;
// FALLTHROUGH
case X86::MOV8rm:
case X86::MOV16rm:
case X86::MOV16_rm:
case X86::MOV32_rm:
case X86::MOV64rm:
case X86::LD_Fp64m:
case X86::MOVSSrm:
case X86::MOVSDrm:
case X86::MOVAPSrm:
case X86::MOVAPDrm:
case X86::MMX_MOVD64rm:
case X86::MMX_MOVQ64rm:
// This code cares about loads from three cases: constant pool entries,
// invariant argument slots, and global stubs. In order to handle these cases
// for all of the myriad of X86 instructions, we just scan for a CP/FI/GV
// operand and base are analysis on it. This is safe because the address of
// none of these three cases is ever used as anything other than a load base
// and X86 doesn't have any instructions that load from multiple places.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
// Loads from constant pools are trivially invariant.
if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() &&
MI->getOperand(3).isReg() && MI->getOperand(4).isCPI() &&
MI->getOperand(1).getReg() == 0 &&
MI->getOperand(2).getImm() == 1 &&
MI->getOperand(3).getReg() == 0)
if (MO.isCPI())
return true;
// If this is a load from a fixed argument slot, we know the value is
// invariant across the whole function, because we don't redefine argument
// values.
MachineFunction *MF = MI->getParent()->getParent();
if (MI->getOperand(1).isFI()) {
const MachineFrameInfo &MFI = *MF->getFrameInfo();
int Idx = MI->getOperand(1).getIndex();
if (MO.isGlobal()) {
if (TM.getSubtarget<X86Subtarget>().GVRequiresExtraLoad(MO.getGlobal(),
TM, false))
return true;
return false;
}
// If this is a load from an invariant stack slot, the load is a constant.
if (MO.isFI()) {
const MachineFrameInfo &MFI =
*MI->getParent()->getParent()->getFrameInfo();
int Idx = MO.getIndex();
return MFI.isFixedObjectIndex(Idx) && MFI.isImmutableObjectIndex(Idx);
}
return false;
}
// All other instances of these instructions are presumed to have other
// issues.
return false;