[llvm] r204841 - Change the PBQP graph adjacency list structure from std::set to std::vector.

David Blaikie dblaikie at gmail.com
Wed Mar 26 12:17:33 PDT 2014


On Wed, Mar 26, 2014 at 11:58 AM, Lang Hames <lhames at gmail.com> wrote:
> Author: lhames
> Date: Wed Mar 26 13:58:00 2014
> New Revision: 204841
>
> URL: http://llvm.org/viewvc/llvm-project?rev=204841&view=rev
> Log:
> Change the PBQP graph adjacency list structure from std::set to std::vector.
>
> The edge data structure (EdgeEntry) now holds the indices of its entries in the
> adjacency lists of the nodes it connects. This trades a little ugliness for
> faster insertion/removal, which is now O(1) with a cheap constant factor. All
> of this is implementation detail within the PBQP graph, the external API remains
> unchanged.
>
> Individual register allocations are likely to change, since the adjacency lists
> will now be ordered differently (or rather, will now be unordered). This
> shouldn't affect the average quality of allocations however.
>
>
> Modified:
>     llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h
>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h?rev=204841&r1=204840&r2=204841&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h Wed Mar 26 13:58:00 2014
> @@ -51,29 +51,115 @@ namespace PBQP {
>
>      class NodeEntry {
>      public:
> -      typedef std::set<NodeId> AdjEdgeList;
> +      typedef std::vector<EdgeId> AdjEdgeList;
> +      typedef AdjEdgeList::size_type AdjEdgeIdx;
>        typedef AdjEdgeList::const_iterator AdjEdgeItr;
> +
> +      static AdjEdgeIdx getInvalidAdjEdgeIdx() {
> +        return std::numeric_limits<AdjEdgeIdx>::max();
> +      }
> +
>        NodeEntry(VectorPtr Costs) : Costs(Costs) {}
>
> +      AdjEdgeIdx addAdjEdgeId(EdgeId EId) {
> +        AdjEdgeIdx Idx = AdjEdgeIds.size();
> +        AdjEdgeIds.push_back(EId);
> +        return Idx;
> +      }
> +
> +      // If a swap is performed, returns the new EdgeId that must be
> +      // updated, otherwise returns invalidEdgeId().
> +      EdgeId removeAdjEdgeId(AdjEdgeIdx Idx) {
> +        EdgeId EIdToUpdate = Graph::invalidEdgeId();
> +        if (Idx < AdjEdgeIds.size() - 1) {

Hrm - why isn't this ^ an assert? When do you try to remove edges that
aren't in the edge list?

> +          std::swap(AdjEdgeIds[Idx], AdjEdgeIds.back());
> +          EIdToUpdate = AdjEdgeIds[Idx];
> +        }
> +        AdjEdgeIds.pop_back();
> +        return EIdToUpdate;
> +      }
> +
> +      const AdjEdgeList& getAdjEdgeIds() const { return AdjEdgeIds; }
> +
>        VectorPtr Costs;
>        NodeMetadata Metadata;
> +    private:
>        AdjEdgeList AdjEdgeIds;
>      };
>
>      class EdgeEntry {
>      public:
>        EdgeEntry(NodeId N1Id, NodeId N2Id, MatrixPtr Costs)
> -        : Costs(Costs), N1Id(N1Id), N2Id(N2Id) {}
> +        : Costs(Costs) {
> +        NIds[0] = N1Id;
> +        NIds[1] = N2Id;
> +        ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
> +        ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
> +      }
> +
>        void invalidate() {
> -        N1Id = N2Id = Graph::invalidNodeId();
> +        NIds[0] = NIds[1] = Graph::invalidNodeId();
> +        ThisEdgeAdjIdxs[0] = ThisEdgeAdjIdxs[1] =
> +          NodeEntry::getInvalidAdjEdgeIdx();
>          Costs = nullptr;
>        }
> -      NodeId getN1Id() const { return N1Id; }
> -      NodeId getN2Id() const { return N2Id; }
> +
> +      void connectToN(Graph &G, EdgeId ThisEdgeId, unsigned NIdx) {
> +        assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
> +               "Edge already connected to NIds[NIdx].");
> +        NodeEntry &N = G.getNode(NIds[NIdx]);
> +        ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
> +      }
> +
> +      void connectTo(Graph &G, EdgeId ThisEdgeId, NodeId NId) {
> +        if (NId == NIds[0])
> +          connectToN(G, ThisEdgeId, 0);
> +        else {
> +          assert(NId == NIds[1] && "Edge does not connect NId.");
> +          connectToN(G, ThisEdgeId, 1);
> +        }
> +      }
> +
> +      void connect(Graph &G, EdgeId ThisEdgeId) {
> +        connectToN(G, ThisEdgeId, 0);
> +        connectToN(G, ThisEdgeId, 1);
> +      }
> +
> +      void updateAdjEdgeIdx(NodeId NId, typename NodeEntry::AdjEdgeIdx NewIdx) {
> +        if (NId == NIds[0])
> +          ThisEdgeAdjIdxs[0] = NewIdx;
> +        else {
> +          assert(NId == NIds[1] && "Edge not connected to NId");
> +          ThisEdgeAdjIdxs[1] = NewIdx;
> +        }
> +      }
> +
> +      void disconnectFromN(Graph &G, unsigned NIdx) {
> +        assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
> +               "Edge not connected to NIds[NIdx].");
> +        NodeEntry &N = G.getNode(NIds[NIdx]);
> +        EdgeId EIdToUpdate = N.removeAdjEdgeId(ThisEdgeAdjIdxs[NIdx]);
> +        if (EIdToUpdate != Graph::invalidEdgeId())
> +          G.getEdge(EIdToUpdate).updateAdjEdgeIdx(NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
> +        ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
> +      }
> +
> +      void disconnectFrom(Graph &G, NodeId NId) {
> +        if (NId == NIds[0])
> +          disconnectFromN(G, 0);
> +        else {
> +          assert(NId == NIds[1] && "Edge does not connect NId");
> +          disconnectFromN(G, 1);
> +        }
> +      }
> +
> +      NodeId getN1Id() const { return NIds[0]; }
> +      NodeId getN2Id() const { return NIds[1]; }
>        MatrixPtr Costs;
>        EdgeMetadata Metadata;
>      private:
> -      NodeId N1Id, N2Id;
> +      NodeId NIds[2];
> +      typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
>      };
>
>      // ----- MEMBERS -----
> @@ -134,8 +220,8 @@ namespace PBQP {
>               (N2.Costs->getLength() == NE.Costs->getCols()) &&
>               "Edge cost dimensions do not match node costs dimensions.");
>
> -      N1.AdjEdgeIds.insert(EId);
> -      N2.AdjEdgeIds.insert(EId);
> +      // Add the edge to the adjacency sets of its nodes.
> +      NE.connect(*this, EId);
>        return EId;
>      }
>
> @@ -228,14 +314,14 @@ namespace PBQP {
>      public:
>        AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) { }
>        typename NodeEntry::AdjEdgeItr begin() const {
> -        return NE.AdjEdgeIds.begin();
> +        return NE.getAdjEdgeIds().begin();
>        }
>        typename NodeEntry::AdjEdgeItr end() const {
> -        return NE.AdjEdgeIds.end();
> +        return NE.getAdjEdgeIds().end();
>        }
> -      bool empty() const { return NE.AdjEdges.empty(); }
> +      bool empty() const { return NE.getAdjEdgeIds().empty(); }
>        typename NodeEntry::AdjEdgeList::size_type size() const {
> -        return NE.AdjEdgeIds.size();
> +        return NE.getAdjEdgeIds().size();
>        }
>      private:
>        const NodeEntry &NE;
> @@ -336,7 +422,7 @@ namespace PBQP {
>      }
>
>      typename NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const {
> -      return getNode(NId).AdjEdgeIds.size();
> +      return getNode(NId).getAdjEdgeIds().size();
>      }
>
>      /// \brief Set an edge's cost matrix.
> @@ -459,8 +545,9 @@ namespace PBQP {
>      void disconnectEdge(EdgeId EId, NodeId NId) {
>        if (Solver)
>          Solver->handleDisconnectEdge(EId, NId);
> -      NodeEntry &N = getNode(NId);
> -      N.AdjEdgeIds.erase(EId);
> +
> +      EdgeEntry &E = getEdge(EId);
> +      E.disconnectFrom(*this, NId);
>      }
>
>      /// \brief Convenience method to disconnect all neighbours from the given
> @@ -475,8 +562,8 @@ namespace PBQP {
>      /// Adds an edge that had been previously disconnected back into the
>      /// adjacency set of the nodes that the edge connects.
>      void reconnectEdge(EdgeId EId, NodeId NId) {
> -      NodeEntry &N = getNode(NId);
> -      N.addAdjEdge(EId);
> +      EdgeEntry &E = getEdge(EId);
> +      E.connectTo(*this, EId, NId);
>        if (Solver)
>          Solver->handleReconnectEdge(EId, NId);
>      }
> @@ -487,10 +574,7 @@ namespace PBQP {
>        if (Solver)
>          Solver->handleRemoveEdge(EId);
>        EdgeEntry &E = getEdge(EId);
> -      NodeEntry &N1 = getNode(E.getNode1());
> -      NodeEntry &N2 = getNode(E.getNode2());
> -      N1.removeEdge(EId);
> -      N2.removeEdge(EId);
> +      E.disconnect();
>        FreeEdgeIds.push_back(EId);
>        Edges[EId].invalidate();
>      }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list