Index: llvm/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/include/llvm/Transforms/IPO/Attributor.h +++ llvm/include/llvm/Transforms/IPO/Attributor.h @@ -965,6 +965,19 @@ /* ForceUpdate */ true); } + /// Return abstract attribute of type \p AAType at position \p IRP. If the AA + /// has not been initialized, this initializes it and forces it to indicate + /// a pessimistic fixpoint. This is useful when we want to query abstract + /// attributes after we are done with the update stage e.g. in + /// AbstractAttribute::manifest. + template + const AAType &getAAAfterIterationFor(const IRPosition &IRP) { + return getOrCreateAAFor(IRP, nullptr, /* TrackDependence */ false, + DepClassTy::OPTIONAL, + /* ForceUpdate */ false, + /* AfterIteration */ true); + } + /// The version of getAAFor that allows to omit a querying abstract /// attribute. Using this after Attributor started running is restricted to /// only the Attributor itself. Initial seeding of AAs can be done via this @@ -974,10 +987,13 @@ const AbstractAttribute *QueryingAA = nullptr, bool TrackDependence = false, DepClassTy DepClass = DepClassTy::OPTIONAL, - bool ForceUpdate = false) { + bool ForceUpdate = false, + bool AfterIteration = false) { if (AAType *AAPtr = lookupAAFor(IRP, QueryingAA, TrackDependence)) { - if (ForceUpdate) + if (ForceUpdate) { + assert(!AfterIteration && "We cannot update AA after iteration!"); updateAA(*AAPtr); + } return *AAPtr; } @@ -1020,6 +1036,13 @@ return AA; } + // If this is queried after the update stage, we immediately force it to + // indicate a pessimistic fixpoint. + if (AfterIteration) { + AA.getState().indicatePessimisticFixpoint(); + return AA; + } + // Allow seeded attributes to declare dependencies. // Remember the seeding state. bool OldSeedingPeriod = SeedingPeriod;