mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-05 09:24:28 +00:00
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:
@ -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) {
|
||||||
|
Reference in New Issue
Block a user