136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------- ReductionRules.h - Reduction Rules -------------*- C++ -*-===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Reduction Rules.
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_CODEGEN_PBQP_REDUCTIONRULES_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_CODEGEN_PBQP_REDUCTIONRULES_H
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Graph.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Math.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Solution.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace llvm {
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace PBQP {
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Reduce a node of degree one.
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ///
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Propagate costs from the given node, which must be of degree one, to its
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// neighbor. Notify the problem domain.
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename GraphT>
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void applyR1(GraphT &G, typename GraphT::NodeId NId) {
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::NodeId NodeId;
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::EdgeId EdgeId;
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::Vector Vector;
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::Matrix Matrix;
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::RawVector RawVector;
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(G.getNodeDegree(NId) == 1 &&
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           "R1 applied to node with degree != 1.");
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EdgeId EId = *G.adjEdgeIds(NId).begin();
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NodeId MId = G.getEdgeOtherNodeId(EId, NId);
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Matrix &ECosts = G.getEdgeCosts(EId);
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Vector &XCosts = G.getNodeCosts(NId);
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RawVector YCosts = G.getNodeCosts(MId);
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Duplicate a little to avoid transposing matrices.
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (NId == G.getEdgeNode1Id(EId)) {
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned j = 0; j < YCosts.getLength(); ++j) {
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        PBQPNum Min = ECosts[0][j] + XCosts[0];
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (unsigned i = 1; i < XCosts.getLength(); ++i) {
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          PBQPNum C = ECosts[i][j] + XCosts[i];
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          if (C < Min)
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Min = C;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        YCosts[j] += Min;
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned i = 0; i < YCosts.getLength(); ++i) {
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        PBQPNum Min = ECosts[i][0] + XCosts[0];
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (unsigned j = 1; j < XCosts.getLength(); ++j) {
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          PBQPNum C = ECosts[i][j] + XCosts[j];
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          if (C < Min)
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Min = C;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        YCosts[i] += Min;
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    G.setNodeCosts(MId, YCosts);
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    G.disconnectEdge(EId, MId);
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename GraphT>
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void applyR2(GraphT &G, typename GraphT::NodeId NId) {
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::NodeId NodeId;
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::EdgeId EdgeId;
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::Vector Vector;
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::Matrix Matrix;
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::RawMatrix RawMatrix;
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(G.getNodeDegree(NId) == 2 &&
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           "R2 applied to node with degree != 2.");
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Vector &XCosts = G.getNodeCosts(NId);
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typename GraphT::AdjEdgeItr AEItr = G.adjEdgeIds(NId).begin();
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EdgeId YXEId = *AEItr,
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           ZXEId = *(++AEItr);
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NodeId YNId = G.getEdgeOtherNodeId(YXEId, NId),
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           ZNId = G.getEdgeOtherNodeId(ZXEId, NId);
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool FlipEdge1 = (G.getEdgeNode1Id(YXEId) == NId),
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         FlipEdge2 = (G.getEdgeNode1Id(ZXEId) == NId);
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Matrix *YXECosts = FlipEdge1 ?
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      new Matrix(G.getEdgeCosts(YXEId).transpose()) :
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      &G.getEdgeCosts(YXEId);
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Matrix *ZXECosts = FlipEdge2 ?
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      new Matrix(G.getEdgeCosts(ZXEId).transpose()) :
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      &G.getEdgeCosts(ZXEId);
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned XLen = XCosts.getLength(),
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      YLen = YXECosts->getRows(),
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ZLen = ZXECosts->getRows();
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RawMatrix Delta(YLen, ZLen);
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (unsigned i = 0; i < YLen; ++i) {
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned j = 0; j < ZLen; ++j) {
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        PBQPNum Min = (*YXECosts)[i][0] + (*ZXECosts)[j][0] + XCosts[0];
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (unsigned k = 1; k < XLen; ++k) {
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          PBQPNum C = (*YXECosts)[i][k] + (*ZXECosts)[j][k] + XCosts[k];
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          if (C < Min) {
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Min = C;
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          }
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Delta[i][j] = Min;
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (FlipEdge1)
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      delete YXECosts;
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (FlipEdge2)
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      delete ZXECosts;
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EdgeId YZEId = G.findEdge(YNId, ZNId);
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (YZEId == G.invalidEdgeId()) {
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      YZEId = G.addEdge(YNId, ZNId, Delta);
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const Matrix &YZECosts = G.getEdgeCosts(YZEId);
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (YNId == G.getEdgeNode1Id(YZEId)) {
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        G.updateEdgeCosts(YZEId, Delta + YZECosts);
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else {
137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        G.updateEdgeCosts(YZEId, Delta.transpose() + YZECosts);
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    G.disconnectEdge(YXEId, YNId);
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    G.disconnectEdge(ZXEId, ZNId);
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // TODO: Try to normalize newly added/modified edge.
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#ifndef NDEBUG
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Does this Cost vector have any register options ?
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  template <typename VectorT>
150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasRegisterOptions(const VectorT &V) {
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned VL = V.getLength();
152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // An empty or spill only cost vector does not provide any register option.
154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (VL <= 1)
155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If there are registers in the cost vector, but all of them have infinite
158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // costs, then ... there is no available register.
159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (unsigned i = 1; i < VL; ++i)
160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (V[i] != std::numeric_limits<PBQP::PBQPNum>::infinity())
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return true;
162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // \brief Find a solution to a fully reduced graph by backpropagation.
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Given a graph and a reduction order, pop each node from the reduction
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // order and greedily compute a minimum solution based on the node costs, and
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the dependent costs due to previously solved nodes.
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Note - This does not return the graph to its original (pre-reduction)
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //        state: the existing solvers destructively alter the node and edge
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //        costs. Given that, the backpropagate function doesn't attempt to
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //        replace the edges either, but leaves the graph in its reduced
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //        state.
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename GraphT, typename StackT>
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Solution backpropagate(GraphT& G, StackT stack) {
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef GraphBase::NodeId NodeId;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::Matrix Matrix;
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef typename GraphT::RawVector RawVector;
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Solution s;
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (!stack.empty()) {
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      NodeId NId = stack.back();
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      stack.pop_back();
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RawVector v = G.getNodeCosts(NId);
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#ifndef NDEBUG
193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Although a conservatively allocatable node can be allocated to a register,
194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // spilling it may provide a lower cost solution. Assert here that spilling
195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // is done by choice, not because there were no register available.
196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (G.getNodeMetadata(NId).wasConservativelyAllocatable())
197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        assert(hasRegisterOptions(v) && "A conservatively allocatable node "
198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                        "must have available register options");
199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif
200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (auto EId : G.adjEdgeIds(NId)) {
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const Matrix& edgeCosts = G.getEdgeCosts(EId);
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (NId == G.getEdgeNode1Id(EId)) {
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          NodeId mId = G.getEdgeNode2Id(EId);
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          v += edgeCosts.getColAsVector(s.getSelection(mId));
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        } else {
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          NodeId mId = G.getEdgeNode1Id(EId);
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          v += edgeCosts.getRowAsVector(s.getSelection(mId));
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      s.setSelection(NId, v.minIndex());
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return s;
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} // namespace PBQP
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} // namespace llvm
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
222