Skip to content

Commit 25dcd23

Browse files
authored
[IPO] Added attributor for identifying invariant loads (#141800)
The attributor conservatively marks pointers whose loads are eligible to be marked as `!invariant.load`. It does so by identifying: 1. Pointers marked `noalias` and `readonly` 2. Pointers whose underlying objects are all eligible for invariant loads. The attributor then manifests this attribute at non-atomic non-volatile load instructions.
1 parent 5acdd8d commit 25dcd23

File tree

6 files changed

+772
-15
lines changed

6 files changed

+772
-15
lines changed

llvm/include/llvm/Transforms/IPO/Attributor.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6335,6 +6335,47 @@ struct AAUnderlyingObjects : AbstractAttribute {
63356335
AA::ValueScope Scope = AA::Interprocedural) const = 0;
63366336
};
63376337

6338+
/// An abstract interface for identifying pointers from which loads can be
6339+
/// marked invariant.
6340+
struct AAInvariantLoadPointer : public AbstractAttribute {
6341+
AAInvariantLoadPointer(const IRPosition &IRP) : AbstractAttribute(IRP) {}
6342+
6343+
/// See AbstractAttribute::isValidIRPositionForInit
6344+
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP) {
6345+
if (!IRP.getAssociatedType()->isPointerTy())
6346+
return false;
6347+
6348+
return AbstractAttribute::isValidIRPositionForInit(A, IRP);
6349+
}
6350+
6351+
/// Create an abstract attribute view for the position \p IRP.
6352+
static AAInvariantLoadPointer &createForPosition(const IRPosition &IRP,
6353+
Attributor &A);
6354+
6355+
/// Return true if the pointer's contents are known to remain invariant.
6356+
virtual bool isKnownInvariant() const = 0;
6357+
virtual bool isKnownLocallyInvariant() const = 0;
6358+
6359+
/// Return true if the pointer's contents are assumed to remain invariant.
6360+
virtual bool isAssumedInvariant() const = 0;
6361+
virtual bool isAssumedLocallyInvariant() const = 0;
6362+
6363+
/// See AbstractAttribute::getName().
6364+
StringRef getName() const override { return "AAInvariantLoadPointer"; }
6365+
6366+
/// See AbstractAttribute::getIdAddr().
6367+
const char *getIdAddr() const override { return &ID; }
6368+
6369+
/// This function should return true if the type of the \p AA is
6370+
/// AAInvariantLoadPointer
6371+
static bool classof(const AbstractAttribute *AA) {
6372+
return (AA->getIdAddr() == &ID);
6373+
}
6374+
6375+
/// Unique ID (due to the unique address).
6376+
static const char ID;
6377+
};
6378+
63386379
/// An abstract interface for address space information.
63396380
struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
63406381
AAAddressSpace(const IRPosition &IRP, Attributor &A)

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3612,6 +3612,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
36123612
if (SimplifyAllLoads)
36133613
getAssumedSimplified(IRPosition::value(I), nullptr,
36143614
UsedAssumedInformation, AA::Intraprocedural);
3615+
getOrCreateAAFor<AAInvariantLoadPointer>(
3616+
IRPosition::value(*LI->getPointerOperand()));
36153617
getOrCreateAAFor<AAAddressSpace>(
36163618
IRPosition::value(*LI->getPointerOperand()));
36173619
} else {

0 commit comments

Comments
 (0)