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