blob: cbc37f34928695c1cae9e41418cf384c9bafcda3 [file] [log] [blame]
George Burgess IV1ca8aff2016-07-06 00:36:12 +00001//======- CFLGraph.h - Abstract stratified sets implementation. --------======//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file defines CFLGraph, an auxiliary data structure used by CFL-based
11/// alias analysis.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ANALYSIS_CFLGRAPH_H
16#define LLVM_ANALYSIS_CFLGRAPH_H
17
George Burgess IVe1919962016-07-06 00:47:21 +000018#include "AliasAnalysisSummary.h"
19#include "llvm/ADT/STLExtras.h"
George Burgess IV1ca8aff2016-07-06 00:36:12 +000020
21namespace llvm {
George Burgess IV1ca8aff2016-07-06 00:36:12 +000022namespace cflaa {
George Burgess IV1ca8aff2016-07-06 00:36:12 +000023/// Edges can be one of four "weights" -- each weight must have an inverse
24/// weight (Assign has Assign; Reference has Dereference).
25enum class EdgeType {
26 /// The weight assigned when assigning from or to a value. For example, in:
27 /// %b = getelementptr %a, 0
28 /// ...The relationships are %b assign %a, and %a assign %b. This used to be
29 /// two edges, but having a distinction bought us nothing.
30 Assign,
31
32 /// The edge used when we have an edge going from some handle to a Value.
33 /// Examples of this include:
34 /// %b = load %a (%b Dereference %a)
35 /// %b = extractelement %a, 0 (%a Dereference %b)
36 Dereference,
37
38 /// The edge used when our edge goes from a value to a handle that may have
39 /// contained it at some point. Examples:
40 /// %b = load %a (%a Reference %b)
41 /// %b = extractelement %a, 0 (%b Reference %a)
42 Reference
43};
44
45/// \brief The Program Expression Graph (PEG) of CFL analysis
46/// CFLGraph is auxiliary data structure used by CFL-based alias analysis to
47/// describe flow-insensitive pointer-related behaviors. Given an LLVM function,
48/// the main purpose of this graph is to abstract away unrelated facts and
49/// translate the rest into a form that can be easily digested by CFL analyses.
50class CFLGraph {
51 typedef Value *Node;
52
53 struct Edge {
54 EdgeType Type;
55 Node Other;
56 };
57
58 typedef std::vector<Edge> EdgeList;
59
60 struct NodeInfo {
61 EdgeList Edges;
George Burgess IVe1919962016-07-06 00:47:21 +000062 AliasAttrs Attr;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000063 };
64
65 typedef DenseMap<Node, NodeInfo> NodeMap;
66 NodeMap NodeImpls;
67
68 // Gets the inverse of a given EdgeType.
69 static EdgeType flipWeight(EdgeType Initial) {
70 switch (Initial) {
71 case EdgeType::Assign:
72 return EdgeType::Assign;
73 case EdgeType::Dereference:
74 return EdgeType::Reference;
75 case EdgeType::Reference:
76 return EdgeType::Dereference;
77 }
78 llvm_unreachable("Incomplete coverage of EdgeType enum");
79 }
80
81 const NodeInfo *getNode(Node N) const {
82 auto Itr = NodeImpls.find(N);
83 if (Itr == NodeImpls.end())
84 return nullptr;
85 return &Itr->second;
86 }
87 NodeInfo *getNode(Node N) {
88 auto Itr = NodeImpls.find(N);
89 if (Itr == NodeImpls.end())
90 return nullptr;
91 return &Itr->second;
92 }
93
94 static Node nodeDeref(const NodeMap::value_type &P) { return P.first; }
95 typedef std::pointer_to_unary_function<const NodeMap::value_type &, Node>
96 NodeDerefFun;
97
98public:
99 typedef EdgeList::const_iterator const_edge_iterator;
100 typedef mapped_iterator<NodeMap::const_iterator, NodeDerefFun>
101 const_node_iterator;
102
103 bool addNode(Node N) {
George Burgess IVe1919962016-07-06 00:47:21 +0000104 return NodeImpls
105 .insert(std::make_pair(N, NodeInfo{EdgeList(), getAttrNone()}))
106 .second;
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000107 }
108
George Burgess IVe1919962016-07-06 00:47:21 +0000109 void addAttr(Node N, AliasAttrs Attr) {
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000110 auto *Info = getNode(N);
111 assert(Info != nullptr);
112 Info->Attr |= Attr;
113 }
114
115 void addEdge(Node From, Node To, EdgeType Type) {
116 auto *FromInfo = getNode(From);
117 assert(FromInfo != nullptr);
118 auto *ToInfo = getNode(To);
119 assert(ToInfo != nullptr);
120
121 FromInfo->Edges.push_back(Edge{Type, To});
122 ToInfo->Edges.push_back(Edge{flipWeight(Type), From});
123 }
124
George Burgess IVe1919962016-07-06 00:47:21 +0000125 AliasAttrs attrFor(Node N) const {
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000126 auto *Info = getNode(N);
127 assert(Info != nullptr);
128 return Info->Attr;
129 }
130
131 iterator_range<const_edge_iterator> edgesFor(Node N) const {
132 auto *Info = getNode(N);
133 assert(Info != nullptr);
134 auto &Edges = Info->Edges;
135 return make_range(Edges.begin(), Edges.end());
136 }
137
138 iterator_range<const_node_iterator> nodes() const {
139 return make_range<const_node_iterator>(
140 map_iterator(NodeImpls.begin(), NodeDerefFun(nodeDeref)),
141 map_iterator(NodeImpls.end(), NodeDerefFun(nodeDeref)));
142 }
143
144 bool empty() const { return NodeImpls.empty(); }
145 std::size_t size() const { return NodeImpls.size(); }
146};
147}
148}
149
150#endif