[llvm-commits] [dragonegg] r154003 - /dragonegg/trunk/src/Aliasing.cpp

Duncan Sands baldrick at free.fr
Wed Apr 4 01:24:58 PDT 2012


Author: baldrick
Date: Wed Apr  4 03:24:57 2012
New Revision: 154003

URL: http://llvm.org/viewvc/llvm-project?rev=154003&view=rev
Log:
Invert the policy for converting GCC's tbaa info to LLVM metadata:
rather than keeping the nodes at the top of GCC's DAG, keep those
at the bottom (the leaves) since they represent the scalar types.

Modified:
    dragonegg/trunk/src/Aliasing.cpp

Modified: dragonegg/trunk/src/Aliasing.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Aliasing.cpp?rev=154003&r1=154002&r2=154003&view=diff
==============================================================================
--- dragonegg/trunk/src/Aliasing.cpp (original)
+++ dragonegg/trunk/src/Aliasing.cpp Wed Apr  4 03:24:57 2012
@@ -29,7 +29,6 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Metadata.h"
-#include "llvm/ADT/EquivalenceClasses.h"
 
 // System headers
 #include <gmp.h>
@@ -89,74 +88,68 @@
 
   // The difficulty here is that GCC's alias sets are the nodes of a directed
   // acyclic graph (DAG) rooted at 0, and in complicated cases it really is a
-  // DAG and not a tree.  On the other hand, LLVM requires TBAA nodes to form
-  // a tree.  In short we need to come up with a tree and a graph map (i.e. a
-  // map that takes nodes to nodes and edges to edges) from GCC's DAG to this
-  // tree.  An additional difficulty is that we don't actually know the edges
-  // in the DAG: GCC's alias analysis interface does not expose them.  All that
-  // we have is alias_set_subset_of(s, t) which returns true iff there is a path
-  // from t to s in the DAG. Finally, we don't know the nodes of the DAG either!
-  // We only discover them progressively as we convert functions.
-  // For the moment we take a very simple approach: the TBAA tree will be only
-  // one level deep: a list of nodes hanging off the root node.  This is not a
-  // good choice in general: it is perfectly possible for a huge alias DAG to
-  // result in just one node hanging off the root.  But it is simple.  We keep
-  // a collection of disjoint sets of DAG nodes seen so far.  The sets represent
-  // the equivalence relation generated by requiring A and B to be in the same
-  // equivalence class if there is a path from A to B or from B to A.
-  typedef EquivalenceClasses<alias_set_type> DisjointSets;
-  static DisjointSets Nodes; // The TBAA nodes hanging off the root.
+  // DAG and not a tree.  This is due to record types: the DAG has a node for
+  // each record type with, for every field, an edge from the node to the node
+  // for the field's type.  As a result the leaves of the DAG are usually scalar
+  // types, with an incoming edge from every record type with a field with that
+  // scalar type.  On the other hand, LLVM requires TBAA nodes to form a tree.
+  // In short we need to come up with a tree and a graph map (i.e. a map that
+  // takes nodes to nodes and edges to edges) from GCC's DAG to this tree.  (An
+  // alternative is to complicate LLVM so that it too uses DAGs for TBAA).  An
+  // additional difficulty is that we don't actually know the edges in the DAG:
+  // GCC's alias analysis interface does not expose them.  All that we have is
+  // alias_set_subset_of(s, t) which returns true iff there is a path from t to
+  // s in the DAG.  Finally, we don't know the nodes of the DAG either!  We only
+  // discover them progressively as we convert functions.
+  // For the moment we take a very simple approach: we only use the leaf nodes
+  // of GCC's DAG.  This means that we do a good job for scalars and a poor job
+  // for record types, including complex types.
   static std::map<alias_set_type, MDNode*> NodeTags; // Node -> metadata map.
+  static SmallVector<alias_set_type, 8> LeafNodes;   // Current set of leaves.
 
-  // If alias_set was already seen then return the previously computed metadata.
-  DisjointSets::member_iterator MI = Nodes.findLeader(alias_set);
-  if (MI != Nodes.member_end()) {
-    assert(NodeTags.find(*MI) != NodeTags.end() && "Node has no metadata!");
-    return NodeTags[*MI];
+  std::map<alias_set_type, MDNode*>::iterator I = NodeTags.find(alias_set);
+  if (I != NodeTags.end())
+    return I->second;
+
+  if (LeafNodes.empty())
+    // Check for a GCC special case: a node can have an edge to the root node.
+    // This is handled automatically (below) except when there are not yet any
+    // known leaf nodes.
+    if (alias_set_subset_of(0, alias_set)) {
+      NodeTags[alias_set] = 0;
+      return 0;
+    }
+
+  // If there is a path from this node to any leaf node then it is not a leaf
+  // node and can be discarded.
+  for (unsigned i = 0, e = LeafNodes.size(); i != e; ++i)
+    if (alias_set_subset_of(LeafNodes[i], alias_set)) {
+      NodeTags[alias_set] = 0;
+      return 0;
+    }
+  assert(!alias_set_subset_of(0, alias_set) && "'May alias' not transitive?");
+
+  // If there is a path from any leaf node to this one then no longer consider
+  // that node to be a leaf.
+  for (unsigned i = LeafNodes.size(); i; ) {
+    alias_set_type leaf_set = LeafNodes[--i];
+    if (alias_set_subset_of(alias_set, leaf_set)) {
+      LeafNodes.erase(LeafNodes.begin() + i);
+      MDNode *&LeafTag = NodeTags[leaf_set];
+      // It would be neat to strip the tbaa tag from any instructions using it
+      // but it is simpler to just replace it with the root tag everywhere.
+      LeafTag->replaceAllUsesWith(getTBAARoot());
+      LeafTag = 0;
+    }
   }
 
-  // Examine all previously seen nodes and determine which of them, if any, may
-  // alias alias_set.
-  SmallVector<DisjointSets::member_iterator, 8> MayAlias;
-  for (DisjointSets::iterator I = Nodes.begin(); I != Nodes.end(); ++I)
-    for (DisjointSets::member_iterator MI = Nodes.member_begin(I),
-         ME = Nodes.member_end(); MI != ME; ++MI)
-      if (alias_sets_conflict_p(alias_set, *MI)) {
-        // May alias - remember this and move on to the next node.
-        MayAlias.push_back(Nodes.findLeader(I));
-        break;
-      }
-
-  // If none of the existing nodes may be aliased, then create a new node.
-  if (MayAlias.empty()) {
-    // Create metadata describing a new node hanging off root.  The name doesn't
-    // matter much but needs to be unique for the compilation unit.
-    std::string TreeName = ("alias set " + Twine(alias_set) + ": " +
-      getDescriptiveName(TYPE_CANONICAL(main_type(t)))).str();
-    Value *Ops[2] = { MDString::get(Context, TreeName), getTBAARoot() };
-    MDNode *AliasTag = MDNode::get(Context, Ops);
-    NodeTags[alias_set] = AliasTag;
-    // Remember the new node in the equivalence relation.
-    Nodes.insert(alias_set);
-    return AliasTag;
-  }
-
-  // Merge all of the nodes that may alias alias_set into one node.
-  DisjointSets::member_iterator TheChosenOne = MayAlias[0];
-  MDNode *TheChosenTag = NodeTags[*TheChosenOne];
-  for (unsigned i = 1, e = MayAlias.size(); i != e; ++i) {
-    DisjointSets::member_iterator Leader = MayAlias[i];
-    MDNode *AliasTag = NodeTags[*Leader];
-    // Use the chosen node's TBAA metadata instead of this node's.
-    AliasTag->replaceAllUsesWith(TheChosenTag);
-    NodeTags.erase(*Leader);
-    // Merge this node into the chosen node.
-    Leader = Nodes.unionSets(TheChosenOne, Leader);
-    assert(Leader == TheChosenOne && "Union mutated chosen leader!");
-  }
-  // Add alias_set itself to the merged node.
-  Nodes.unionSets(TheChosenOne, Nodes.findLeader(Nodes.insert(alias_set)));
-
-  // Finally, return the metadata for the merged node.
-  return TheChosenTag;
+  // Create metadata describing the new node hanging off root.  The name doesn't
+  // matter much but needs to be unique for the compilation unit.
+  std::string TreeName = ("alias set " + Twine(alias_set) + ": " +
+    getDescriptiveName(TYPE_CANONICAL(main_type(t)))).str();
+  Value *Ops[2] = { MDString::get(Context, TreeName), getTBAARoot() };
+  MDNode *AliasTag = MDNode::get(Context, Ops);
+  NodeTags[alias_set] = AliasTag;
+  LeafNodes.push_back(alias_set);
+  return AliasTag;
 }





More information about the llvm-commits mailing list