Skip to content

Commit e0615bc

Browse files
committed
[Loads] Add optimized FindAvailableLoadedValue() overload (NFCI)
FindAvailableLoadedValue() accepts an iterator by reference. If no available value is found, then the iterator will either be left at a clobbering instruction or the beginning of the basic block. This allows using FindAvailableLoadedValue() across multiple blocks. If this functionality is not needed, as is the case in InstCombine, then we can use a much more efficient implementation: First try to find an available value, and only perform clobber checks if we actually found one. As this function only looks at a very small number of instructions (6 by default) and usually doesn't find an available value, this saves many expensive alias analysis queries.
1 parent 215bb15 commit e0615bc

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

llvm/include/llvm/Analysis/Loads.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ Value *FindAvailableLoadedValue(LoadInst *Load,
133133
bool *IsLoadCSE = nullptr,
134134
unsigned *NumScanedInst = nullptr);
135135

136+
/// This overload provides a more efficient implementation of
137+
/// FindAvailableLoadedValue() for the case where we are not interested in
138+
/// finding the closest clobbering instruction if no available load is found.
139+
/// This overload cannot be used to scan across multiple blocks.
140+
Value *FindAvailableLoadedValue(LoadInst *Load, AAResults &AA, bool *IsLoadCSE,
141+
unsigned MaxInstsToScan = DefMaxInstsToScan);
142+
136143
/// Scan backwards to see if we have the value of the given pointer available
137144
/// locally within a small number of instructions.
138145
///

llvm/lib/Analysis/Loads.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,51 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
593593
return nullptr;
594594
}
595595

596+
Value *llvm::FindAvailableLoadedValue(LoadInst *Load, AAResults &AA,
597+
bool *IsLoadCSE,
598+
unsigned MaxInstsToScan) {
599+
const DataLayout &DL = Load->getModule()->getDataLayout();
600+
Value *StrippedPtr = Load->getPointerOperand()->stripPointerCasts();
601+
BasicBlock *ScanBB = Load->getParent();
602+
Type *AccessTy = Load->getType();
603+
bool AtLeastAtomic = Load->isAtomic();
604+
605+
if (!Load->isUnordered())
606+
return nullptr;
607+
608+
// Try to find an available value first, and delay expensive alias analysis
609+
// queries until later.
610+
Value *Available = nullptr;;
611+
SmallVector<Instruction *> MustNotAliasInsts;
612+
for (Instruction &Inst : make_range(++Load->getReverseIterator(),
613+
ScanBB->rend())) {
614+
if (isa<DbgInfoIntrinsic>(&Inst))
615+
continue;
616+
617+
if (MaxInstsToScan-- == 0)
618+
return nullptr;
619+
620+
Available = getAvailableLoadStore(&Inst, StrippedPtr, AccessTy,
621+
AtLeastAtomic, DL, IsLoadCSE);
622+
if (Available)
623+
break;
624+
625+
if (Inst.mayWriteToMemory())
626+
MustNotAliasInsts.push_back(&Inst);
627+
}
628+
629+
// If we found an available value, ensure that the instructions in between
630+
// did not modify the memory location.
631+
if (Available) {
632+
auto AccessSize = LocationSize::precise(DL.getTypeStoreSize(AccessTy));
633+
for (Instruction *Inst : MustNotAliasInsts)
634+
if (isModSet(AA.getModRefInfo(Inst, StrippedPtr, AccessSize)))
635+
return nullptr;
636+
}
637+
638+
return Available;
639+
}
640+
596641
bool llvm::canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
597642
Instruction *CtxI) {
598643
Type *Ty = A->getType();

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -956,10 +956,8 @@ Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) {
956956
// Do really simple store-to-load forwarding and load CSE, to catch cases
957957
// where there are several consecutive memory accesses to the same location,
958958
// separated by a few arithmetic operations.
959-
BasicBlock::iterator BBI(LI);
960959
bool IsLoadCSE = false;
961-
if (Value *AvailableVal = FindAvailableLoadedValue(
962-
&LI, LI.getParent(), BBI, DefMaxInstsToScan, AA, &IsLoadCSE)) {
960+
if (Value *AvailableVal = FindAvailableLoadedValue(&LI, *AA, &IsLoadCSE)) {
963961
if (IsLoadCSE)
964962
combineMetadataForCSE(cast<LoadInst>(AvailableVal), &LI, false);
965963

0 commit comments

Comments
 (0)