[PATCH] D21262: [CFLAA] Tag actual arguments as AttrEscaped instead of AttrUnknown
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 13 17:19:56 PDT 2016
george.burgess.iv added inline comments.
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:132
@@ +131,3 @@
+class CFLGraph {
+private:
+ typedef Value *Node;
----------------
Not done
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:158-212
@@ -153,4 +157,57 @@
- Edge(Value *From, Value *To, EdgeType W, StratifiedAttrs A)
- : From(From), To(To), Weight(W), AdditionalAttrs(A) {}
+ const EdgeList *getNode(Node N) const {
+ auto Itr = NodeImpls.find(N);
+ if (Itr == NodeImpls.end())
+ return nullptr;
+ return &Itr->second;
+ }
+ EdgeList *getNode(Node N) {
+ auto Itr = NodeImpls.find(N);
+ if (Itr == NodeImpls.end())
+ return nullptr;
+ return &Itr->second;
+ }
+
+ static Node nodeDeref(const NodeMap::value_type &P) { return P.first; }
+ typedef std::pointer_to_unary_function<const NodeMap::value_type &, Node>
+ NodeDerefFun;
+
+public:
+ typedef EdgeList::const_iterator const_edge_iterator;
+ typedef mapped_iterator<NodeMap::const_iterator, NodeDerefFun>
+ const_node_iterator;
+
+ CFLGraph() = default;
+ CFLGraph(CFLGraph &&) = default;
+ CFLGraph &operator=(CFLGraph &&) = default;
+
+ bool addNode(Node N) {
+ return NodeImpls.insert(std::make_pair(N, EdgeList())).second;
+ }
+
+ void addEdge(Node From, Node To, EdgeType Type,
+ StratifiedAttrs Attr = StratifiedAttrs()) {
+ auto FromEdges = getNode(From);
+ assert(FromEdges != nullptr);
+ auto ToEdges = getNode(To);
+ assert(ToEdges != nullptr);
+
+ FromEdges->push_back(Edge{Attr, Type, To});
+ ToEdges->push_back(Edge{Attr, flipWeight(Type), 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<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(); }
};
----------------
If we see the flexibility being useful in the future, then I'm fine with it; I was just wondering if this was intentional or not.
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:180
@@ +179,3 @@
+
+ CFLGraph() = default;
+ CFLGraph(CFLGraph &&) = default;
----------------
Looks like they might have slipped by. :)
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:237
@@ +236,3 @@
+ Externals.insert(Val);
+ else if (auto CExpr = dyn_cast<ConstantExpr>(Val)) {
+ if (hasUsefulEdges(CExpr))
----------------
The former, please.
Generally, the style rule is "useless braces shouldn't exist, unless they help readability somehow."
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:372
@@ +371,3 @@
+ // Encodes the notion of a "use"
+ struct Edge {
+ // Which value the edge is coming from
----------------
I don't see what that has to do with the comment style, but I agree that it probably doesn't matter.
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:517
@@ +516,3 @@
+ // readonly or readnone), and that the result could alias just about
+ // anything, too (unless the result is marked noalias).
+ if (!CS.onlyReadsMemory())
----------------
Sounds good.
(Also, it looks like `CS.onlyReadsMemory()` will check for callsite attributes (e.g. readonly/readnone) for us, so you picked the better option there, I think.)
================
Comment at: lib/Analysis/CFLAliasAnalysis.cpp:527
@@ +526,3 @@
+ auto Fn = CS.getCalledFunction();
+ if (Fn == nullptr || !Fn->doesNotAlias(0))
+ addEdge(Inst, Inst, EdgeType::Assign, AttrUnknown);
----------------
grievejia wrote:
> george.burgess.iv wrote:
> > Looks like we won't add this to the sets if `Fn->doesNotAlias(0)`.
> Which is intended: noalias return values are treated like mallocs.
Ah, I forgot that we added the nodes at the beginning of the function now -- my mistake. :)
================
Comment at: test/Analysis/CFLAliasAnalysis/attr-escape.ll:53
@@ +52,3 @@
+; CHECK: NoAlias: i32* %c, i32** %a
+define void @test_external_call_readonly(i32* %x) {
+ %a = alloca i32*, align 8
----------------
grievejia wrote:
> george.burgess.iv wrote:
> > Can we have a test for callsites marked as `readonly`, (if we currently support them) as well?
> I'm not aware that we can mark the callsite (instead of the function) readonly. How can we distinguish the two in our codes?
If you're talking about tests, `call void @foo(args) readonly` is the syntax, IIRC. It's definitely less common than just using a function-level attribute.
If you're talking about in CFLAA, I think I sort of addressed that in an earlier response.
http://reviews.llvm.org/D21262
More information about the llvm-commits
mailing list