refactor all the constantexpr/instruction handling code out into a

new FindMaximalLegalAddressingModeForOperation helper method.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60011 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2008-11-25 05:15:49 +00:00
parent 7ad1c7342b
commit bb3204a440

View File

@ -573,61 +573,22 @@ static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale,
return true; return true;
} }
/// FindMaximalLegalAddressingMode - If we can, try to merge the computation of
/// Addr into the specified addressing mode. If Addr can't be added to AddrMode
/// this returns false. This assumes that Addr is either a pointer type or
/// intptr_t for the target.
///
/// This method is used to optimize both load/store and inline asms with memory
/// operands.
static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
ExtAddrMode &AddrMode, ExtAddrMode &AddrMode,
SmallVectorImpl<Instruction*> &AMI,
const TargetLowering &TLI,
unsigned Depth);
/// FindMaximalLegalAddressingModeForOperation - Given an instruction or
/// constant expr, see if we can fold the operation into the addressing mode.
/// If so, update the addressing mode and return true, otherwise return false.
static bool
FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
const Type *AccessTy,
ExtAddrMode &AddrMode,
SmallVectorImpl<Instruction*> &AddrModeInsts, SmallVectorImpl<Instruction*> &AddrModeInsts,
const TargetLowering &TLI, const TargetLowering &TLI,
unsigned Depth) { unsigned Depth) {
// If this is a global variable, fold it into the addressing mode if possible.
if (GlobalValue *GV = dyn_cast<GlobalValue>(Addr)) {
if (AddrMode.BaseGV == 0) {
AddrMode.BaseGV = GV;
if (TLI.isLegalAddressingMode(AddrMode, AccessTy))
return true;
AddrMode.BaseGV = 0;
}
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(Addr)) {
AddrMode.BaseOffs += CI->getSExtValue();
if (TLI.isLegalAddressingMode(AddrMode, AccessTy))
return true;
AddrMode.BaseOffs -= CI->getSExtValue();
} else if (isa<ConstantPointerNull>(Addr)) {
return true;
}
// Look through constant exprs and instructions.
unsigned Opcode = ~0U;
User *AddrInst = 0;
if (Instruction *I = dyn_cast<Instruction>(Addr)) {
Opcode = I->getOpcode();
AddrInst = I;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr)) {
Opcode = CE->getOpcode();
AddrInst = CE;
}
// Limit recursion to avoid exponential behavior.
if (Depth == 5) { AddrInst = 0; Opcode = ~0U; }
// If this is really an instruction, add it to our list of related
// instructions.
if (Instruction *I = dyn_cast_or_null<Instruction>(AddrInst))
AddrModeInsts.push_back(I);
#if 0
if (AddrInst && !AddrInst->hasOneUse())
;
else
#endif
switch (Opcode) { switch (Opcode) {
case Instruction::PtrToInt: case Instruction::PtrToInt:
// PtrToInt is always a noop, as we know that the int type is pointer sized. // PtrToInt is always a noop, as we know that the int type is pointer sized.
@ -783,11 +744,53 @@ static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
break; break;
} }
} }
return false;
}
if (Instruction *I = dyn_cast_or_null<Instruction>(AddrInst)) { /// FindMaximalLegalAddressingMode - If we can, try to merge the computation of
assert(AddrModeInsts.back() == I && "Stack imbalance"); I = I; /// Addr into the specified addressing mode. If Addr can't be added to AddrMode
AddrModeInsts.pop_back(); /// this returns false. This assumes that Addr is either a pointer type or
/// intptr_t for the target.
///
/// This method is used to optimize both load/store and inline asms with memory
/// operands.
static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
ExtAddrMode &AddrMode,
SmallVectorImpl<Instruction*> &AddrModeInsts,
const TargetLowering &TLI,
unsigned Depth) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Addr)) {
// Fold in immediates if legal for the target.
AddrMode.BaseOffs += CI->getSExtValue();
if (TLI.isLegalAddressingMode(AddrMode, AccessTy))
return true;
AddrMode.BaseOffs -= CI->getSExtValue();
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(Addr)) {
// If this is a global variable, fold it into the addressing mode if possible.
if (AddrMode.BaseGV == 0) {
AddrMode.BaseGV = GV;
if (TLI.isLegalAddressingMode(AddrMode, AccessTy))
return true;
AddrMode.BaseGV = 0;
} }
} else if (Instruction *I = dyn_cast<Instruction>(Addr)) {
if (Depth < 5 && // Limit recursion to avoid exponential behavior.
FindMaximalLegalAddressingModeForOperation(I, I->getOpcode(),
AccessTy, AddrMode,
AddrModeInsts, TLI, Depth)) {
AddrModeInsts.push_back(I);
return true;
}
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr)) {
if (Depth < 5 && // Limit recursion to avoid exponential behavior.
FindMaximalLegalAddressingModeForOperation(CE, CE->getOpcode(),
AccessTy, AddrMode,
AddrModeInsts, TLI, Depth))
return true;
} else if (isa<ConstantPointerNull>(Addr)) {
return true;
}
// Worse case, the target should support [reg] addressing modes. :) // Worse case, the target should support [reg] addressing modes. :)
if (!AddrMode.HasBaseReg) { if (!AddrMode.HasBaseReg) {