예제 #1
0
  virtual void registerBlock(Node * bl) { 
    assert(!bl->list());
    // XXX PEDANTIC
    //assert(!reachable(bl));

    bl->next() = head;
    bl->prev() = NULL;
    
    if(head)
      head->prev() = bl;
    else {
      // empty
      assert(_ct == 0);
      tail = bl;
    }
    
    head = bl;   

    bl->list() = this;

    //fprintf(stderr,"(%p) added block %p\n",this,bl);

    assert(reachable(bl));

    _ct++;
  }
예제 #2
0
static int ok_to_give_up(void)
{
	int i;

	if (!have_obj.nr)
		return 0;

	for (i = 0; i < want_obj.nr; i++) {
		struct object *want = want_obj.objects[i].item;

		if (want->flags & COMMON_KNOWN)
			continue;
		want = deref_tag(want, "a want line", 0);
		if (!want || want->type != OBJ_COMMIT) {
			/* no way to tell if this is reachable by
			 * looking at the ancestry chain alone, so
			 * leave a note to ourselves not to worry about
			 * this object anymore.
			 */
			want_obj.objects[i].item->flags |= COMMON_KNOWN;
			continue;
		}
		if (!reachable((struct commit *)want))
			return 0;
	}
	return 1;
}
예제 #3
0
void
build_graph()
{
	int i, j;
	memset(graph, 0, sizeof(graph));
	for(i=0; i<M; i++)
		for(j=i+1; j<M; j++)
			if(reachable(rides+i, rides+j))
				graph[i][j] = 1;
}
예제 #4
0
bool cbLab::reachableRobot(cbPoint i,cbPoint f)
{
    cbPoint auxi,auxf, offset;

    if(wallDistance(i)<ROBOT_RADIUS*0.999) return false;
    if(wallDistance(f)<ROBOT_RADIUS*0.999) return false;

    if(!reachable(i,f)) return false;

    offset=(f-i).normalize().rotate(M_PI/2)*ROBOT_RADIUS*0.999;

    auxi=i+offset;
    auxf=f+offset;
    if(!reachable(auxi,auxf)) return false;

    auxi=i-offset;
    auxf=f-offset;
    if(!reachable(auxi,auxf)) return false;

    return true;
}
예제 #5
0
파일: lvlgen.c 프로젝트: chrissexton/mid
static int stairlocs(Lvl *lvl, Loc ls[])
{
	int nls = 0;
	for (int z = 0; z < lvl->d; z++)
	for (int x = 1; x < lvl->w-1; x++)
	for (int y = 1; y < lvl->h-2; y++) {
		if (reachable(lvl, x, y, z) &&  tileinfo(lvl, x, y+1, z).flags & Tcollide
			&& !(tileinfo(lvl, x, y, z).flags & (Tfdoor | Tbdoor | Tup))) {
			ls[nls] = (Loc){ x, y, z };
			nls++;
		}
	}
	return nls;
}
예제 #6
0
파일: stmt.c 프로젝트: 0culus/ioq3
Code code(int kind) {
	Code cp;

	if (!reachable(kind))
		warning("unreachable code\n");

	NEW(cp, FUNC);
	cp->kind = kind;
	cp->prev = codelist;
	cp->next = NULL;
	codelist->next = cp;
	codelist = cp;
	return cp;
}
예제 #7
0
파일: stmt.c 프로젝트: 0culus/ioq3
void definept(Coordinate *p) {
	Code cp = code(Defpoint);

	cp->u.point.src = p ? *p : src;
	cp->u.point.point = npoints;
	if (ncalled > 0) {
		int n = findcount(cp->u.point.src.file,
			cp->u.point.src.x, cp->u.point.src.y);
		if (n > 0)
			refinc = (float)n/ncalled;
	}
	if (glevel > 2)	locus(identifiers, &cp->u.point.src);
	if (events.points && reachable(Gen))
		{
			Tree e = NULL;
			apply(events.points, &cp->u.point.src, &e);
			if (e)
				listnodes(e, 0, 0);
		}
}
예제 #8
0
void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
                         Callback &CB) {

  CFG *cfg = AC.getCFG();
  if (!cfg)
    return;

  // Scan for reachable blocks from the entrance of the CFG.
  // If there are no unreachable blocks, we're done.
  llvm::BitVector reachable(cfg->getNumBlockIDs());
  unsigned numReachable =
    scanMaybeReachableFromBlock(&cfg->getEntry(), PP, reachable);
  if (numReachable == cfg->getNumBlockIDs())
    return;
  
  // If there aren't explicit EH edges, we should include the 'try' dispatch
  // blocks as roots.
  if (!AC.getCFGBuildOptions().AddEHEdges) {
    for (CFG::try_block_iterator I = cfg->try_blocks_begin(),
         E = cfg->try_blocks_end() ; I != E; ++I) {
      numReachable += scanMaybeReachableFromBlock(*I, PP, reachable);
    }
    if (numReachable == cfg->getNumBlockIDs())
      return;
  }

  // There are some unreachable blocks.  We need to find the root blocks that
  // contain code that should be considered unreachable.  
  for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
    const CFGBlock *block = *I;
    // A block may have been marked reachable during this loop.
    if (reachable[block->getBlockID()])
      continue;
    
    DeadCodeScan DS(reachable, PP);
    numReachable += DS.scanBackwards(block, CB);
    
    if (numReachable == cfg->getNumBlockIDs())
      return;
  }
}
void init_direction_table() {

  for (Square s1 = SQ_A1; s1 <= SQ_H8; s1++)
      for (Square s2 = SQ_A1; s2 <= SQ_H8; s2++)
      {
          DirectionTable[s1][s2] = uint8_t(DIR_NONE);
          SignedDirectionTable[s1][s2] = uint8_t(SIGNED_DIR_NONE);
          if (s1 == s2)
              continue;

          for (SignedDirection d = SIGNED_DIR_E; d != SIGNED_DIR_NONE; d++)
          {
              if (reachable(s1, s2, d))
              {
                  SignedDirectionTable[s1][s2] = uint8_t(d);
                  DirectionTable[s1][s2] = uint8_t(d / 2);
                  break;
              }
          }
      }
}
예제 #10
0
파일: 820.cpp 프로젝트: lschirmer/works
void maxflow() {
   int vj, min;
   fTotal = 0;
   while(reachable(s, t)) {
       min = FLOW[parent[t]][t];
       vj = t;
       while(parent[vj] != vj) {
          if(FLOW[parent[vj]][vj] < min)
             min = FLOW[parent[vj]][vj];
             vj = parent[vj];
       }

       vj = t;
       while(parent[vj] != vj) {
          FLOW[parent[vj]][vj] -= min;
          FLOW[vj][parent[vj]] += min;
          F[parent[vj]][vj] += min;
          vj = parent[vj];
       }
       fTotal += min;
   }
}
예제 #11
0
bool hasCycle(Graph const * graph){
	int n = graph->getVerticesNumber();
	std::vector<std::vector<bool>> reachable(n, std::vector<bool>(n));

	for (int i = 0; i < n; ++i){
		std::vector<int> incidenceList = graph->getIncidenceList(i);
		for (auto &to : incidenceList)
			reachable[i][to] = true;
	}

	for (int k = 0; k < n; ++k)
	for (int i = 0; i < n; ++i)
	for (int j = 0; j < n; ++j)
	if (reachable[i][k] && reachable[k][j])
		reachable[i][j] = true;

	for (int i = 0; i < n; ++i)
	for (int j = i + 1; j < n; ++j)
	if (reachable[i][j] && reachable[j][i])
		return true;

	return false;
}
예제 #12
0
파일: opt.cpp 프로젝트: BillHu/hhvm
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) {
  Timer _t(Timer::optimize);

  auto const finishPass = [&] (const char* msg) {
    if (msg) {
      printUnit(6, unit, folly::format("after {}", msg).str().c_str());
    }
    assertx(checkCfg(unit));
    assertx(checkTmpsSpanningCalls(unit));
    if (debug) {
      forEachInst(rpoSortCfg(unit), [&](IRInstruction* inst) {
        assertx(checkOperandTypes(inst, &unit));
      });
    }
  };

  auto const doPass = [&] (void (*fn)(IRUnit&), const char* msg = nullptr) {
    fn(unit);
    finishPass(msg);
  };

  auto const dce = [&] (const char* which) {
    if (!RuntimeOption::EvalHHIRDeadCodeElim) return;
    eliminateDeadCode(unit);
    finishPass(folly::format("{} DCE", which).str().c_str());
  };

  auto const simplifyPass = [] (IRUnit& unit) {
    boost::dynamic_bitset<> reachable(unit.numBlocks());
    reachable.set(unit.entry()->id());

    auto const blocks = rpoSortCfg(unit);

    for (auto block : blocks) {
      // Skip unreachable blocks, or simplify() cries.
      if (!reachable.test(block->id())) continue;

      for (auto& inst : *block) simplify(unit, &inst);

      if (auto const b = block->back().next())  reachable.set(b->id());
      if (auto const b = block->back().taken()) reachable.set(b->id());
    }
  };

  auto const doSimplify = RuntimeOption::EvalHHIRExtraOptPass &&
                          RuntimeOption::EvalHHIRSimplification;
  auto const hasLoop = RuntimeOption::EvalJitLoops && cfgHasLoop(unit);

  auto const traceMode = kind != TransKind::Optimize ||
                         RuntimeOption::EvalJitPGORegionSelector == "hottrace";

  // TODO (#5792564): Guard relaxation doesn't work with loops.
  // TODO (#6599498): Guard relaxation is broken in wholecfg mode.
  if (shouldHHIRRelaxGuards() && !hasLoop && traceMode) {
    Timer _t(Timer::optimize_relaxGuards);
    const bool simple = kind == TransKind::Profile &&
                        (RuntimeOption::EvalJitRegionSelector == "tracelet" ||
                         RuntimeOption::EvalJitRegionSelector == "method");
    RelaxGuardsFlags flags = (RelaxGuardsFlags)
      (RelaxReflow | (simple ? RelaxSimple : RelaxNormal));
    auto changed = relaxGuards(unit, *irBuilder.guards(), flags);
    if (changed) finishPass("guard relaxation");

    if (doSimplify) {
      doPass(simplifyPass, "guard relaxation simplify");
    }
  }

  // This is vestigial (it removes some instructions needed by the old refcount
  // opts pass), and will be removed soon.
  eliminateTakes(unit);

  dce("initial");

  if (RuntimeOption::EvalHHIRPredictionOpts) {
    doPass(optimizePredictions, "prediction opts");
  }

  if (doSimplify) {
    doPass(simplifyPass, "simplify");
    dce("simplify");
  }

  if (RuntimeOption::EvalHHIRGlobalValueNumbering) {
    doPass(gvn);
    dce("gvn");
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(optimizeLoads);
    dce("loadelim");
  }

  /*
   * Note: doing this pass this late might not be ideal, in particular because
   * we've already turned some StLoc instructions into StLocNT.
   *
   * But right now there are assumptions preventing us from doing it before
   * refcount opts.  (Refcount opts needs to see all the StLocs explicitly
   * because it makes assumptions about whether references are consumed based
   * on that.)
   */
  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(optimizeStores);
    dce("storeelim");
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) {
    doPass(optimizeRefcounts2);
    dce("refcount");
  }

  if (RuntimeOption::EvalHHIRGenerateAsserts) {
    doPass(insertAsserts);
  }
}
int solution(vector<int> &A) {
    const int N = A.size();

    // If only 1 or 2 leaves,
    // can jump that in 1 jump
    if (N < 3) {
        return 1;
    }
    
    // Generate fibonacci numbers
    std::vector<int> fibNums;
    fibNums.push_back(0);
    fibNums.push_back(1);
    
    for (int i = 2; fibNums.back() < MAX_N_VALUE; ++i) {
        fibNums.push_back(fibNums[i-1] + fibNums[i-2]);   
    }
    
    // Reachable leaves vector
    std::vector<int> reachable(N);
    for (int i = 0; i < N; ++i) {
        reachable[i] = 0;
    }

    int pos;
    
    // Queue of leaves positions to analyze, starting at -1
    std::queue<int> leavesToLookAt;
    leavesToLookAt.push(-1);
    
    // Get reachable leaves after first jump
    for (int i = 2; i < fibNums.size(); ++i) {
        pos = fibNums[i] - 1;
        
        if (pos > N) {
            break;
        } else if (pos == N) {
            return 1;
        } else if (A[pos]) {
             reachable[pos] = 1;
             leavesToLookAt.push(pos);
        }
    }
    
    // Look at humps from other leaves we have reached
    int nextPos;
    int minJumps = -1;
    
    while(leavesToLookAt.size()) {
        pos = leavesToLookAt.front();
        leavesToLookAt.pop();
        
        for (int i = 2; i < fibNums.size(); ++i) {
            nextPos = pos + fibNums[i];
            
            if (nextPos > N) {
                // can't jump more than N + 1 (destination)
                break;
            } else if (nextPos == N) {
                // Destination
                if ((minJumps == -1) || ((reachable[pos] + 1) < minJumps)) {
                    // Update minJumps if found a path that is cheaper
                    minJumps = reachable[pos] + 1;
                }
            } else if (A[nextPos] && !reachable[nextPos]) {
                reachable[nextPos] = reachable[pos] + 1;
                leavesToLookAt.push(nextPos);
            }
        }
    }

    return minJumps;
}
예제 #14
0
separation find_wheel_minor(matroid_permuted <MatroidType>& permuted_matroid, matrix_permuted <MatrixType>& permuted_matrix,
                            matroid_element_set& extra_elements)
{
    assert (permuted_matrix.size1() >= 3 && permuted_matroid.size2() >= 3);

    /// Permute 1's in first row to the left.
    matroid_reorder_columns(permuted_matroid, permuted_matrix, 0, 1, 0, permuted_matroid.size2(), std::greater <int>());
    size_t count_first_row_ones = matrix_count_property_column_series(permuted_matrix, 0, 1, 0, permuted_matrix.size2(), is_non_zero());

    /// Trivial 1-separation
    if (count_first_row_ones == 0)
    {
        return separation(std::make_pair(1, 0));
    }

    matroid_reorder_rows(permuted_matroid, permuted_matrix, 1, permuted_matroid.size1(), 0, 1, std::greater <int>());
    size_t count_first_column_ones = matrix_count_property_row_series(permuted_matrix, 0, permuted_matroid.size1(), 0, 1, is_non_zero());

    /// 1- or 2-separation
    if (count_first_row_ones == 1)
    {
        if (count_first_column_ones == 0)
        {
            return separation(std::make_pair(1, 1));
        }
        else
        {
            return separation(std::make_pair(1, 1), std::make_pair(1, 0));
        }
    }
    else if (count_first_column_ones == 1)
    {
        return separation(std::make_pair(1, 1), std::make_pair(0, 1));
    }

    assert ((permuted_matrix(0,0) == 1) && (permuted_matrix(1,0) == 1) && (permuted_matrix(0,1) == 1));

    /// Ensure we have a 2x2 block of ones
    if (permuted_matrix(1, 1) != 1)
    {
        matroid_binary_pivot(permuted_matroid, permuted_matrix, 0, 0);
        extra_elements.insert(permuted_matroid.name1(0));
        extra_elements.insert(permuted_matroid.name2(0));
    }

    assert ((permuted_matrix(0,0) == 1) && (permuted_matrix(1,0) == 1) && (permuted_matrix(0,1) == 1) && (permuted_matrix(1,1) == 1));

    /// Grow the block to a set-maximal one.
    matroid_reorder_columns(permuted_matroid, permuted_matrix, 0, 2, 2, permuted_matroid.size2(), std::greater <int>());
    size_t block_width = 2 + matrix_count_property_column_series(permuted_matrix, 0, 2, 2, permuted_matrix.size2(), is_all_ones());

    matroid_reorder_rows(permuted_matroid, permuted_matrix, 2, permuted_matroid.size1(), 0, block_width, std::greater <int>());

    size_t block_height = 2 + matrix_count_property_row_series(permuted_matrix, 2, permuted_matrix.size1(), 0, block_width, is_all_ones());

    /// Search for a path in BFS graph
    zero_block_matrix_modifier modifier(block_height, block_width);
    matrix_modified <matrix_permuted <MatrixType> , zero_block_matrix_modifier> modified_matrix(permuted_matrix, modifier);
    bipartite_graph_dimensions dim(permuted_matrix.size1(), permuted_matrix.size2());
    std::vector <bipartite_graph_dimensions::index_type> start_nodes(block_height);
    for (size_t i = 0; i < block_height; i++)
        start_nodes[i] = dim.row_to_index(i);
    std::vector <bipartite_graph_dimensions::index_type> end_nodes(block_width);
    for (size_t i = 0; i < block_width; i++)
        end_nodes[i] = dim.column_to_index(i);

    std::vector <bipartite_graph_bfs_node> bfs_result;
    bool found_path = bipartite_graph_bfs(modified_matrix, dim, start_nodes, end_nodes, false, bfs_result);

    /// There must be a 2-separation.
    if (!found_path)
    {
        std::pair <size_t, size_t> split(0, 0);

        /// Swap unreachable rows to top
        std::vector <int> reachable(permuted_matrix.size1());
        for (size_t i = 0; i < permuted_matrix.size1(); ++i)
        {
            const bipartite_graph_bfs_node& node = bfs_result[dim.row_to_index(i)];
            int value = (node.is_reachable() ? (node.distance > 0 ? 2 : 1) : 0);
            reachable[permuted_matrix.perm1()(i)] = value;
            if (value == 0)
                split.first++;
        }
        vector_less <int, std::less <int> > less(reachable, std::less <int>());

        sort(permuted_matrix.perm1(), less);
        permuted_matroid.perm1() = permuted_matrix.perm1();

        /// Swap unreachable columns to left
        reachable.resize(permuted_matrix.size2());
        for (size_t i = 0; i < permuted_matrix.size2(); ++i)
        {
            const bipartite_graph_bfs_node& node = bfs_result[dim.column_to_index(i)];
            int value = (node.is_reachable() ? 2 : (node.distance == -2 ? 1 : 0));
            reachable[permuted_matrix.perm2()(i)] = value;
            if (value < 2)
                split.second++;
        }

        sort(permuted_matrix.perm2(), less);
        permuted_matroid.perm2() = permuted_matrix.perm2();

        return separation(split, std::make_pair(split.first, split.second - 1));
    }

    /// Go back along the path to find the nearest endpoint.
    bipartite_graph_dimensions::index_type nearest_end = 0;
    for (std::vector <bipartite_graph_dimensions::index_type>::const_iterator iter = end_nodes.begin(); iter != end_nodes.end(); ++iter)
    {
        if (bfs_result[*iter].is_reachable())
            nearest_end = *iter;
    }

    assert (bfs_result[nearest_end].is_reachable());

    size_t w3_one_column = dim.index_to_column(nearest_end);
    size_t nearest_distance = bfs_result[nearest_end].distance + 1;

    assert (nearest_distance % 2 == 0);

    size_t last_index = nearest_end;
    size_t current_index = bfs_result[last_index].predecessor;

    /// Find indices for basic W3-parts.
    size_t w3_one_row = 0;
    size_t w3_path_column = 0;
    size_t w3_path_row = dim.index_to_row(current_index);
    size_t w3_zero_column = 0;
    while (permuted_matrix(w3_path_row, w3_zero_column) != 0)
    {
        w3_zero_column++;
        assert (w3_zero_column < block_width);
    }

    /// Apply path shortening technique.
    while (last_index != current_index)
    {
        std::pair <size_t, size_t> coords = dim.indexes_to_coordinates(current_index, last_index);

        if ((bfs_result[current_index].distance % 2 == 0) && (bfs_result[current_index].distance >= 2) && (bfs_result[current_index].distance + 2
                < (int) nearest_distance))
        {
            matroid_binary_pivot(permuted_matroid, permuted_matrix, coords.first, coords.second);
            extra_elements.insert(permuted_matroid.name1(coords.first));
            extra_elements.insert(permuted_matroid.name2(coords.second));
        }

        if (bfs_result[current_index].distance == 1)
        {
            assert (dim.is_column(current_index));

            w3_path_column = dim.index_to_column(current_index);
        }
        else if (bfs_result[current_index].distance == 0)
        {
            assert (dim.is_row(current_index));

            w3_one_row = dim.index_to_row(current_index);
        }

        last_index = current_index;
        current_index = bfs_result[current_index].predecessor;
    }

    /// Collect more W3-indices.
    size_t w3_zero_row = 0;
    while (permuted_matrix(w3_zero_row, w3_path_column) != 0)
    {
        w3_zero_row++;
        assert (w3_zero_row< block_height);
    }

    assert (permuted_matrix (w3_one_row, w3_one_column) == 1);
    assert (permuted_matrix (w3_one_row, w3_zero_column) == 1);
    assert (permuted_matrix (w3_one_row, w3_path_column) == 1);
    assert (permuted_matrix (w3_zero_row, w3_one_column) == 1);
    assert (permuted_matrix (w3_zero_row, w3_zero_column) == 1);
    assert (permuted_matrix (w3_zero_row, w3_path_column) == 0);
    assert (permuted_matrix (w3_path_row, w3_one_column) == 1);
    assert (permuted_matrix (w3_path_row, w3_zero_column) == 0);
    assert (permuted_matrix (w3_path_row, w3_path_column) == 1);

    /// Some normalization
    if (w3_zero_row > w3_one_row)
    {
        matroid_permute1(permuted_matroid, permuted_matrix, w3_one_row, w3_zero_row);
        std::swap(w3_one_row, w3_zero_row);
    }
    if (w3_one_row > w3_path_row)
    {
        matroid_permute1(permuted_matroid, permuted_matrix, w3_path_row, w3_one_row);
        std::swap(w3_path_row, w3_one_row);
    }

    if (w3_zero_column > w3_one_column)
    {
        matroid_permute2(permuted_matroid, permuted_matrix, w3_one_column, w3_zero_column);
        std::swap(w3_one_column, w3_zero_column);
    }
    if (w3_one_column > w3_path_column)
    {
        matroid_permute2(permuted_matroid, permuted_matrix, w3_path_column, w3_one_column);
        std::swap(w3_path_column, w3_one_column);
    }

    matroid_permute1(permuted_matroid, permuted_matrix, 0, w3_zero_row);
    matroid_permute1(permuted_matroid, permuted_matrix, 1, w3_one_row);
    matroid_permute1(permuted_matroid, permuted_matrix, 2, w3_path_row);

    matroid_permute2(permuted_matroid, permuted_matrix, 0, w3_zero_column);
    matroid_permute2(permuted_matroid, permuted_matrix, 1, w3_one_column);
    matroid_permute2(permuted_matroid, permuted_matrix, 2, w3_path_column);

    return separation();
}
예제 #15
0
void FindUnreachableCode(AnalysisContext &AC, Callback &CB) {
  CFG *cfg = AC.getCFG();
  if (!cfg)
    return;

  // Scan for reachable blocks.
  llvm::BitVector reachable(cfg->getNumBlockIDs());
  unsigned numReachable = ScanReachableFromBlock(cfg->getEntry(), reachable);

    // If there are no unreachable blocks, we're done.
  if (numReachable == cfg->getNumBlockIDs())
    return;

  SourceRange R1, R2;

  llvm::SmallVector<ErrLoc, 24> lines;
  bool AddEHEdges = AC.getAddEHEdges();

  // First, give warnings for blocks with no predecessors, as they
  // can't be part of a loop.
  for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
    CFGBlock &b = **I;
    if (!reachable[b.getBlockID()]) {
      if (b.pred_empty()) {
        if (!AddEHEdges
        && dyn_cast_or_null<CXXTryStmt>(b.getTerminator().getStmt())) {
            // When not adding EH edges from calls, catch clauses
            // can otherwise seem dead.  Avoid noting them as dead.
          numReachable += ScanReachableFromBlock(b, reachable);
          continue;
        }
        SourceLocation c = GetUnreachableLoc(b, R1, R2);
        if (!c.isValid()) {
            // Blocks without a location can't produce a warning, so don't mark
            // reachable blocks from here as live.
          reachable.set(b.getBlockID());
          ++numReachable;
          continue;
        }
        lines.push_back(ErrLoc(c, R1, R2));
          // Avoid excessive errors by marking everything reachable from here
        numReachable += ScanReachableFromBlock(b, reachable);
      }
    }
  }

  if (numReachable < cfg->getNumBlockIDs()) {
      // And then give warnings for the tops of loops.
    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
      CFGBlock &b = **I;
      if (!reachable[b.getBlockID()])
          // Avoid excessive errors by marking everything reachable from here
        lines.push_back(ErrLoc(MarkLiveTop(&b, reachable,
                                         AC.getASTContext().getSourceManager()),
                               SourceRange(), SourceRange()));
    }
  }

  llvm::array_pod_sort(lines.begin(), lines.end(), LineCmp);

  for (llvm::SmallVectorImpl<ErrLoc>::iterator I=lines.begin(), E=lines.end();
       I != E; ++I)
    if (I->Loc.isValid())
      CB.HandleUnreachable(I->Loc, I->R1, I->R2);
}