/// Recursively walk all the uses of I until we find a memory use.
/// If we find an obviously non-foldable instruction, return true.
-/// Add the ultimately found memory instructions to MemoryUses.
+/// Add accessed addresses and types to MemoryUses.
static bool FindAllMemoryUses(
- Instruction *I,
- SmallVectorImpl<std::pair<Instruction *, unsigned>> &MemoryUses,
+ Instruction *I, SmallVectorImpl<std::pair<Value *, Type *>> &MemoryUses,
SmallPtrSetImpl<Instruction *> &ConsideredInsts, const TargetLowering &TLI,
const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI,
BlockFrequencyInfo *BFI, int SeenInsts = 0) {
Instruction *UserI = cast<Instruction>(U.getUser());
if (LoadInst *LI = dyn_cast<LoadInst>(UserI)) {
- MemoryUses.push_back(std::make_pair(LI, U.getOperandNo()));
+ MemoryUses.push_back({U.get(), LI->getType()});
continue;
}
if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
- unsigned opNo = U.getOperandNo();
- if (opNo != StoreInst::getPointerOperandIndex())
+ if (U.getOperandNo() != StoreInst::getPointerOperandIndex())
return true; // Storing addr, not into addr.
- MemoryUses.push_back(std::make_pair(SI, opNo));
+ MemoryUses.push_back({U.get(), SI->getValueOperand()->getType()});
continue;
}
if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(UserI)) {
- unsigned opNo = U.getOperandNo();
- if (opNo != AtomicRMWInst::getPointerOperandIndex())
+ if (U.getOperandNo() != AtomicRMWInst::getPointerOperandIndex())
return true; // Storing addr, not into addr.
- MemoryUses.push_back(std::make_pair(RMW, opNo));
+ MemoryUses.push_back({U.get(), RMW->getValOperand()->getType()});
continue;
}
if (AtomicCmpXchgInst *CmpX = dyn_cast<AtomicCmpXchgInst>(UserI)) {
- unsigned opNo = U.getOperandNo();
- if (opNo != AtomicCmpXchgInst::getPointerOperandIndex())
+ if (U.getOperandNo() != AtomicCmpXchgInst::getPointerOperandIndex())
return true; // Storing addr, not into addr.
- MemoryUses.push_back(std::make_pair(CmpX, opNo));
+ MemoryUses.push_back({U.get(), CmpX->getCompareOperand()->getType()});
continue;
}
// we can remove the addressing mode and effectively trade one live register
// for another (at worst.) In this context, folding an addressing mode into
// the use is just a particularly nice way of sinking it.
- SmallVector<std::pair<Instruction*,unsigned>, 16> MemoryUses;
+ SmallVector<std::pair<Value *, Type *>, 16> MemoryUses;
SmallPtrSet<Instruction*, 16> ConsideredInsts;
if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TLI, TRI, OptSize,
PSI, BFI))
// growth since most architectures have some reasonable small and fast way to
// compute an effective address. (i.e LEA on x86)
SmallVector<Instruction*, 32> MatchedAddrModeInsts;
- for (unsigned i = 0, e = MemoryUses.size(); i != e; ++i) {
- Instruction *User = MemoryUses[i].first;
- unsigned OpNo = MemoryUses[i].second;
-
- // Get the access type of this use. If the use isn't a pointer, we don't
- // know what it accesses.
- Value *Address = User->getOperand(OpNo);
- PointerType *AddrTy = dyn_cast<PointerType>(Address->getType());
- if (!AddrTy)
- return false;
- Type *AddressAccessTy = AddrTy->getElementType();
- unsigned AS = AddrTy->getAddressSpace();
+ for (const std::pair<Value *, Type *> &Pair : MemoryUses) {
+ Value *Address = Pair.first;
+ Type *AddressAccessTy = Pair.second;
+ unsigned AS = Address->getType()->getPointerAddressSpace();
// Do a match against the root of this address, ignoring profitability. This
// will tell us if the addressing mode for the memory operation will