Jlm
Loading...
Searching...
No Matches
PointsToGraphAliasAnalysis.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
7
8namespace jlm::llvm::aa
9{
11 std::shared_ptr<const PointsToGraph> pointsToGraph)
12 : pointsToGraph_(std::move(pointsToGraph))
13{}
14
16
17std::string
19{
20 return "PointsToGraphAA";
21}
22
25 const rvsdg::Output & p1,
26 const size_t s1,
27 const rvsdg::Output & p2,
28 const size_t s2)
29{
30 // If the two pointers are the same value, they must alias
31 if (&p1 == &p2)
32 return MustAlias;
33
34 // The output may have been created after the PointsToGraph
35 // In which case we have no better response than MayAlias
36 auto tryP1RegisterNode = pointsToGraph_->tryGetNodeForRegister(p1);
37 if (!tryP1RegisterNode)
38 return MayAlias;
39
40 auto tryP2RegisterNode = pointsToGraph_->tryGetNodeForRegister(p2);
41 if (!tryP2RegisterNode)
42 return MayAlias;
43
44 const auto p1RegisterNode = *tryP1RegisterNode;
45 const auto p2RegisterNode = *tryP2RegisterNode;
46
47 // Check if both pointers may target the external node, to avoid iterating over large sets
48 const bool p1TargetsExternal = pointsToGraph_->isTargetingAllExternallyAvailable(p1RegisterNode);
49 const bool p2TargetsExternal = pointsToGraph_->isTargetingAllExternallyAvailable(p2RegisterNode);
50 if (p1TargetsExternal && p2TargetsExternal)
51 return MayAlias;
52
53 // If both p1 and p2 have exactly one possible target, which is the same for both,
54 // and is the same size as the operations, and only represents one concrete memory location,
55 // we can respond with MustAlias
56 if (s1 == s2)
57 {
58 const auto p1SingleTarget = TryGetSingleTarget(p1RegisterNode, s1);
59 const auto p2SingleTarget = TryGetSingleTarget(p2RegisterNode, s2);
60 if (p1SingleTarget.has_value() && p2SingleTarget.has_value()
61 && *p1SingleTarget == *p2SingleTarget && IsRepresentingSingleMemoryLocation(*p1SingleTarget)
62 && pointsToGraph_->tryGetNodeSize(*p1SingleTarget) == s1)
63 {
64 return MustAlias;
65 }
66 }
67
68 // For a memory location to be the target of both p1 and p2, it needs to be large enough
69 // to represent both [p1, p1+s1) and [p2, p2+s2)
70 const auto neededSize = std::max(s1, s2);
71
72 // At least one of the nodes only has explicit targets
73 PointsToGraph::NodeIndex onlyExplicitTargetsNode = p1RegisterNode;
74 PointsToGraph::NodeIndex otherNode = p2RegisterNode;
75 if (p1TargetsExternal)
76 {
77 JLM_ASSERT(!p2TargetsExternal);
78 std::swap(onlyExplicitTargetsNode, otherNode);
79 }
80
81 for (const auto target : pointsToGraph_->getExplicitTargets(onlyExplicitTargetsNode).Items())
82 {
83 // Skip memory locations that are too small
84 const auto targetSize = pointsToGraph_->tryGetNodeSize(target);
85
86 if (targetSize.has_value() && *targetSize < neededSize)
87 continue;
88
89 if (pointsToGraph_->isTargeting(otherNode, target))
90 return MayAlias;
91 }
92
93 return NoAlias;
94}
95
96std::optional<PointsToGraph::NodeIndex>
98{
99 // Nodes that target everything external always have "infinite" targets
100 if (pointsToGraph_->isTargetingAllExternallyAvailable(node))
101 return std::nullopt;
102
103 std::optional<PointsToGraph::NodeIndex> singleTarget = std::nullopt;
104
105 for (const auto target : pointsToGraph_->getExplicitTargets(node).Items())
106 {
107 // Skip memory locations that are too small to hold size
108 const auto targetSize = pointsToGraph_->tryGetNodeSize(target);
109 if (targetSize.has_value() && *targetSize < size)
110 continue;
111
112 // If we already have a "single target", there is more than one target
113 if (singleTarget.has_value())
114 return std::nullopt;
115
116 singleTarget = target;
117 }
118
119 return singleTarget;
120}
121
122bool
124{
125 switch (pointsToGraph_->getNodeKind(node))
126 {
130 return false;
134 return true;
135 default:
136 throw std::logic_error("Unknown node kind");
137 }
138}
139
140}
PointsToGraphAliasAnalysis(std::shared_ptr< const PointsToGraph > pointsToGraph)
bool IsRepresentingSingleMemoryLocation(PointsToGraph::NodeIndex node) const
std::optional< PointsToGraph::NodeIndex > TryGetSingleTarget(PointsToGraph::NodeIndex node, size_t size) const
std::shared_ptr< const PointsToGraph > pointsToGraph_
~PointsToGraphAliasAnalysis() noexcept override
AliasQueryResponse Query(const rvsdg::Output &p1, size_t s1, const rvsdg::Output &p2, size_t s2) override
#define JLM_ASSERT(x)
Definition common.hpp:16
static std::string ToString(const std::vector< MemoryNodeId > &memoryNodeIds)