]> granicus.if.org Git - llvm/commitdiff
[CFLAA] Ignore non-pointers, move Attrs to graph nodes.
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Wed, 15 Jun 2016 20:43:41 +0000 (20:43 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Wed, 15 Jun 2016 20:43:41 +0000 (20:43 +0000)
This patch makes CFLAA ignore non-pointer values, since we can now
sanely do that with the escaping/unknown attributes. Additionally,
StratifiedAttrs make more sense to sit on nodes than edges (since
they're properties of values, and ultimately end up on the nodes of
StratifiedSets). So, this patch puts said attributes on nodes.

Patch by Jia Chen.

Differential Revision: http://reviews.llvm.org/D21387

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272833 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFLAliasAnalysis.cpp

index 8d88986ac19904a91707c2ad42db8628a3fe8aae..ac918dcf0c8eecd74e1e3a2c6bb248dd803f9fe2 100644 (file)
@@ -132,13 +132,18 @@ class CFLGraph {
   typedef Value *Node;
 
   struct Edge {
-    StratifiedAttrs Attr;
     EdgeType Type;
     Node Other;
   };
 
   typedef std::vector<Edge> EdgeList;
-  typedef DenseMap<Node, EdgeList> NodeMap;
+
+  struct NodeInfo {
+    EdgeList Edges;
+    StratifiedAttrs Attr;
+  };
+
+  typedef DenseMap<Node, NodeInfo> NodeMap;
   NodeMap NodeImpls;
 
   // Gets the inverse of a given EdgeType.
@@ -154,13 +159,13 @@ class CFLGraph {
     llvm_unreachable("Incomplete coverage of EdgeType enum");
   }
 
-  const EdgeList *getNode(Node N) const {
+  const NodeInfo *getNode(Node N) const {
     auto Itr = NodeImpls.find(N);
     if (Itr == NodeImpls.end())
       return nullptr;
     return &Itr->second;
   }
-  EdgeList *getNode(Node N) {
+  NodeInfo *getNode(Node N) {
     auto Itr = NodeImpls.find(N);
     if (Itr == NodeImpls.end())
       return nullptr;
@@ -177,24 +182,37 @@ public:
       const_node_iterator;
 
   bool addNode(Node N) {
-    return NodeImpls.insert(std::make_pair(N, EdgeList())).second;
+    return NodeImpls.insert(std::make_pair(N, NodeInfo{EdgeList(), AttrNone}))
+        .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);
+  void addAttr(Node N, StratifiedAttrs Attr) {
+    auto *Info = getNode(N);
+    assert(Info != nullptr);
+    Info->Attr |= Attr;
+  }
+
+  void addEdge(Node From, Node To, EdgeType Type) {
+    auto *FromInfo = getNode(From);
+    assert(FromInfo != nullptr);
+    auto *ToInfo = getNode(To);
+    assert(ToInfo != nullptr);
 
-    FromEdges->push_back(Edge{Attr, Type, To});
-    ToEdges->push_back(Edge{Attr, flipWeight(Type), From});
+    FromInfo->Edges.push_back(Edge{Type, To});
+    ToInfo->Edges.push_back(Edge{flipWeight(Type), From});
+  }
+
+  StratifiedAttrs attrFor(Node N) const {
+    auto *Info = getNode(N);
+    assert(Info != nullptr);
+    return Info->Attr;
   }
 
   iterator_range<const_edge_iterator> edgesFor(Node N) const {
-    auto Edges = getNode(N);
-    assert(Edges != nullptr);
-    return make_range(Edges->begin(), Edges->end());
+    auto *Info = getNode(N);
+    assert(Info != nullptr);
+    auto &Edges = Info->Edges;
+    return make_range(Edges.begin(), Edges.end());
   }
 
   iterator_range<const_node_iterator> nodes() const {
@@ -234,11 +252,18 @@ class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
         visitConstantExpr(CExpr);
   }
 
-  void addEdge(Value *From, Value *To, EdgeType Type, StratifiedAttrs Attr) {
+  void addNodeWithAttr(Value *Val, StratifiedAttrs Attr) {
+    addNode(Val);
+    Graph.addAttr(Val, Attr);
+  }
+
+  void addEdge(Value *From, Value *To, EdgeType Type) {
+    if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
+      return;
     addNode(From);
     if (To != From)
       addNode(To);
-    Graph.addEdge(From, To, Type, Attr);
+    Graph.addEdge(From, To, Type);
   }
 
 public:
@@ -254,46 +279,46 @@ public:
 
   void visitPtrToIntInst(PtrToIntInst &Inst) {
     auto *Ptr = Inst.getOperand(0);
-    addEdge(Ptr, &Inst, EdgeType::Assign, AttrEscaped);
+    addNodeWithAttr(Ptr, AttrEscaped);
   }
 
   void visitIntToPtrInst(IntToPtrInst &Inst) {
     auto *Ptr = &Inst;
-    addEdge(Ptr, Ptr, EdgeType::Assign, AttrUnknown);
+    addNodeWithAttr(Ptr, AttrUnknown);
   }
 
   void visitCastInst(CastInst &Inst) {
     auto *Src = Inst.getOperand(0);
-    addEdge(Src, &Inst, EdgeType::Assign, AttrNone);
+    addEdge(Src, &Inst, EdgeType::Assign);
   }
 
   void visitBinaryOperator(BinaryOperator &Inst) {
     auto *Op1 = Inst.getOperand(0);
     auto *Op2 = Inst.getOperand(1);
-    addEdge(Op1, &Inst, EdgeType::Assign, AttrNone);
-    addEdge(Op2, &Inst, EdgeType::Assign, AttrNone);
+    addEdge(Op1, &Inst, EdgeType::Assign);
+    addEdge(Op2, &Inst, EdgeType::Assign);
   }
 
   void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
     auto *Ptr = Inst.getPointerOperand();
     auto *Val = Inst.getNewValOperand();
-    addEdge(Ptr, Val, EdgeType::Dereference, AttrNone);
+    addEdge(Ptr, Val, EdgeType::Dereference);
   }
 
   void visitAtomicRMWInst(AtomicRMWInst &Inst) {
     auto *Ptr = Inst.getPointerOperand();
     auto *Val = Inst.getValOperand();
-    addEdge(Ptr, Val, EdgeType::Dereference, AttrNone);
+    addEdge(Ptr, Val, EdgeType::Dereference);
   }
 
   void visitPHINode(PHINode &Inst) {
     for (Value *Val : Inst.incoming_values())
-      addEdge(Val, &Inst, EdgeType::Assign, AttrNone);
+      addEdge(Val, &Inst, EdgeType::Assign);
   }
 
   void visitGetElementPtrInst(GetElementPtrInst &Inst) {
     auto *Op = Inst.getPointerOperand();
-    addEdge(Op, &Inst, EdgeType::Assign, AttrNone);
+    addEdge(Op, &Inst, EdgeType::Assign);
   }
 
   void visitSelectInst(SelectInst &Inst) {
@@ -304,8 +329,8 @@ public:
 
     auto *TrueVal = Inst.getTrueValue();
     auto *FalseVal = Inst.getFalseValue();
-    addEdge(TrueVal, &Inst, EdgeType::Assign, AttrNone);
-    addEdge(FalseVal, &Inst, EdgeType::Assign, AttrNone);
+    addEdge(TrueVal, &Inst, EdgeType::Assign);
+    addEdge(FalseVal, &Inst, EdgeType::Assign);
   }
 
   void visitAllocaInst(AllocaInst &Inst) { Graph.addNode(&Inst); }
@@ -313,13 +338,13 @@ public:
   void visitLoadInst(LoadInst &Inst) {
     auto *Ptr = Inst.getPointerOperand();
     auto *Val = &Inst;
-    addEdge(Val, Ptr, EdgeType::Reference, AttrNone);
+    addEdge(Val, Ptr, EdgeType::Reference);
   }
 
   void visitStoreInst(StoreInst &Inst) {
     auto *Ptr = Inst.getPointerOperand();
     auto *Val = Inst.getValueOperand();
-    addEdge(Ptr, Val, EdgeType::Dereference, AttrNone);
+    addEdge(Ptr, Val, EdgeType::Dereference);
   }
 
   void visitVAArgInst(VAArgInst &Inst) {
@@ -329,8 +354,7 @@ public:
     //  2. Increments (stores to) *Ptr by some target-specific amount.
     // For now, we'll handle this like a landingpad instruction (by placing the
     // result in its own group, and having that group alias externals).
-    auto *Val = &Inst;
-    addEdge(Val, Val, EdgeType::Assign, AttrUnknown);
+    addNodeWithAttr(&Inst, AttrUnknown);
   }
 
   static bool isFunctionExternal(Function *Fn) {
@@ -374,9 +398,8 @@ public:
     EdgeType Weight;
 
     // Whether we aliased any external values along the way that may be
-    // invisible to the analysis (i.e. landingpad for exceptions, calls for
-    // interprocedural analysis, etc.)
-    StratifiedAttrs AdditionalAttrs;
+    // invisible to the analysis
+    StratifiedAttrs FromAttrs, ToAttrs;
   };
 
   bool
@@ -424,25 +447,23 @@ public:
         auto &ParamInfo = Parameters[I];
         auto &ArgVal = Arguments[I];
         bool AddEdge = false;
-        StratifiedAttrs Externals;
+        StratifiedAttrs RetAttrs, ParamAttrs;
         for (unsigned X = 0, XE = RetVals.size(); X != XE; ++X) {
           auto MaybeInfo = Sets.find(RetVals[X]);
           if (!MaybeInfo.hasValue())
             return false;
 
           auto &RetInfo = *MaybeInfo;
-          auto RetAttrs = Sets.getLink(RetInfo.Index).Attrs;
-          auto ParamAttrs = Sets.getLink(ParamInfo.Index).Attrs;
+          RetAttrs |= Sets.getLink(RetInfo.Index).Attrs;
+          ParamAttrs |= Sets.getLink(ParamInfo.Index).Attrs;
           auto MaybeRelation =
               getIndexRelation(Sets, ParamInfo.Index, RetInfo.Index);
-          if (MaybeRelation.hasValue()) {
+          if (MaybeRelation.hasValue())
             AddEdge = true;
-            Externals |= RetAttrs | ParamAttrs;
-          }
         }
         if (AddEdge)
           Output.push_back(
-              Edge{FuncValue, ArgVal, EdgeType::Assign, Externals});
+              Edge{FuncValue, ArgVal, EdgeType::Assign, RetAttrs, ParamAttrs});
       }
 
       if (Parameters.size() != Arguments.size())
@@ -468,15 +489,18 @@ public:
           if (!MaybeRelation.hasValue())
             continue;
 
-          auto NewAttrs = SubAttrs | MainAttrs;
-          Output.push_back(Edge{MainVal, SubVal, EdgeType::Assign, NewAttrs});
+          Output.push_back(
+              Edge{MainVal, SubVal, EdgeType::Assign, MainAttrs, SubAttrs});
         }
       }
     }
 
     // Commit all edges in Output to CFLGraph
-    for (const auto &Edge : Output)
-      addEdge(Edge.From, Edge.To, Edge.Weight, Edge.AdditionalAttrs);
+    for (const auto &Edge : Output) {
+      addEdge(Edge.From, Edge.To, Edge.Weight);
+      Graph.addAttr(Edge.From, Edge.FromAttrs);
+      Graph.addAttr(Edge.To, Edge.ToAttrs);
+    }
 
     return true;
   }
@@ -511,13 +535,14 @@ public:
     // anything, too (unless the result is marked noalias).
     if (!CS.onlyReadsMemory())
       for (Value *V : CS.args()) {
-        Escapes.insert(V);
+        if (V->getType()->isPointerTy())
+          Escapes.insert(V);
       }
 
     if (!Inst->getType()->isVoidTy()) {
       auto *Fn = CS.getCalledFunction();
       if (Fn == nullptr || !Fn->doesNotAlias(0))
-        addEdge(Inst, Inst, EdgeType::Assign, AttrUnknown);
+        Graph.addAttr(Inst, AttrUnknown);
     }
   }
 
@@ -528,40 +553,40 @@ public:
   void visitExtractElementInst(ExtractElementInst &Inst) {
     auto *Ptr = Inst.getVectorOperand();
     auto *Val = &Inst;
-    addEdge(Val, Ptr, EdgeType::Reference, AttrNone);
+    addEdge(Val, Ptr, EdgeType::Reference);
   }
 
   void visitInsertElementInst(InsertElementInst &Inst) {
     auto *Vec = Inst.getOperand(0);
     auto *Val = Inst.getOperand(1);
-    addEdge(Vec, &Inst, EdgeType::Assign, AttrNone);
-    addEdge(&Inst, Val, EdgeType::Dereference, AttrNone);
+    addEdge(Vec, &Inst, EdgeType::Assign);
+    addEdge(&Inst, Val, EdgeType::Dereference);
   }
 
   void visitLandingPadInst(LandingPadInst &Inst) {
     // Exceptions come from "nowhere", from our analysis' perspective.
     // So we place the instruction its own group, noting that said group may
     // alias externals
-    addEdge(&Inst, &Inst, EdgeType::Assign, AttrUnknown);
+    addNodeWithAttr(&Inst, AttrUnknown);
   }
 
   void visitInsertValueInst(InsertValueInst &Inst) {
     auto *Agg = Inst.getOperand(0);
     auto *Val = Inst.getOperand(1);
-    addEdge(Agg, &Inst, EdgeType::Assign, AttrNone);
-    addEdge(&Inst, Val, EdgeType::Dereference, AttrNone);
+    addEdge(Agg, &Inst, EdgeType::Assign);
+    addEdge(&Inst, Val, EdgeType::Dereference);
   }
 
   void visitExtractValueInst(ExtractValueInst &Inst) {
     auto *Ptr = Inst.getAggregateOperand();
-    addEdge(&Inst, Ptr, EdgeType::Reference, AttrNone);
+    addEdge(&Inst, Ptr, EdgeType::Reference);
   }
 
   void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
     auto *From1 = Inst.getOperand(0);
     auto *From2 = Inst.getOperand(1);
-    addEdge(From1, &Inst, EdgeType::Assign, AttrNone);
-    addEdge(From2, &Inst, EdgeType::Assign, AttrNone);
+    addEdge(From1, &Inst, EdgeType::Assign);
+    addEdge(From2, &Inst, EdgeType::Assign);
   }
 
   void visitConstantExpr(ConstantExpr *CE) {
@@ -603,8 +628,10 @@ class CFLGraphBuilder {
   }
 
   void addArgumentToGraph(Argument &Arg) {
-    Graph.addNode(&Arg);
-    ExternalValues.insert(&Arg);
+    if (Arg.getType()->isPointerTy()) {
+      Graph.addNode(&Arg);
+      ExternalValues.insert(&Arg);
+    }
   }
 
   // Given an Instruction, this will add it to the graph, along with any
@@ -777,6 +804,9 @@ CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
     if (canSkipAddingToSets(CurValue))
       continue;
 
+    auto Attr = Graph.attrFor(CurValue);
+    SetBuilder.noteAttributes(CurValue, Attr);
+
     for (const auto &Edge : Graph.edgesFor(CurValue)) {
       auto Label = Edge.Type;
       auto *OtherValue = Edge.Other;
@@ -797,10 +827,6 @@ CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
         break;
       }
 
-      auto Aliasing = Edge.Attr;
-      SetBuilder.noteAttributes(CurValue, Aliasing);
-      SetBuilder.noteAttributes(OtherValue, Aliasing);
-
       if (Added)
         Worklist.push_back(OtherValue);
     }
@@ -861,6 +887,9 @@ AliasResult CFLAAResult::query(const MemoryLocation &LocA,
   auto *ValA = const_cast<Value *>(LocA.Ptr);
   auto *ValB = const_cast<Value *>(LocB.Ptr);
 
+  if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
+    return NoAlias;
+
   Function *Fn = nullptr;
   auto MaybeFnA = parentFunctionOfValue(ValA);
   auto MaybeFnB = parentFunctionOfValue(ValB);