[llvm] r278961 - [GenericDomTree] Change GenericDomTree to use NodeRef in GraphTraits. NFC.
Vedant Kumar via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 19 16:24:38 PDT 2016
> On Aug 19, 2016, at 4:04 PM, Vedant Kumar via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Hi Tim,
>
> This commit breaks clang-3.8 and gcc 5.4.0 on linux:
>
> /root/llvm/include/llvm/Support/GenericDomTree.h:753:35: error: cannot initialize a parameter of type 'NodeType *' (aka 'clang::CFGBlock *') with an rvalue of type
> 'clang::CFGBlock **'
> if (TraitsTy::child_begin(&*I) == TraitsTy::child_end(&*I))
> ^~~
> /root/llvm/tools/clang/include/clang/Analysis/Analyses/Dominators.h:85:9: note: in instantiation of function template specialization
> 'llvm::DominatorTreeBase<clang::CFGBlock>::recalculate<clang::CFG>' requested here
> DT->recalculate(*cfg);
>
> I don't know what the policy is on supported older releases of clang, but it'd be nice to keep this working. Could you take a look?
^ Sorry, I think the versions of clang and llvm I was building with weren't in
sync. Please ignore this.
vedant
>
> thanks,
> vedant
>
>
>> On Aug 17, 2016, at 1:01 PM, Tim Shen via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>>
>> Author: timshen
>> Date: Wed Aug 17 15:01:58 2016
>> New Revision: 278961
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=278961&view=rev
>> Log:
>> [GenericDomTree] Change GenericDomTree to use NodeRef in GraphTraits. NFC.
>>
>> Summary:
>> Looking at the implementation, GenericDomTree has more specific
>> requirements on NodeRef, e.g. NodeRefObject->getParent() should compile,
>> and NodeRef should be a pointer. We can remove the pointer requirement,
>> but it seems to have little gain, given the limited use cases.
>>
>> Also changed GraphTraits<Inverse<Inverse<T>> to be more accurate.
>>
>> Reviewers: dblaikie, chandlerc
>>
>> Subscribers: llvm-commits
>>
>> Differential Revision: https://reviews.llvm.org/D23593
>>
>> Modified:
>> llvm/trunk/include/llvm/ADT/GraphTraits.h
>> llvm/trunk/include/llvm/IR/Dominators.h
>> llvm/trunk/include/llvm/Support/GenericDomTree.h
>> llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h
>> llvm/trunk/lib/IR/Dominators.cpp
>>
>> Modified: llvm/trunk/include/llvm/ADT/GraphTraits.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/GraphTraits.h?rev=278961&r1=278960&r2=278961&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ADT/GraphTraits.h (original)
>> +++ llvm/trunk/include/llvm/ADT/GraphTraits.h Wed Aug 17 15:01:58 2016
>> @@ -88,23 +88,7 @@ struct Inverse {
>>
>> // Provide a partial specialization of GraphTraits so that the inverse of an
>> // inverse falls back to the original graph.
>> -template<class T>
>> -struct GraphTraits<Inverse<Inverse<T> > > {
>> - typedef typename GraphTraits<T>::NodeType NodeType;
>> - typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
>> -
>> - static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
>> - return GraphTraits<T>::getEntryNode(G->Graph.Graph);
>> - }
>> -
>> - static ChildIteratorType child_begin(NodeType* N) {
>> - return GraphTraits<T>::child_begin(N);
>> - }
>> -
>> - static ChildIteratorType child_end(NodeType* N) {
>> - return GraphTraits<T>::child_end(N);
>> - }
>> -};
>> +template <class T> struct GraphTraits<Inverse<Inverse<T>>> : GraphTraits<T> {};
>>
>> } // End llvm namespace
>>
>>
>> Modified: llvm/trunk/include/llvm/IR/Dominators.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Dominators.h?rev=278961&r1=278960&r2=278961&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/IR/Dominators.h (original)
>> +++ llvm/trunk/include/llvm/IR/Dominators.h Wed Aug 17 15:01:58 2016
>> @@ -33,9 +33,9 @@ extern template class DomTreeNodeBase<Ba
>> extern template class DominatorTreeBase<BasicBlock>;
>>
>> extern template void Calculate<Function, BasicBlock *>(
>> - DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
>> + DominatorTreeBaseByGraphTraits<GraphTraits<BasicBlock *>> &DT, Function &F);
>> extern template void Calculate<Function, Inverse<BasicBlock *>>(
>> - DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
>> + DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT,
>> Function &F);
>>
>> typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
>>
>> Modified: llvm/trunk/include/llvm/Support/GenericDomTree.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTree.h?rev=278961&r1=278960&r2=278961&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/GenericDomTree.h (original)
>> +++ llvm/trunk/include/llvm/Support/GenericDomTree.h Wed Aug 17 15:01:58 2016
>> @@ -13,6 +13,12 @@
>> /// dominance queries on the CFG, but is fully generic w.r.t. the underlying
>> /// graph types.
>> ///
>> +/// Unlike ADT/* graph algorithms, generic dominator tree has more reuiqrement
>> +/// on the graph's NodeRef. The NodeRef should be a pointer and, depending on
>> +/// the implementation, e.g. NodeRef->getParent() return the parent node.
>> +///
>> +/// FIXME: Maybe GenericDomTree needs a TreeTraits, instead of GraphTraits.
>> +///
>> //===----------------------------------------------------------------------===//
>>
>> #ifndef LLVM_SUPPORT_GENERICDOMTREE_H
>> @@ -30,6 +36,23 @@
>>
>> namespace llvm {
>>
>> +template <class NodeT> class DominatorTreeBase;
>> +
>> +namespace detail {
>> +
>> +template <typename GT> struct DominatorTreeBaseTraits {
>> + static_assert(std::is_pointer<typename GT::NodeRef>::value,
>> + "Currently NodeRef must be a pointer type.");
>> + using type = DominatorTreeBase<
>> + typename std::remove_pointer<typename GT::NodeRef>::type>;
>> +};
>> +
>> +} // End namespace detail
>> +
>> +template <typename GT>
>> +using DominatorTreeBaseByGraphTraits =
>> + typename detail::DominatorTreeBaseTraits<GT>::type;
>> +
>> /// \brief Base class that other, more interesting dominator analyses
>> /// inherit from.
>> template <class NodeT> class DominatorBase {
>> @@ -62,7 +85,6 @@ public:
>> bool isPostDominator() const { return IsPostDominators; }
>> };
>>
>> -template <class NodeT> class DominatorTreeBase;
>> struct PostDominatorTree;
>>
>> /// \brief Base class for the actual dominator tree node.
>> @@ -177,8 +199,7 @@ void PrintDomTree(const DomTreeNodeBase<
>>
>> // The calculate routine is provided in a separate header but referenced here.
>> template <class FuncT, class N>
>> -void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT,
>> - FuncT &F);
>> +void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, FuncT &F);
>>
>> /// \brief Core dominator tree base class.
>> ///
>> @@ -251,14 +272,14 @@ protected:
>> // NewBB is split and now it has one successor. Update dominator tree to
>> // reflect this change.
>> template <class N, class GraphT>
>> - void Split(DominatorTreeBase<typename GraphT::NodeType> &DT,
>> - typename GraphT::NodeType *NewBB) {
>> + void Split(DominatorTreeBaseByGraphTraits<GraphT> &DT,
>> + typename GraphT::NodeRef NewBB) {
>> assert(std::distance(GraphT::child_begin(NewBB),
>> GraphT::child_end(NewBB)) == 1 &&
>> "NewBB should have a single successor!");
>> - typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB);
>> + typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
>>
>> - std::vector<typename GraphT::NodeType *> PredBlocks;
>> + std::vector<typename GraphT::NodeRef> PredBlocks;
>> typedef GraphTraits<Inverse<N>> InvTraits;
>> for (typename InvTraits::ChildIteratorType
>> PI = InvTraits::child_begin(NewBB),
>> @@ -273,7 +294,7 @@ protected:
>> PI = InvTraits::child_begin(NewBBSucc),
>> E = InvTraits::child_end(NewBBSucc);
>> PI != E; ++PI) {
>> - typename InvTraits::NodeType *ND = *PI;
>> + typename InvTraits::NodeRef ND = *PI;
>> if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
>> DT.isReachableFromEntry(ND)) {
>> NewBBDominatesNewBBSucc = false;
>> @@ -627,18 +648,17 @@ public:
>>
>> protected:
>> template <class GraphT>
>> - friend typename GraphT::NodeType *
>> - Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
>> - typename GraphT::NodeType *V, unsigned LastLinked);
>> + friend typename GraphT::NodeRef
>> + Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
>> + unsigned LastLinked);
>>
>> template <class GraphT>
>> - friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType> &DT,
>> - typename GraphT::NodeType *V, unsigned N);
>> + friend unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
>> + typename GraphT::NodeRef V, unsigned N);
>>
>> template <class FuncT, class N>
>> - friend void
>> - Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F);
>> -
>> + friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT,
>> + FuncT &F);
>>
>> DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
>> if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
>>
>> Modified: llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h?rev=278961&r1=278960&r2=278961&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h (original)
>> +++ llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h Wed Aug 17 15:01:58 2016
>> @@ -29,9 +29,9 @@
>>
>> namespace llvm {
>>
>> -template<class GraphT>
>> -unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
>> - typename GraphT::NodeType* V, unsigned N) {
>> +template <class GraphT>
>> +unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
>> + typename GraphT::NodeRef V, unsigned N) {
>> // This is more understandable as a recursive algorithm, but we can't use the
>> // recursive algorithm due to stack depth issues. Keep it here for
>> // documentation purposes.
>> @@ -52,15 +52,16 @@ unsigned DFSPass(DominatorTreeBase<typen
>> #else
>> bool IsChildOfArtificialExit = (N != 0);
>>
>> - SmallVector<std::pair<typename GraphT::NodeType*,
>> - typename GraphT::ChildIteratorType>, 32> Worklist;
>> + SmallVector<
>> + std::pair<typename GraphT::NodeRef, typename GraphT::ChildIteratorType>,
>> + 32>
>> + Worklist;
>> Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
>> while (!Worklist.empty()) {
>> - typename GraphT::NodeType* BB = Worklist.back().first;
>> + typename GraphT::NodeRef BB = Worklist.back().first;
>> typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
>>
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
>> - DT.Info[BB];
>> + auto &BBInfo = DT.Info[BB];
>>
>> // First time we visited this BB?
>> if (NextSucc == GraphT::child_begin(BB)) {
>> @@ -89,10 +90,9 @@ unsigned DFSPass(DominatorTreeBase<typen
>> ++Worklist.back().second;
>>
>> // Visit the successor next, if it isn't already visited.
>> - typename GraphT::NodeType* Succ = *NextSucc;
>> + typename GraphT::NodeRef Succ = *NextSucc;
>>
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
>> - DT.Info[Succ];
>> + auto &SuccVInfo = DT.Info[Succ];
>> if (SuccVInfo.Semi == 0) {
>> SuccVInfo.Parent = BBDFSNum;
>> Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
>> @@ -103,25 +103,23 @@ unsigned DFSPass(DominatorTreeBase<typen
>> }
>>
>> template <class GraphT>
>> -typename GraphT::NodeType *
>> -Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
>> - typename GraphT::NodeType *VIn, unsigned LastLinked) {
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
>> - DT.Info[VIn];
>> +typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT,
>> + typename GraphT::NodeRef VIn,
>> + unsigned LastLinked) {
>> + auto &VInInfo = DT.Info[VIn];
>> if (VInInfo.DFSNum < LastLinked)
>> return VIn;
>>
>> - SmallVector<typename GraphT::NodeType*, 32> Work;
>> - SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
>> + SmallVector<typename GraphT::NodeRef, 32> Work;
>> + SmallPtrSet<typename GraphT::NodeRef, 32> Visited;
>>
>> if (VInInfo.Parent >= LastLinked)
>> Work.push_back(VIn);
>>
>> while (!Work.empty()) {
>> - typename GraphT::NodeType* V = Work.back();
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
>> - DT.Info[V];
>> - typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
>> + typename GraphT::NodeRef V = Work.back();
>> + auto &VInfo = DT.Info[V];
>> + typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent];
>>
>> // Process Ancestor first
>> if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
>> @@ -134,10 +132,9 @@ Eval(DominatorTreeBase<typename GraphT::
>> if (VInfo.Parent < LastLinked)
>> continue;
>>
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
>> - DT.Info[VAncestor];
>> - typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
>> - typename GraphT::NodeType* VLabel = VInfo.Label;
>> + auto &VAInfo = DT.Info[VAncestor];
>> + typename GraphT::NodeRef VAncestorLabel = VAInfo.Label;
>> + typename GraphT::NodeRef VLabel = VInfo.Label;
>> if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
>> VInfo.Label = VAncestorLabel;
>> VInfo.Parent = VAInfo.Parent;
>> @@ -146,16 +143,18 @@ Eval(DominatorTreeBase<typename GraphT::
>> return VInInfo.Label;
>> }
>>
>> -template<class FuncT, class NodeT>
>> -void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
>> - FuncT& F) {
>> +template <class FuncT, class NodeT>
>> +void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
>> + FuncT &F) {
>> typedef GraphTraits<NodeT> GraphT;
>> + static_assert(std::is_pointer<typename GraphT::NodeRef>::value,
>> + "NodeRef should be pointer type");
>> + typedef typename std::remove_pointer<typename GraphT::NodeRef>::type NodeType;
>>
>> unsigned N = 0;
>> bool MultipleRoots = (DT.Roots.size() > 1);
>> if (MultipleRoots) {
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
>> - DT.Info[nullptr];
>> + auto &BBInfo = DT.Info[nullptr];
>> BBInfo.DFSNum = BBInfo.Semi = ++N;
>> BBInfo.Label = nullptr;
>>
>> @@ -188,14 +187,13 @@ void Calculate(DominatorTreeBase<typenam
>> Buckets[i] = i;
>>
>> for (unsigned i = N; i >= 2; --i) {
>> - typename GraphT::NodeType* W = DT.Vertex[i];
>> - typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
>> - DT.Info[W];
>> + typename GraphT::NodeRef W = DT.Vertex[i];
>> + auto &WInfo = DT.Info[W];
>>
>> // Step #2: Implicitly define the immediate dominator of vertices
>> for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
>> - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
>> - typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
>> + typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
>> + typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1);
>> DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
>> }
>>
>> @@ -207,7 +205,7 @@ void Calculate(DominatorTreeBase<typenam
>> for (typename InvTraits::ChildIteratorType CI =
>> InvTraits::child_begin(W),
>> E = InvTraits::child_end(W); CI != E; ++CI) {
>> - typename InvTraits::NodeType *N = *CI;
>> + typename InvTraits::NodeRef N = *CI;
>> if (DT.Info.count(N)) { // Only if this predecessor is reachable!
>> unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
>> if (SemiU < WInfo.Semi)
>> @@ -227,17 +225,17 @@ void Calculate(DominatorTreeBase<typenam
>> }
>>
>> if (N >= 1) {
>> - typename GraphT::NodeType* Root = DT.Vertex[1];
>> + typename GraphT::NodeRef Root = DT.Vertex[1];
>> for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
>> - typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
>> + typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
>> DT.IDoms[V] = Root;
>> }
>> }
>>
>> // Step #4: Explicitly define the immediate dominator of each vertex
>> for (unsigned i = 2; i <= N; ++i) {
>> - typename GraphT::NodeType* W = DT.Vertex[i];
>> - typename GraphT::NodeType*& WIDom = DT.IDoms[W];
>> + typename GraphT::NodeRef W = DT.Vertex[i];
>> + typename GraphT::NodeRef &WIDom = DT.IDoms[W];
>> if (WIDom != DT.Vertex[DT.Info[W].Semi])
>> WIDom = DT.IDoms[WIDom];
>> }
>> @@ -248,34 +246,32 @@ void Calculate(DominatorTreeBase<typenam
>> // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
>> // which postdominates all real exits if there are multiple exit blocks, or
>> // an infinite loop.
>> - typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr;
>> + typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr;
>>
>> DT.RootNode =
>> (DT.DomTreeNodes[Root] =
>> - llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
>> - Root, nullptr)).get();
>> + llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr))
>> + .get();
>>
>> // Loop over all of the reachable blocks in the function...
>> for (unsigned i = 2; i <= N; ++i) {
>> - typename GraphT::NodeType* W = DT.Vertex[i];
>> + typename GraphT::NodeRef W = DT.Vertex[i];
>>
>> // Don't replace this with 'count', the insertion side effect is important
>> if (DT.DomTreeNodes[W])
>> continue; // Haven't calculated this node yet?
>>
>> - typename GraphT::NodeType* ImmDom = DT.getIDom(W);
>> + typename GraphT::NodeRef ImmDom = DT.getIDom(W);
>>
>> assert(ImmDom || DT.DomTreeNodes[nullptr]);
>>
>> // Get or calculate the node for the immediate dominator
>> - DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
>> - DT.getNodeForBlock(ImmDom);
>> + DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom);
>>
>> // Add a new tree node for this BasicBlock, and link it as a child of
>> // IDomNode
>> DT.DomTreeNodes[W] = IDomNode->addChild(
>> - llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
>> - W, IDomNode));
>> + llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode));
>> }
>>
>> // Free temporary memory used to construct idom's
>>
>> Modified: llvm/trunk/lib/IR/Dominators.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Dominators.cpp?rev=278961&r1=278960&r2=278961&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/IR/Dominators.cpp (original)
>> +++ llvm/trunk/lib/IR/Dominators.cpp Wed Aug 17 15:01:58 2016
>> @@ -64,9 +64,13 @@ template class llvm::DomTreeNodeBase<Bas
>> template class llvm::DominatorTreeBase<BasicBlock>;
>>
>> template void llvm::Calculate<Function, BasicBlock *>(
>> - DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
>> + DominatorTreeBase<
>> + typename std::remove_pointer<GraphTraits<BasicBlock *>::NodeRef>::type>
>> + &DT,
>> + Function &F);
>> template void llvm::Calculate<Function, Inverse<BasicBlock *>>(
>> - DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
>> + DominatorTreeBase<typename std::remove_pointer<
>> + GraphTraits<Inverse<BasicBlock *>>::NodeRef>::type> &DT,
>> Function &F);
>>
>> // dominates - Return true if Def dominates a use in User. This performs
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list