-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Attributor]: AApointerInfo - store the full chain of instructions that make up the access #96526
Open
vidsinghal
wants to merge
1
commit into
llvm:main
Choose a base branch
from
vidsinghal:pointerinfo_keep_chains
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+793
−112
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-llvm-transforms Author: Vidush Singhal (vidsinghal) ChangesFull diff: https://github.com/llvm/llvm-project/pull/96526.diff 2 Files Affected:
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 6ba04dbc31db3..bef573da7ddd9 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -103,6 +103,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
@@ -137,9 +138,11 @@
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
+#include <cstdint>
#include <limits>
#include <map>
#include <optional>
+#include <utility>
namespace llvm {
@@ -5784,6 +5787,54 @@ struct AAPointerInfo : public AbstractAttribute {
AK_MUST_READ_WRITE = AK_MUST | AK_R | AK_W,
};
+ /// A helper containing a list of offsets computed for a Use. Ideally this
+ /// list should be strictly ascending, but we ensure that only when we
+ /// actually translate the list of offsets to a RangeList.
+ struct OffsetInfo {
+ using VecTy = SmallVector<int64_t>;
+ using const_iterator = VecTy::const_iterator;
+ VecTy Offsets;
+
+ const_iterator begin() const { return Offsets.begin(); }
+ const_iterator end() const { return Offsets.end(); }
+
+ bool operator==(const OffsetInfo &RHS) const {
+ return Offsets == RHS.Offsets;
+ }
+
+ bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
+
+ void insert(int64_t Offset) { Offsets.push_back(Offset); }
+ bool isUnassigned() const { return Offsets.size() == 0; }
+
+ bool isUnknown() const {
+ if (isUnassigned())
+ return false;
+ if (Offsets.size() == 1)
+ return Offsets.front() == AA::RangeTy::Unknown;
+ return false;
+ }
+
+ void setUnknown() {
+ Offsets.clear();
+ Offsets.push_back(AA::RangeTy::Unknown);
+ }
+
+ void addToAll(int64_t Inc) {
+ for (auto &Offset : Offsets) {
+ Offset += Inc;
+ }
+ }
+
+ /// Copy offsets from \p R into the current list.
+ ///
+ /// Ideally all lists should be strictly ascending, but we defer that to the
+ /// actual use of the list. So we just blindly append here.
+ void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); }
+ };
+
+ using OffsetInfoMapTy = DenseMap<Value *, OffsetInfo>;
+
/// A container for a list of ranges.
struct RangeList {
// The set of ranges rarely contains more than one element, and is unlikely
@@ -5938,13 +5989,16 @@ struct AAPointerInfo : public AbstractAttribute {
/// An access description.
struct Access {
Access(Instruction *I, int64_t Offset, int64_t Size,
- std::optional<Value *> Content, AccessKind Kind, Type *Ty)
+ std::optional<Value *> Content, AccessKind Kind, Type *Ty,
+ OffsetInfoMapTy &OffsetInfoMap)
: LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
Kind(Kind), Ty(Ty) {
verify();
+ generateAccessCausingChain(OffsetInfoMap);
}
Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
- std::optional<Value *> Content, AccessKind K, Type *Ty)
+ std::optional<Value *> Content, AccessKind K, Type *Ty,
+ OffsetInfoMapTy &OffsetInfoMap)
: LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
Kind(K), Ty(Ty) {
if (Ranges.size() > 1) {
@@ -5952,13 +6006,15 @@ struct AAPointerInfo : public AbstractAttribute {
Kind = AccessKind(Kind & ~AK_MUST);
}
verify();
+ generateAccessCausingChain(OffsetInfoMap);
}
Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
int64_t Size, std::optional<Value *> Content, AccessKind Kind,
- Type *Ty)
+ Type *Ty, OffsetInfoMapTy &OffsetInfoMap)
: LocalI(LocalI), RemoteI(RemoteI), Content(Content),
Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
verify();
+ generateAccessCausingChain(OffsetInfoMap);
}
Access(const Access &Other) = default;
@@ -6077,6 +6133,50 @@ struct AAPointerInfo : public AbstractAttribute {
}
}
+ // Generate the full chain of access cauing instruction to the
+ void generateAccessCausingChain(OffsetInfoMapTy &OffsetInfoMap) {
+
+ SmallVector<Instruction *> ReadyList;
+ DenseMap<Instruction *, bool> Visited;
+ ReadyList.push_back(LocalI);
+ CompleteAccessChain.push_back(LocalI);
+
+ while (!ReadyList.empty()) {
+
+ Instruction *Back = ReadyList.back();
+ ReadyList.pop_back();
+
+ if (!Visited.insert(std::make_pair(Back, true)).second)
+ continue;
+
+ // populate worklist with operands.
+ for (auto *It = Back->op_begin(); It != Back->op_end(); It++) {
+ if (Instruction *I = dyn_cast<Instruction>(It))
+ ReadyList.push_back(I);
+ }
+
+ if (!OffsetInfoMap.contains(Back))
+ continue;
+
+ const OffsetInfo &Info = OffsetInfoMap.lookup(Back);
+ const auto &OffsetVec = Info.Offsets;
+
+ bool HasAtLeastOneSameOffset = false;
+ for (auto *It = begin(); It != end(); It++) {
+ int64_t RangeOffset = It->Offset;
+ for (auto Offset : OffsetVec) {
+ if (RangeOffset == Offset) {
+ HasAtLeastOneSameOffset = true;
+ break;
+ }
+ }
+ }
+
+ if (HasAtLeastOneSameOffset)
+ CompleteAccessChain.push_back(Back);
+ }
+ }
+
const RangeList &getRanges() const { return Ranges; }
using const_iterator = RangeList::const_iterator;
@@ -6104,6 +6204,9 @@ struct AAPointerInfo : public AbstractAttribute {
/// The type of the content, thus the type read/written, can be null if not
/// available.
Type *Ty;
+
+ /// The full chain of instruction that participate in the Access.
+ SmallVector<Instruction *> CompleteAccessChain;
};
/// Create an abstract attribute view for the position \p IRP.
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index c4b9375a53a27..a7f9fdd7c0532 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -850,6 +850,7 @@ struct AA::PointerInfo::State : public AbstractState {
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges,
Instruction &I, std::optional<Value *> Content,
AAPointerInfo::AccessKind Kind, Type *Ty,
+ AAPointerInfo::OffsetInfoMapTy &OffsetInfoMap,
Instruction *RemoteI = nullptr);
AAPointerInfo::const_bin_iterator begin() const { return OffsetBins.begin(); }
@@ -929,7 +930,7 @@ struct AA::PointerInfo::State : public AbstractState {
ChangeStatus AA::PointerInfo::State::addAccess(
Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I,
std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
- Instruction *RemoteI) {
+ AAPointerInfo::OffsetInfoMapTy &OffsetInfoMap, Instruction *RemoteI) {
RemoteI = RemoteI ? RemoteI : &I;
// Check if we have an access for this instruction, if not, simply add it.
@@ -956,7 +957,8 @@ ChangeStatus AA::PointerInfo::State::addAccess(
};
if (!AccExists) {
- AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
+ AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty,
+ OffsetInfoMap);
assert((AccessList.size() == AccIndex + 1) &&
"New Access should have been at AccIndex");
LocalList.push_back(AccIndex);
@@ -966,7 +968,8 @@ ChangeStatus AA::PointerInfo::State::addAccess(
// Combine the new Access with the existing Access, and then update the
// mapping in the offset bins.
- AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
+ AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty,
+ OffsetInfoMap);
auto &Current = AccessList[AccIndex];
auto Before = Current;
Current &= Acc;
@@ -1002,54 +1005,9 @@ ChangeStatus AA::PointerInfo::State::addAccess(
namespace {
-/// A helper containing a list of offsets computed for a Use. Ideally this
-/// list should be strictly ascending, but we ensure that only when we
-/// actually translate the list of offsets to a RangeList.
-struct OffsetInfo {
- using VecTy = SmallVector<int64_t>;
- using const_iterator = VecTy::const_iterator;
- VecTy Offsets;
-
- const_iterator begin() const { return Offsets.begin(); }
- const_iterator end() const { return Offsets.end(); }
-
- bool operator==(const OffsetInfo &RHS) const {
- return Offsets == RHS.Offsets;
- }
-
- bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
-
- void insert(int64_t Offset) { Offsets.push_back(Offset); }
- bool isUnassigned() const { return Offsets.size() == 0; }
-
- bool isUnknown() const {
- if (isUnassigned())
- return false;
- if (Offsets.size() == 1)
- return Offsets.front() == AA::RangeTy::Unknown;
- return false;
- }
-
- void setUnknown() {
- Offsets.clear();
- Offsets.push_back(AA::RangeTy::Unknown);
- }
-
- void addToAll(int64_t Inc) {
- for (auto &Offset : Offsets) {
- Offset += Inc;
- }
- }
-
- /// Copy offsets from \p R into the current list.
- ///
- /// Ideally all lists should be strictly ascending, but we defer that to the
- /// actual use of the list. So we just blindly append here.
- void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); }
-};
-
#ifndef NDEBUG
-static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) {
+static raw_ostream &operator<<(raw_ostream &OS,
+ const AAPointerInfo::OffsetInfo &OI) {
ListSeparator LS;
OS << "[";
for (auto Offset : OI) {
@@ -1365,7 +1323,8 @@ struct AAPointerInfoImpl
ChangeStatus translateAndAddStateFromCallee(Attributor &A,
const AAPointerInfo &OtherAA,
- CallBase &CB) {
+ CallBase &CB,
+ OffsetInfoMapTy &OffsetInfoMap) {
using namespace AA::PointerInfo;
if (!OtherAA.getState().isValidState() || !isValidState())
return indicatePessimisticFixpoint();
@@ -1388,8 +1347,9 @@ struct AAPointerInfoImpl
AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
- Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
- RAcc.getType(), RAcc.getRemoteInst());
+ Changed |=
+ addAccess(A, RAcc.getRanges(), CB, Content, AK, RAcc.getType(),
+ OffsetInfoMap, RAcc.getRemoteInst());
}
}
return Changed;
@@ -1418,7 +1378,7 @@ struct AAPointerInfoImpl
}
Changed |=
addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
- RAcc.getType(), RAcc.getRemoteInst());
+ RAcc.getType(), OffsetInfoMap, RAcc.getRemoteInst());
}
}
}
@@ -1452,6 +1412,8 @@ struct AAPointerInfoImpl
}
}
}
+
+ OffsetInfoMapTy OffsetInfoMap;
};
struct AAPointerInfoFloating : public AAPointerInfoImpl {
@@ -1463,7 +1425,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
bool handleAccess(Attributor &A, Instruction &I,
std::optional<Value *> Content, AccessKind Kind,
SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed,
- Type &Ty) {
+ Type &Ty, OffsetInfoMapTy &OffsetInfoMap) {
using namespace AA::PointerInfo;
auto Size = AA::RangeTy::Unknown;
const DataLayout &DL = A.getDataLayout();
@@ -1481,7 +1443,8 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
!Content.value_or(nullptr) || !isa<Constant>(*Content) ||
(*Content)->getType() != VT ||
DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
- Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty);
+ Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty,
+ OffsetInfoMap);
} else {
// Handle vector stores with constant content element-wise.
// TODO: We could look for the elements or create instructions
@@ -1501,7 +1464,8 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
// Add the element access.
Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
- ElementContent, Kind, ElementType);
+ ElementContent, Kind, ElementType,
+ OffsetInfoMap);
// Advance the offsets for the next element.
for (auto &ElementOffset : ElementOffsets)
@@ -1596,7 +1560,7 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
const DataLayout &DL = A.getDataLayout();
Value &AssociatedValue = getAssociatedValue();
- DenseMap<Value *, OffsetInfo> OffsetInfoMap;
+ OffsetInfoMap.clear();
OffsetInfoMap[&AssociatedValue].insert(0);
auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
@@ -1750,7 +1714,7 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
AK = AccessKind(AK | AccessKind::AK_MAY);
if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
OffsetInfoMap[CurPtr].Offsets, Changed,
- *LoadI->getType()))
+ *LoadI->getType(), OffsetInfoMap))
return false;
auto IsAssumption = [](Instruction &I) {
@@ -1834,9 +1798,10 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
Content =
A.getAssumedSimplified(*Assumption.first, *this,
UsedAssumedInformation, AA::Interprocedural);
- return handleAccess(
- A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
- OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
+ return handleAccess(A, *Assumption.second, Content,
+ AccessKind::AK_ASSUMPTION,
+ OffsetInfoMap[CurPtr].Offsets, Changed,
+ *LoadI->getType(), OffsetInfoMap);
}
auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
@@ -1863,7 +1828,7 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
Content = A.getAssumedSimplified(
*ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
- Changed, ValueTy);
+ Changed, ValueTy, OffsetInfoMap);
};
if (auto *StoreI = dyn_cast<StoreInst>(Usr))
@@ -1984,8 +1949,8 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
} else {
auto Kind =
ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
- Changed =
- Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
+ Changed = Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind,
+ nullptr, OffsetInfoMap);
}
LLVM_DEBUG({
dbgs() << "Accesses by bin after update:\n";
@@ -2005,8 +1970,8 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
auto *ArgAA =
A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
if (ArgAA && ArgAA->getState().isValidState())
- return translateAndAddStateFromCallee(A, *ArgAA,
- *cast<CallBase>(getCtxI()));
+ return translateAndAddStateFromCallee(
+ A, *ArgAA, *cast<CallBase>(getCtxI()), OffsetInfoMap);
if (!Arg->getParent()->isDeclaration())
return indicatePessimisticFixpoint();
}
@@ -2023,7 +1988,7 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
auto Kind =
ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
- nullptr);
+ nullptr, OffsetInfoMap);
}
/// See AbstractAttribute::trackStatistics()
|
vidsinghal
changed the title
Store the full chain of instructions that make up the access.
[Attributor]: AApointerInfo - store the full chain of instructions that make up the access
Jun 24, 2024
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
3 times, most recently
from
June 24, 2024 18:06
654d25e
to
ba83e3b
Compare
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
3 times, most recently
from
June 25, 2024 22:09
f9bf7b4
to
c67e4bf
Compare
jdoerfert
reviewed
Jun 26, 2024
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
18 times, most recently
from
July 1, 2024 18:11
b265b61
to
a8a794a
Compare
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
shiltian
reviewed
Jul 8, 2024
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
from
July 8, 2024 20:24
e87d1ad
to
0e2b87e
Compare
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
7 times, most recently
from
July 8, 2024 20:43
d6451cb
to
5a52f5b
Compare
shiltian
reviewed
Jul 9, 2024
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
from
July 10, 2024 00:21
5a52f5b
to
7f92d36
Compare
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
8 times, most recently
from
July 11, 2024 16:41
267330a
to
ecbda90
Compare
vidsinghal
force-pushed
the
pointerinfo_keep_chains
branch
from
July 11, 2024 16:43
ecbda90
to
c95ac0a
Compare
shiltian
reviewed
Jul 13, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patch is in a descent shape I think. WDYT? @jdoerfert
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Support for keeping track of the full chain of instructions in AAPointerInfo.
We need this for modifying intermediate instructions rather than add new instructions to the final load/store when offsets change. Corresponding PR: #72029