mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-28 06:27:16 +00:00
significantly refactor all the addressing mode matching logic
into a new AddressingModeMatcher class. This makes it easier to reason about and reduces passing around of stuff, but has no functionality change. llvm-svn: 60012
This commit is contained in:
parent
9ed8c8eec9
commit
5e0361dd74
@ -53,9 +53,8 @@ namespace {
|
||||
bool CanMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const;
|
||||
void EliminateMostlyEmptyBlock(BasicBlock *BB);
|
||||
bool OptimizeBlock(BasicBlock &BB);
|
||||
bool OptimizeLoadStoreInst(Instruction *I, Value *Addr,
|
||||
const Type *AccessTy,
|
||||
DenseMap<Value*,Value*> &SunkAddrs);
|
||||
bool OptimizeMemoryInst(Instruction *I, Value *Addr, const Type *AccessTy,
|
||||
DenseMap<Value*,Value*> &SunkAddrs);
|
||||
bool OptimizeInlineAsmInst(Instruction *I, CallSite CS,
|
||||
DenseMap<Value*,Value*> &SunkAddrs);
|
||||
bool OptimizeExtUses(Instruction *I);
|
||||
@ -486,6 +485,10 @@ static void EraseDeadInstructions(Value *V) {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Addressing Mode Analysis and Optimization
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// ExtAddrMode - This is an extended version of TargetLowering::AddrMode
|
||||
/// which holds actual Value*'s for register values.
|
||||
@ -506,7 +509,6 @@ static OStream &operator<<(OStream &OS, const ExtAddrMode &AM) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
|
||||
void ExtAddrMode::print(OStream &OS) const {
|
||||
bool NeedPlus = false;
|
||||
OS << "[";
|
||||
@ -527,13 +529,44 @@ void ExtAddrMode::print(OStream &OS) const {
|
||||
OS << ']';
|
||||
}
|
||||
|
||||
/// TryMatchingScaledValue - Try adding ScaleReg*Scale to the specified
|
||||
/// addressing mode. Return true if this addr mode is legal for the target,
|
||||
namespace {
|
||||
/// AddressingModeMatcher - This class exposes a single public method, which is
|
||||
/// used to construct a "maximal munch" of the addressing mode for the target
|
||||
/// specified by TLI for an access to "V" with an access type of AccessTy. This
|
||||
/// returns the addressing mode that is actually matched by value, but also
|
||||
/// returns the list of instructions involved in that addressing computation in
|
||||
/// AddrModeInsts.
|
||||
class AddressingModeMatcher {
|
||||
SmallVectorImpl<Instruction*> &AddrModeInsts;
|
||||
const TargetLowering &TLI;
|
||||
const Type *AccessTy;
|
||||
ExtAddrMode &AddrMode;
|
||||
AddressingModeMatcher(SmallVectorImpl<Instruction*> &AMI,
|
||||
const TargetLowering &T, const Type *AT,ExtAddrMode &AM)
|
||||
: AddrModeInsts(AMI), TLI(T), AccessTy(AT), AddrMode(AM) {}
|
||||
public:
|
||||
|
||||
static ExtAddrMode Match(Value *V, const Type *AccessTy,
|
||||
SmallVectorImpl<Instruction*> &AddrModeInsts,
|
||||
const TargetLowering &TLI) {
|
||||
ExtAddrMode Result;
|
||||
|
||||
bool Success =
|
||||
AddressingModeMatcher(AddrModeInsts,TLI,AccessTy,Result).MatchAddr(V, 0);
|
||||
Success = Success; assert(Success && "Couldn't select *anything*?");
|
||||
return Result;
|
||||
}
|
||||
private:
|
||||
bool MatchScaledValue(Value *ScaleReg, int64_t Scale);
|
||||
bool MatchAddr(Value *V, unsigned Depth);
|
||||
bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
/// MatchScaledValue - Try adding ScaleReg*Scale to the current addressing mode.
|
||||
/// Return true and update AddrMode if this addr mode is legal for the target,
|
||||
/// false if not.
|
||||
static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale,
|
||||
const Type *AccessTy, ExtAddrMode &AddrMode,
|
||||
SmallVectorImpl<Instruction*> &AddrModeInsts,
|
||||
const TargetLowering &TLI, unsigned Depth) {
|
||||
bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale) {
|
||||
// If we already have a scale of this value, we can add to it, otherwise, we
|
||||
// need an available scale field.
|
||||
if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg)
|
||||
@ -566,6 +599,7 @@ static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale,
|
||||
if (TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) {
|
||||
AddrModeInsts.push_back(cast<Instruction>(ScaleReg));
|
||||
AddrMode = TestAddrMode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,46 +607,31 @@ static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
|
||||
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,
|
||||
const TargetLowering &TLI,
|
||||
unsigned Depth) {
|
||||
/// MatchOperationAddr - 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 without modifying AddrMode.
|
||||
bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode,
|
||||
unsigned Depth) {
|
||||
// Avoid exponential behavior on extremely deep expression trees.
|
||||
if (Depth >= 5) return false;
|
||||
|
||||
switch (Opcode) {
|
||||
case Instruction::PtrToInt:
|
||||
// PtrToInt is always a noop, as we know that the int type is pointer sized.
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth))
|
||||
return true;
|
||||
break;
|
||||
return MatchAddr(AddrInst->getOperand(0), Depth);
|
||||
case Instruction::IntToPtr:
|
||||
// This inttoptr is a no-op if the integer type is pointer sized.
|
||||
if (TLI.getValueType(AddrInst->getOperand(0)->getType()) ==
|
||||
TLI.getPointerTy()) {
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
TLI.getPointerTy())
|
||||
return MatchAddr(AddrInst->getOperand(0), Depth);
|
||||
return false;
|
||||
case Instruction::Add: {
|
||||
// Check to see if we can merge in the RHS then the LHS. If so, we win.
|
||||
ExtAddrMode BackupAddrMode = AddrMode;
|
||||
unsigned OldSize = AddrModeInsts.size();
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(1), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth+1) &&
|
||||
FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth+1))
|
||||
if (MatchAddr(AddrInst->getOperand(1), Depth+1) &&
|
||||
MatchAddr(AddrInst->getOperand(0), Depth+1))
|
||||
return true;
|
||||
|
||||
// Restore the old addr mode info.
|
||||
@ -620,10 +639,8 @@ FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
|
||||
AddrModeInsts.resize(OldSize);
|
||||
|
||||
// Otherwise this was over-aggressive. Try merging in the LHS then the RHS.
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth+1) &&
|
||||
FindMaximalLegalAddressingMode(AddrInst->getOperand(1), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth+1))
|
||||
if (MatchAddr(AddrInst->getOperand(0), Depth+1) &&
|
||||
MatchAddr(AddrInst->getOperand(1), Depth+1))
|
||||
return true;
|
||||
|
||||
// Otherwise we definitely can't merge the ADD in.
|
||||
@ -641,15 +658,12 @@ FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
|
||||
case Instruction::Shl: {
|
||||
// Can only handle X*C and X << C.
|
||||
ConstantInt *RHS = dyn_cast<ConstantInt>(AddrInst->getOperand(1));
|
||||
if (!RHS) break;
|
||||
if (!RHS) return false;
|
||||
int64_t Scale = RHS->getSExtValue();
|
||||
if (Opcode == Instruction::Shl)
|
||||
Scale = 1 << Scale;
|
||||
|
||||
if (TryMatchingScaledValue(AddrInst->getOperand(0), Scale, AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI, Depth))
|
||||
return true;
|
||||
break;
|
||||
return MatchScaledValue(AddrInst->getOperand(0), Scale);
|
||||
}
|
||||
case Instruction::GetElementPtr: {
|
||||
// Scan the GEP. We check it if it contains constant offsets and at most
|
||||
@ -664,7 +678,7 @@ FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
|
||||
if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
|
||||
const StructLayout *SL = TD->getStructLayout(STy);
|
||||
unsigned Idx =
|
||||
cast<ConstantInt>(AddrInst->getOperand(i))->getZExtValue();
|
||||
cast<ConstantInt>(AddrInst->getOperand(i))->getZExtValue();
|
||||
ConstantOffset += SL->getElementOffset(Idx);
|
||||
} else {
|
||||
uint64_t TypeSize = TD->getABITypeSize(GTI.getIndexedType());
|
||||
@ -672,10 +686,8 @@ FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
|
||||
ConstantOffset += CI->getSExtValue()*TypeSize;
|
||||
} else if (TypeSize) { // Scales of zero don't do anything.
|
||||
// We only allow one variable index at the moment.
|
||||
if (VariableOperand != -1) {
|
||||
VariableOperand = -2;
|
||||
break;
|
||||
}
|
||||
if (VariableOperand != -1)
|
||||
return false;
|
||||
|
||||
// Remember the variable index.
|
||||
VariableOperand = i;
|
||||
@ -684,81 +696,70 @@ FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode,
|
||||
}
|
||||
}
|
||||
|
||||
// If the GEP had multiple variable indices, punt.
|
||||
if (VariableOperand == -2)
|
||||
break;
|
||||
|
||||
// A common case is for the GEP to only do a constant offset. In this case,
|
||||
// just add it to the disp field and check validity.
|
||||
if (VariableOperand == -1) {
|
||||
AddrMode.BaseOffs += ConstantOffset;
|
||||
if (ConstantOffset == 0 || TLI.isLegalAddressingMode(AddrMode, AccessTy)){
|
||||
// Check to see if we can fold the base pointer in too.
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI,
|
||||
Depth+1))
|
||||
if (MatchAddr(AddrInst->getOperand(0), Depth+1))
|
||||
return true;
|
||||
}
|
||||
AddrMode.BaseOffs -= ConstantOffset;
|
||||
} else {
|
||||
// Check that this has no base reg yet. If so, we won't have a place to
|
||||
// put the base of the GEP (assuming it is not a null ptr).
|
||||
bool SetBaseReg = false;
|
||||
if (AddrMode.HasBaseReg) {
|
||||
if (!isa<ConstantPointerNull>(AddrInst->getOperand(0)))
|
||||
break;
|
||||
} else {
|
||||
AddrMode.HasBaseReg = true;
|
||||
AddrMode.BaseReg = AddrInst->getOperand(0);
|
||||
SetBaseReg = true;
|
||||
}
|
||||
|
||||
// See if the scale amount is valid for this target.
|
||||
AddrMode.BaseOffs += ConstantOffset;
|
||||
if (TryMatchingScaledValue(AddrInst->getOperand(VariableOperand),
|
||||
VariableScale, AccessTy, AddrMode,
|
||||
AddrModeInsts, TLI, Depth)) {
|
||||
if (!SetBaseReg) return true;
|
||||
|
||||
// If this match succeeded, we know that we can form an address with the
|
||||
// GepBase as the basereg. See if we can match *more*.
|
||||
AddrMode.HasBaseReg = false;
|
||||
AddrMode.BaseReg = 0;
|
||||
if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy,
|
||||
AddrMode, AddrModeInsts, TLI,
|
||||
Depth+1))
|
||||
return true;
|
||||
// Strange, shouldn't happen. Restore the base reg and succeed the easy
|
||||
// way.
|
||||
AddrMode.HasBaseReg = true;
|
||||
AddrMode.BaseReg = AddrInst->getOperand(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
AddrMode.BaseOffs -= ConstantOffset;
|
||||
if (SetBaseReg) {
|
||||
AddrMode.HasBaseReg = false;
|
||||
AddrMode.BaseReg = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
// Save the valid addressing mode in case we can't match.
|
||||
ExtAddrMode BackupAddrMode = AddrMode;
|
||||
|
||||
// Check that this has no base reg yet. If so, we won't have a place to
|
||||
// put the base of the GEP (assuming it is not a null ptr).
|
||||
bool SetBaseReg = true;
|
||||
if (isa<ConstantPointerNull>(AddrInst->getOperand(0)))
|
||||
SetBaseReg = false; // null pointer base doesn't need representation.
|
||||
else if (AddrMode.HasBaseReg)
|
||||
return false; // Base register already specified, can't match GEP.
|
||||
else {
|
||||
// Otherwise, we'll use the GEP base as the BaseReg.
|
||||
AddrMode.HasBaseReg = true;
|
||||
AddrMode.BaseReg = AddrInst->getOperand(0);
|
||||
}
|
||||
|
||||
// See if the scale and offset amount is valid for this target.
|
||||
AddrMode.BaseOffs += ConstantOffset;
|
||||
|
||||
// FIXME: If VariableScale = 1, just call MatchAddr recursively?
|
||||
if (!MatchScaledValue(AddrInst->getOperand(VariableOperand),VariableScale)){
|
||||
AddrMode = BackupAddrMode;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have a null as the base of the GEP, folding in the constant offset
|
||||
// plus variable scale is all we can do.
|
||||
if (!SetBaseReg) return true;
|
||||
|
||||
// If this match succeeded, we know that we can form an address with the
|
||||
// GepBase as the basereg. Match the base pointer of the GEP more
|
||||
// aggressively by zeroing out BaseReg and rematching. If the base is
|
||||
// (for example) another GEP, this allows merging in that other GEP into
|
||||
// the addressing mode we're forming.
|
||||
AddrMode.HasBaseReg = false;
|
||||
AddrMode.BaseReg = 0;
|
||||
bool Success = MatchAddr(AddrInst->getOperand(0), Depth+1);
|
||||
assert(Success && "MatchAddr should be able to fill in BaseReg!");
|
||||
Success=Success;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// MatchAddr - If we can, try to add the value of 'Addr' into the current
|
||||
/// addressing mode. If Addr can't be added to AddrMode this returns false and
|
||||
/// leaves AddrMode unmodified. 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) {
|
||||
bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) {
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Addr)) {
|
||||
// Fold in immediates if legal for the target.
|
||||
AddrMode.BaseOffs += CI->getSExtValue();
|
||||
@ -766,7 +767,7 @@ static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *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 this is a global variable, try to fold it into the addressing mode.
|
||||
if (AddrMode.BaseGV == 0) {
|
||||
AddrMode.BaseGV = GV;
|
||||
if (TLI.isLegalAddressingMode(AddrMode, AccessTy))
|
||||
@ -774,24 +775,18 @@ static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
|
||||
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)) {
|
||||
if (MatchOperationAddr(I, I->getOpcode(), 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))
|
||||
if (MatchOperationAddr(CE, CE->getOpcode(), Depth))
|
||||
return true;
|
||||
} else if (isa<ConstantPointerNull>(Addr)) {
|
||||
// Null pointer gets folded without affecting the addressing mode.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Worse case, the target should support [reg] addressing modes. :)
|
||||
if (!AddrMode.HasBaseReg) {
|
||||
AddrMode.HasBaseReg = true;
|
||||
@ -817,6 +812,10 @@ static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy,
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Memory Optimization
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// IsNonLocalValue - Return true if the specified values are defined in a
|
||||
/// different basic block than BB.
|
||||
static bool IsNonLocalValue(Value *V, BasicBlock *BB) {
|
||||
@ -825,21 +824,22 @@ static bool IsNonLocalValue(Value *V, BasicBlock *BB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// OptimizeLoadStoreInst - Load and Store Instructions have often have
|
||||
/// OptimizeMemoryInst - Load and Store Instructions have often have
|
||||
/// addressing modes that can do significant amounts of computation. As such,
|
||||
/// instruction selection will try to get the load or store to do as much
|
||||
/// computation as possible for the program. The problem is that isel can only
|
||||
/// see within a single block. As such, we sink as much legal addressing mode
|
||||
/// stuff into the block as possible.
|
||||
bool CodeGenPrepare::OptimizeLoadStoreInst(Instruction *LdStInst, Value *Addr,
|
||||
const Type *AccessTy,
|
||||
DenseMap<Value*,Value*> &SunkAddrs) {
|
||||
///
|
||||
/// This method is used to optimize both load/store and inline asms with memory
|
||||
/// operands.
|
||||
bool CodeGenPrepare::OptimizeMemoryInst(Instruction *LdStInst, Value *Addr,
|
||||
const Type *AccessTy,
|
||||
DenseMap<Value*,Value*> &SunkAddrs) {
|
||||
// Figure out what addressing mode will be built up for this operation.
|
||||
SmallVector<Instruction*, 16> AddrModeInsts;
|
||||
ExtAddrMode AddrMode;
|
||||
bool Success = FindMaximalLegalAddressingMode(Addr, AccessTy, AddrMode,
|
||||
AddrModeInsts, *TLI, 0);
|
||||
Success = Success; assert(Success && "Couldn't select *anything*?");
|
||||
ExtAddrMode AddrMode =
|
||||
AddressingModeMatcher::Match(Addr, AccessTy, AddrModeInsts, *TLI);
|
||||
|
||||
// Check to see if any of the instructions supersumed by this addr mode are
|
||||
// non-local to I's BB.
|
||||
@ -940,7 +940,7 @@ bool CodeGenPrepare::OptimizeLoadStoreInst(Instruction *LdStInst, Value *Addr,
|
||||
}
|
||||
|
||||
/// OptimizeInlineAsmInst - If there are any memory operands, use
|
||||
/// OptimizeLoadStoreInt to sink their address computing into the block when
|
||||
/// OptimizeMemoryInst to sink their address computing into the block when
|
||||
/// possible / profitable.
|
||||
bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
|
||||
DenseMap<Value*,Value*> &SunkAddrs) {
|
||||
@ -981,8 +981,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
|
||||
if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
|
||||
OpInfo.isIndirect) {
|
||||
Value *OpVal = OpInfo.CallOperandVal;
|
||||
MadeChange |= OptimizeLoadStoreInst(I, OpVal, OpVal->getType(),
|
||||
SunkAddrs);
|
||||
MadeChange |= OptimizeMemoryInst(I, OpVal, OpVal->getType(), SunkAddrs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,13 +1110,13 @@ bool CodeGenPrepare::OptimizeBlock(BasicBlock &BB) {
|
||||
MadeChange |= OptimizeCmpExpression(CI);
|
||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||
if (TLI)
|
||||
MadeChange |= OptimizeLoadStoreInst(I, I->getOperand(0), LI->getType(),
|
||||
SunkAddrs);
|
||||
MadeChange |= OptimizeMemoryInst(I, I->getOperand(0), LI->getType(),
|
||||
SunkAddrs);
|
||||
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||
if (TLI)
|
||||
MadeChange |= OptimizeLoadStoreInst(I, SI->getOperand(1),
|
||||
SI->getOperand(0)->getType(),
|
||||
SunkAddrs);
|
||||
MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1),
|
||||
SI->getOperand(0)->getType(),
|
||||
SunkAddrs);
|
||||
} else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
|
||||
if (GEPI->hasAllZeroIndices()) {
|
||||
/// The GEP operand must be a pointer, so must its result -> BitCast
|
||||
|
Loading…
Reference in New Issue
Block a user