[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