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++; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; } } } }
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; } }
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; }
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; }
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(); }
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); }