[llvm] r272578 - [CFLAA] Refactor to remove redundant maps. NFC.
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 13 12:21:19 PDT 2016
Author: gbiv
Date: Mon Jun 13 14:21:18 2016
New Revision: 272578
URL: http://llvm.org/viewvc/llvm-project?rev=272578&view=rev
Log:
[CFLAA] Refactor to remove redundant maps. NFC.
Patch by Jia Chen.
Differential Revision: http://reviews.llvm.org/D21233
Modified:
llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
Modified: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp?rev=272578&r1=272577&r2=272578&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp Mon Jun 13 14:21:18 2016
@@ -512,141 +512,85 @@ public:
}
};
-/// Set building requires a weighted bidirectional graph.
-template <typename EdgeTypeT> class WeightedBidirectionalGraph {
-public:
- typedef std::size_t Node;
-
+/// The Program Expression Graph (PEG) of CFL analysis
+class CFLGraph {
private:
- const static Node StartNode = Node(0);
+ typedef Value *Node;
struct Edge {
- EdgeTypeT Weight;
+ StratifiedAttrs Attr;
+ EdgeType Type;
Node Other;
-
- Edge(const EdgeTypeT &W, const Node &N) : Weight(W), Other(N) {}
-
- bool operator==(const Edge &E) const {
- return Weight == E.Weight && Other == E.Other;
- }
-
- bool operator!=(const Edge &E) const { return !operator==(E); }
};
- struct NodeImpl {
- std::vector<Edge> Edges;
- };
-
- std::vector<NodeImpl> NodeImpls;
-
- bool inbounds(Node NodeIndex) const { return NodeIndex < NodeImpls.size(); }
-
- const NodeImpl &getNode(Node N) const { return NodeImpls[N]; }
- NodeImpl &getNode(Node N) { return NodeImpls[N]; }
-
-public:
- /// \brief Iterator for edges. Because this graph is bidirected, we don't
- /// allow modification of the edges using this iterator. Additionally, the
- /// iterator becomes invalid if you add edges to or from the node you're
- /// getting the edges of.
- struct EdgeIterator : public std::iterator<std::forward_iterator_tag,
- std::tuple<EdgeTypeT, Node *>> {
- EdgeIterator(const typename std::vector<Edge>::const_iterator &Iter)
- : Current(Iter) {}
-
- EdgeIterator(NodeImpl &Impl) : Current(Impl.begin()) {}
-
- EdgeIterator &operator++() {
- ++Current;
- return *this;
- }
-
- EdgeIterator operator++(int) {
- EdgeIterator Copy(Current);
- operator++();
- return Copy;
- }
-
- std::tuple<EdgeTypeT, Node> &operator*() {
- Store = std::make_tuple(Current->Weight, Current->Other);
- return Store;
- }
-
- bool operator==(const EdgeIterator &Other) const {
- return Current == Other.Current;
+ typedef std::vector<Edge> EdgeList;
+ typedef DenseMap<Node, EdgeList> NodeMap;
+ NodeMap NodeImpls;
+
+ // Gets the inverse of a given EdgeType.
+ static EdgeType flipWeight(EdgeType Initial) {
+ switch (Initial) {
+ case EdgeType::Assign:
+ return EdgeType::Assign;
+ case EdgeType::Dereference:
+ return EdgeType::Reference;
+ case EdgeType::Reference:
+ return EdgeType::Dereference;
}
+ llvm_unreachable("Incomplete coverage of EdgeType enum");
+ }
- bool operator!=(const EdgeIterator &Other) const {
- return !operator==(Other);
- }
+ const EdgeList *getNode(Node N) const {
+ auto Itr = NodeImpls.find(N);
+ if (Itr == NodeImpls.end())
+ return nullptr;
+ return &Itr->second;
+ }
+ EdgeList &getOrCreateNode(Node N) { return NodeImpls[N]; }
- private:
- typename std::vector<Edge>::const_iterator Current;
- std::tuple<EdgeTypeT, Node> Store;
- };
+ static Node nodeDeref(const NodeMap::value_type &P) { return P.first; }
+ typedef std::pointer_to_unary_function<const NodeMap::value_type &, Node>
+ NodeDerefFun;
- /// Wrapper for EdgeIterator with begin()/end() calls.
- struct EdgeIterable {
- EdgeIterable(const std::vector<Edge> &Edges)
- : BeginIter(Edges.begin()), EndIter(Edges.end()) {}
-
- EdgeIterator begin() { return EdgeIterator(BeginIter); }
-
- EdgeIterator end() { return EdgeIterator(EndIter); }
-
- private:
- typename std::vector<Edge>::const_iterator BeginIter;
- typename std::vector<Edge>::const_iterator EndIter;
- };
+public:
+ typedef EdgeList::const_iterator const_edge_iterator;
+ typedef mapped_iterator<NodeMap::const_iterator, NodeDerefFun>
+ const_node_iterator;
- // ----- Actual graph-related things ----- //
+ CFLGraph() = default;
+ CFLGraph(CFLGraph &&) = default;
+ CFLGraph &operator=(CFLGraph &&) = default;
- WeightedBidirectionalGraph() {}
+ void addNode(Node N) { getOrCreateNode(N); }
- WeightedBidirectionalGraph(WeightedBidirectionalGraph<EdgeTypeT> &&Other)
- : NodeImpls(std::move(Other.NodeImpls)) {}
+ void addEdge(Node From, Node To, EdgeType Type,
+ StratifiedAttrs Attr = StratifiedAttrs()) {
- WeightedBidirectionalGraph<EdgeTypeT> &
- operator=(WeightedBidirectionalGraph<EdgeTypeT> &&Other) {
- NodeImpls = std::move(Other.NodeImpls);
- return *this;
- }
+ // We can't getOrCreateNode() twice in a row here since the second call may
+ // invalidate the reference returned from the first call
+ getOrCreateNode(From);
+ auto &ToEdges = getOrCreateNode(To);
+ auto &FromEdges = getOrCreateNode(From);
- Node addNode() {
- auto Index = NodeImpls.size();
- auto NewNode = Node(Index);
- NodeImpls.push_back(NodeImpl());
- return NewNode;
+ FromEdges.push_back(Edge{Attr, Type, To});
+ ToEdges.push_back(Edge{Attr, flipWeight(Type), From});
}
- void addEdge(Node From, Node To, const EdgeTypeT &Weight,
- const EdgeTypeT &ReverseWeight) {
- assert(inbounds(From));
- assert(inbounds(To));
- auto &FromNode = getNode(From);
- auto &ToNode = getNode(To);
- FromNode.Edges.push_back(Edge(Weight, To));
- ToNode.Edges.push_back(Edge(ReverseWeight, From));
+ iterator_range<const_edge_iterator> edgesFor(Node N) const {
+ auto Edges = getNode(N);
+ assert(Edges != nullptr);
+ return make_range(Edges->begin(), Edges->end());
}
- iterator_range<EdgeIterator> edgesFor(const Node &N) const {
- const auto &Node = getNode(N);
- return make_range(EdgeIterator(Node.Edges.begin()),
- EdgeIterator(Node.Edges.end()));
+ iterator_range<const_node_iterator> nodes() const {
+ return make_range<const_node_iterator>(
+ map_iterator(NodeImpls.begin(), NodeDerefFun(nodeDeref)),
+ map_iterator(NodeImpls.end(), NodeDerefFun(nodeDeref)));
}
bool empty() const { return NodeImpls.empty(); }
std::size_t size() const { return NodeImpls.size(); }
-
- /// Gets an arbitrary node in the graph as a starting point for traversal.
- Node getEntryNode() {
- assert(inbounds(StartNode));
- return StartNode;
- }
};
-
-typedef WeightedBidirectionalGraph<std::pair<EdgeType, StratifiedAttrs>> GraphT;
-typedef DenseMap<Value *, GraphT::Node> NodeMapT;
}
//===----------------------------------------------------------------------===//
@@ -667,9 +611,6 @@ static StratifiedAttr argNumberToAttr(un
/// Given a Value, potentially return which StratifiedAttr it maps to.
static Optional<StratifiedAttr> valueToAttr(Value *Val);
-/// Gets the inverse of a given EdgeType.
-static EdgeType flipWeight(EdgeType Initial);
-
/// Gets edges of the given Instruction*, writing them to the SmallVector*.
static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &,
const TargetLibraryInfo &);
@@ -685,7 +626,7 @@ static Level directionOfEdgeType(EdgeTyp
/// Builds the graph needed for constructing the StratifiedSets for the
/// given function
static void buildGraphFrom(CFLAAResult &, Function *,
- SmallVectorImpl<Value *> &, NodeMapT &, GraphT &,
+ SmallVectorImpl<Value *> &, CFLGraph &,
const TargetLibraryInfo &);
/// Gets the edges of a ConstantExpr as if it was an Instruction. This function
@@ -702,8 +643,8 @@ static void constexprToEdges(CFLAAResult
/// addInstructionToGraph would add both the `load` and `getelementptr`
/// instructions to the graph appropriately.
static void addInstructionToGraph(CFLAAResult &, Instruction &,
- SmallVectorImpl<Value *> &, NodeMapT &,
- GraphT &, const TargetLibraryInfo &);
+ SmallVectorImpl<Value *> &, CFLGraph &,
+ const TargetLibraryInfo &);
/// Determines whether it would be pointless to add the given Value to our sets.
static bool canSkipAddingToSets(Value *Val);
@@ -777,18 +718,6 @@ static StratifiedAttr argNumberToAttr(un
return 1 << (ArgNum + AttrFirstArgIndex);
}
-static EdgeType flipWeight(EdgeType Initial) {
- switch (Initial) {
- case EdgeType::Assign:
- return EdgeType::Assign;
- case EdgeType::Dereference:
- return EdgeType::Reference;
- case EdgeType::Reference:
- return EdgeType::Dereference;
- }
- llvm_unreachable("Incomplete coverage of EdgeType enum");
-}
-
static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst,
SmallVectorImpl<Edge> &Output,
const TargetLibraryInfo &TLI) {
@@ -851,18 +780,8 @@ static void constexprToEdges(CFLAAResult
static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst,
SmallVectorImpl<Value *> &ReturnedValues,
- NodeMapT &Map, GraphT &Graph,
+ CFLGraph &Graph,
const TargetLibraryInfo &TLI) {
- const auto findOrInsertNode = [&Map, &Graph](Value *Val) {
- auto Pair = Map.insert(std::make_pair(Val, GraphT::Node()));
- auto &Iter = Pair.first;
- if (Pair.second) {
- auto NewNode = Graph.addNode();
- Iter->second = NewNode;
- }
- return Iter->second;
- };
-
// We don't want the edges of most "return" instructions, but we *do* want
// to know what can be returned.
if (isa<ReturnInst>(&Inst))
@@ -880,17 +799,12 @@ static void addInstructionToGraph(CFLAAR
auto MaybeVal = getTargetValue(&Inst);
assert(MaybeVal.hasValue());
auto *Target = *MaybeVal;
- findOrInsertNode(Target);
+ Graph.addNode(Target);
return;
}
- auto addEdgeToGraph = [&](const Edge &E) {
- auto To = findOrInsertNode(E.To);
- auto From = findOrInsertNode(E.From);
- auto FlippedWeight = flipWeight(E.Weight);
- auto Attrs = E.AdditionalAttrs;
- Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs),
- std::make_pair(FlippedWeight, Attrs));
+ auto addEdgeToGraph = [&Graph](const Edge &E) {
+ Graph.addEdge(E.From, E.To, E.Weight, E.AdditionalAttrs);
};
SmallVector<ConstantExpr *, 4> ConstantExprs;
@@ -911,13 +825,12 @@ static void addInstructionToGraph(CFLAAR
static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn,
SmallVectorImpl<Value *> &ReturnedValues,
- NodeMapT &Map, GraphT &Graph,
- const TargetLibraryInfo &TLI) {
+ CFLGraph &Graph, const TargetLibraryInfo &TLI) {
// (N.B. We may remove graph construction entirely, because it doesn't really
// buy us much.)
for (auto &Bb : Fn->getBasicBlockList())
for (auto &Inst : Bb.getInstList())
- addInstructionToGraph(Analysis, Inst, ReturnedValues, Map, Graph, TLI);
+ addInstructionToGraph(Analysis, Inst, ReturnedValues, Graph, TLI);
}
static bool canSkipAddingToSets(Value *Val) {
@@ -943,74 +856,56 @@ static bool canSkipAddingToSets(Value *V
// Builds the graph + StratifiedSets for a function.
CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
- NodeMapT Map;
- GraphT Graph;
+ CFLGraph Graph;
SmallVector<Value *, 4> ReturnedValues;
- buildGraphFrom(*this, Fn, ReturnedValues, Map, Graph, TLI);
-
- DenseMap<GraphT::Node, Value *> NodeValueMap;
- NodeValueMap.reserve(Map.size());
- for (const auto &Pair : Map)
- NodeValueMap.insert(std::make_pair(Pair.second, Pair.first));
-
- const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) {
- auto ValIter = NodeValueMap.find(Node);
- assert(ValIter != NodeValueMap.end());
- return ValIter->second;
- };
+ buildGraphFrom(*this, Fn, ReturnedValues, Graph, TLI);
StratifiedSetsBuilder<Value *> Builder;
- SmallVector<GraphT::Node, 16> Worklist;
+ SmallVector<Value *, 16> Worklist;
SmallPtrSet<Value *, 16> Globals;
- for (auto &Pair : Map) {
- Worklist.clear();
- auto *Value = Pair.first;
- Builder.add(Value);
- auto InitialNode = Pair.second;
- Worklist.push_back(InitialNode);
- while (!Worklist.empty()) {
- auto Node = Worklist.pop_back_val();
- auto *CurValue = findValueOrDie(Node);
- if (canSkipAddingToSets(CurValue))
- continue;
+ for (auto Node : Graph.nodes())
+ Worklist.push_back(Node);
+
+ while (!Worklist.empty()) {
+ auto *CurValue = Worklist.pop_back_val();
+ Builder.add(CurValue);
+ if (canSkipAddingToSets(CurValue))
+ continue;
+
+ if (isa<GlobalValue>(CurValue))
+ Globals.insert(CurValue);
- if (isa<GlobalValue>(CurValue))
- Globals.insert(CurValue);
+ for (const auto &Edge : Graph.edgesFor(CurValue)) {
+ auto Label = Edge.Type;
+ auto *OtherValue = Edge.Other;
- for (const auto &EdgeTuple : Graph.edgesFor(Node)) {
- auto Weight = std::get<0>(EdgeTuple);
- auto Label = Weight.first;
- auto &OtherNode = std::get<1>(EdgeTuple);
- auto *OtherValue = findValueOrDie(OtherNode);
-
- if (canSkipAddingToSets(OtherValue))
- continue;
- if (isa<GlobalValue>(OtherValue))
- Globals.insert(OtherValue);
-
- bool Added;
- switch (directionOfEdgeType(Label)) {
- case Level::Above:
- Added = Builder.addAbove(CurValue, OtherValue);
- break;
- case Level::Below:
- Added = Builder.addBelow(CurValue, OtherValue);
- break;
- case Level::Same:
- Added = Builder.addWith(CurValue, OtherValue);
- break;
- }
-
- auto Aliasing = Weight.second;
- Builder.noteAttributes(CurValue, Aliasing);
- Builder.noteAttributes(OtherValue, Aliasing);
+ if (canSkipAddingToSets(OtherValue))
+ continue;
+ if (isa<GlobalValue>(OtherValue))
+ Globals.insert(OtherValue);
- if (Added)
- Worklist.push_back(OtherNode);
+ bool Added;
+ switch (directionOfEdgeType(Label)) {
+ case Level::Above:
+ Added = Builder.addAbove(CurValue, OtherValue);
+ break;
+ case Level::Below:
+ Added = Builder.addBelow(CurValue, OtherValue);
+ break;
+ case Level::Same:
+ Added = Builder.addWith(CurValue, OtherValue);
+ break;
}
+
+ auto Aliasing = Edge.Attr;
+ Builder.noteAttributes(CurValue, Aliasing);
+ Builder.noteAttributes(OtherValue, Aliasing);
+
+ if (Added)
+ Worklist.push_back(OtherValue);
}
}
More information about the llvm-commits
mailing list