/** * Creates a node proving a property that is an intersection between the results of two nodes @a n1 and @a n2. * * Calls graph_t::set_contradiction if the new node proves an empty result. * * @note Predecessors are ordered so that the first one is "less than" the second one. */ intersection_node::intersection_node(node *n1, node *n2) : dependent_node(INTERSECTION) { assert(dominates(n1, this) && dominates(n2, this)); property const &res1 = n1->get_result(), &res2 = n2->get_result(); assert(res1.real == res2.real && res1.real.pred_bnd()); res = res1; res.intersect(res2); if (lower(res1.bnd()) > lower(res2.bnd())) std::swap(n1, n2); // to simplify the graph, no intersection should be nested get_inner_intersection_node(n1, 0); get_inner_intersection_node(n2, 1); insert_pred(n1); insert_pred(n2); if (is_empty(res.bnd())) { if (res1.real.pred() == PRED_REL) { // "always 0" is not a contradiction, so state that the real is "0" instead res = property(res1.real.real2(), interval(0, 0)); return; } res = property(); top_graph->set_contradiction(this); } }
/** * Creates a node proving a property that is an intersection between the results of two nodes @a n1 and @a n2. * * Calls graph_t::set_contradiction if the new node proves an empty result. * * @note Predecessors are ordered so that the first one is "less than" the second one. */ intersection_node::intersection_node(node *n1, node *n2) : dependent_node(INTERSECTION) { assert(dominates(n1, this) && dominates(n2, this)); property const &res1 = n1->get_result(), &res2 = n2->get_result(); assert(res1.real == res2.real && res1.real.pred_bnd()); res = res1; res.intersect(res2); if (lower(res1.bnd()) > lower(res2.bnd())) std::swap(n1, n2); // to simplify the graph, no intersection should be nested get_inner_intersection_node(n1, 0); get_inner_intersection_node(n2, 1); // by disallowing both nodes to be hypotheses, we are sure that even if the // output real is also an input, it is a meaningful input; enforced by the parser assert(n1->type != HYPOTHESIS || n2->type != HYPOTHESIS); insert_pred(n1); insert_pred(n2); if (is_empty(res.bnd())) { if (res1.real.pred() == PRED_REL) { // "always 0" is not a contradiction, so state that the real is "0" instead res = property(res1.real.real2(), interval(0, 0)); return; } res = property(); top_graph->set_contradiction(this); } }
/* * all nondominated points regarding the first 'noObjectives' dimensions * are collected; the points referenced by 'front[0..noPoints-1]' are * considered; 'front' is resorted, such that 'front[0..n-1]' contains * the nondominated points; n is returned */ int Hypervolume::filterNondominatedSet(double** front, int noPoints, int noObjectives) { int i, j; int n; n = noPoints; i = 0; while (i < n) { j = i + 1; while (j < n) { if (dominates(front[i], front[j], noObjectives)) { /* remove point 'j' */ n--; swap(front, j, n); } else if (dominates(front[j], front[i], noObjectives)) { /* remove point 'i'; ensure that the point copied to index 'i' is considered in the next outer loop (thus, decrement i) */ n--; swap(front, i, n); i--; break; } else { j++; } } // while i++; } // while return n; } // filterNondominatedSet
/** * Creates a ::MODUS node. Finds predecessors needed by @a n with ::find_proof. */ modus_node::modus_node(theorem_node *n) : dependent_node(MODUS), target(n) { assert(n); if (!proof_generator) return; if (n->name == "$FALSE") { assert(!parameter_constrained); nb_missing = 1 + n->hyp.size(); } int missing = 0; node_set nodes; for (property_vect::const_iterator i = n->hyp.begin(), i_end = n->hyp.end(); i != i_end; ++i) { node *m = find_proof(*i); if (!m) { assert(!parameter_constrained); m = create_theorem(0, NULL, *i, "$FALSE"); } assert(m && dominates(m, this)); if (m->type != HYPOTHESIS && nodes.insert(m).second) insert_pred(m); if (m->nb_missing) { assert(!parameter_constrained); ++missing; if (m->nb_missing > nb_missing) nb_missing = m->nb_missing; } } nb_missing += missing; }
int * minimaldominatorset(struct localvars * lv, struct globallist *gl, struct heap_state *heap, int includecurrent) { struct heap_object * ho=(lv!=NULL)?lv->object:gl->object; struct referencelist *rl2=ho->rl; int * in=(int *) malloc(sizeof(int)); #if (defined(NOBORINGDOM)||defined(NOLVDOM)) if (lv!=NULL&&isboring(lv)) { *in=0; return in; } #endif while (rl2!=NULL) { if((rl2->lv!=NULL)&&(includecurrent==0)&&(rl2->lv->m==heap->methodlist)) ; else if(dominates(rl2->lv,rl2->gl,lv,gl)) break; rl2=rl2->next; } if (rl2==NULL) *in=1; else *in=0; return in; }
bool is_tmp_usable(const IdomVector& idoms, const SSATmp* tmp, const Block* where) { if (tmp->inst()->is(DefConst)) return true; auto const definingBlock = findDefiningBlock(tmp, idoms); if (!definingBlock) return false; return dominates(definingBlock, where, idoms); }
void CSEHash::filter(Block* block, IdomVector& idoms) { for (auto it = map.begin(), end = map.end(); it != end;) { auto next = it; ++next; if (!dominates(it->second->inst()->getBlock(), block, idoms)) { map.erase(it); } it = next; } }
SSATmp* TraceBuilder::cseLookup(IRInstruction* inst, const folly::Optional<IdomVector>& idoms) { auto tmp = cseHashTable(inst)->lookup(inst); if (tmp && idoms) { // During a reoptimize pass, we need to make sure that any values // we want to reuse for CSE are only reused in blocks dominated by // the block that defines it. if (!dominates(tmp->inst()->block(), inst->block(), *idoms)) { return nullptr; } } return tmp; }
int filter_nondominated_set(double *front, int no_points, int no_objectives) /* all nondominated points regarding the first 'no_objectives' dimensions are collected; the points 0..no_points-1 in 'front' are considered; the points in 'front' are resorted, such that points [0..n-1] represent the nondominated points; n is returned */ { int i, j; int n; n = no_points; i = 0; while (i < n) { j = i + 1; while (j < n) { if (dominates(&(front[i * dim]), &(front[j * dim]), no_objectives)) { /* remove point 'j' */ n--; swap(front, j, n); } else if (dominates(&(front[j * dim]), &(front[i * dim]), no_objectives)) { /* remove point 'i'; ensure that the point copied to index 'i' is considered in the next outer loop (thus, decrement i) */ n--; swap(front, i, n); i--; break; } else j++; } i++; } return n; }
/* * Build the CFG, then the dominator tree, then use it to validate SSA. * 1. Each src must be defined by some other instruction, and each dst must * be defined by the current instruction. * 2. Each src must be defined earlier in the same block or in a dominator. * 3. Each dst must not be previously defined. * 4. Treat tmps defined by DefConst as always defined. * 5. Each predecessor of a reachable block must be reachable (deleted * blocks must not have out-edges to reachable blocks). * 6. The entry block must not have any predecessors. * 7. The entry block starts with a DefFP instruction. */ bool checkCfg(const IRUnit& unit) { auto const blocksIds = rpoSortCfgWithIds(unit); auto const& blocks = blocksIds.blocks; jit::hash_set<const Edge*> edges; // Entry block can't have predecessors. always_assert(unit.entry()->numPreds() == 0); // Entry block starts with DefFP always_assert(!unit.entry()->empty() && unit.entry()->begin()->op() == DefFP); // Check valid successor/predecessor edges. for (Block* b : blocks) { auto checkEdge = [&] (const Edge* e) { always_assert(e->from() == b); edges.insert(e); for (auto& p : e->to()->preds()) if (&p == e) return; always_assert(false); // did not find edge. }; checkBlock(b); if (auto *e = b->nextEdge()) checkEdge(e); if (auto *e = b->takenEdge()) checkEdge(e); } for (Block* b : blocks) { for (auto const &e : b->preds()) { always_assert(&e == e.inst()->takenEdge() || &e == e.inst()->nextEdge()); always_assert(e.to() == b); } } // Visit every instruction and make sure their sources are defined in a block // that dominates the block containing the instruction. auto const idoms = findDominators(unit, blocksIds); forEachInst(blocks, [&] (const IRInstruction* inst) { for (auto src : inst->srcs()) { if (src->inst()->is(DefConst)) continue; auto const dom = findDefiningBlock(src); always_assert_flog( dom && dominates(dom, inst->block(), idoms), "src '{}' in '{}' came from '{}', which is not a " "DefConst and is not defined at this use site", src->toString(), inst->toString(), src->inst()->toString() ); } }); return true; }
void NaiveDominators::dump(Graph& graph, PrintStream& out) const { for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) { BasicBlock* block = graph.block(blockIndex); if (!block) continue; out.print(" Block ", *block, ":"); for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) { if (!dominates(block->index, otherIndex)) continue; out.print(" #", otherIndex); } out.print("\n"); } }
bool TR_DominatorVerifier::isExpensiveAlgorithmCorrect(TR_DominatorsChk &expensiveAlgorithm) { int32_t i,j; _nodesSeenOnEveryPath = new (trStackMemory()) TR_BitVector(_numBlocks,trMemory(), stackAlloc); _nodesSeenOnCurrentPath = new (trStackMemory()) TR_BitVector(_numBlocks,trMemory(), stackAlloc); _dominatorsChkInfo = expensiveAlgorithm.getDominatorsChkInfo(); for (i = 2; i < _numBlocks-1; i++) { TR_BitVector *bucket = _dominatorsChkInfo[i]._tmpbucket; for (j = 0; j < _numBlocks-1; j++) { if (bucket->get(j)) // dominator according to algorithm { // Initializing these BitVectors before checking // dominators for the next block. // The last bit is not changed for either bit vector - is that what // was intended? // _nodesSeenOnEveryPath->setAll(_numBlocks-1); int32_t lastBit = _nodesSeenOnCurrentPath->get(_numBlocks-1); _nodesSeenOnCurrentPath->empty(); if (lastBit) _nodesSeenOnCurrentPath->set(_numBlocks-1); if ( ! dominates(_dominatorsChkInfo[j+1]._block,_dominatorsChkInfo[i]._block) ) // dominator according to the CFG { if (debug("traceVER")) { dumpOptDetails(comp(), " Dominator info for expensive algorithm is incorrect \n"); dumpOptDetails(comp(), " Dominator of [%p] is [%p] as per the algorithm\n", _dominatorsChkInfo[i]._block, _dominatorsChkInfo[j+1]._block); dumpOptDetails(comp(), " But [%p] is not an the dominator of [%p] as per the Control Flow Graph", _dominatorsChkInfo[j+1]._block, _dominatorsChkInfo[i]._block); } return false; } } } } return true; }
/** * Creates a ::MODUS node. Finds predecessors needed by @a n with ::find_proof. */ modus_node::modus_node(theorem_node *n) : dependent_node(MODUS), target(n) { assert(n); if (!proof_generator && parameter_constrained) return; node_set nodes; for (property_vect::const_iterator i = n->hyp.begin(), i_end = n->hyp.end(); i != i_end; ++i) { node *m = find_proof(*i); if (!m) { assert(!parameter_constrained); m = create_theorem(0, NULL, *i, "$FALSE", NULL); } assert(m && dominates(m, this)); if (nodes.insert(m).second) insert_pred(m); } }
Block* findDefiningBlock(const SSATmp* t, const IdomVector& idoms) { assertx(!t->inst()->is(DefConst)); auto const srcInst = t->inst(); if (srcInst->hasEdges()) { auto const next = srcInst->next(); UNUSED auto const taken = srcInst->taken(); always_assert_flog( next && taken, "hasEdges instruction defining a dst had no edges:\n {}\n", srcInst->toString() ); for (const auto& arc : next->preds()) { auto pred = arc.from(); if (pred != srcInst->block() && !dominates(next, pred, idoms)) { return nullptr; } } return next; } return srcInst->block(); }
QList<int> ParetoDominance::getParetoSet(MOVector<OptObjective>* _objs,MOOptVector* _objResults) { if((_objResults->size()==0)||(_objs->size()!=_objResults->size())) return QList<int>(); // Fulling set QList<int> paretoSet; for(int i=0;i<_objResults->at(0)->nbPoints();i++) paretoSet.push_back(i); // Removing points by points when dominated int index=0; int index2; bool indexDominated; while(index<paretoSet.size()) { indexDominated = false; index2=0; while(!indexDominated && index2<paretoSet.size()) { if(index!=index2) indexDominated = dominates(_objs,_objResults,paretoSet.at(index2),paretoSet.at(index)); index2++; } if(indexDominated) { paretoSet.removeAt(index); } else { index++; } } return paretoSet; }
int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32_t *flags) /* {{{ */ { int i, j, k; int depth; zend_basic_block *blocks = cfg->blocks; int *dj_spanning_tree; zend_worklist work; int flag = ZEND_FUNC_NO_LOOPS; ALLOCA_FLAG(list_use_heap); ALLOCA_FLAG(tree_use_heap); ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap); dj_spanning_tree = do_alloca(sizeof(int) * cfg->blocks_count, tree_use_heap); for (i = 0; i < cfg->blocks_count; i++) { dj_spanning_tree[i] = -1; } zend_worklist_push(&work, 0); while (zend_worklist_len(&work)) { next: i = zend_worklist_peek(&work); /* Visit blocks immediately dominated by i. */ for (j = blocks[i].children; j >= 0; j = blocks[j].next_child) { if (zend_worklist_push(&work, j)) { dj_spanning_tree[j] = i; goto next; } } /* Visit join edges. */ for (j = 0; j < 2; j++) { int succ = blocks[i].successors[j]; if (succ < 0) { continue; } else if (blocks[succ].idom == i) { continue; } else if (zend_worklist_push(&work, succ)) { dj_spanning_tree[succ] = i; goto next; } } zend_worklist_pop(&work); } /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs". */ for (i = 0, depth = 0; i < cfg->blocks_count; i++) { if (blocks[i].level > depth) { depth = blocks[i].level; } } for (; depth >= 0; depth--) { for (i = 0; i < cfg->blocks_count; i++) { if (blocks[i].level != depth) { continue; } zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count)); for (j = 0; j < blocks[i].predecessors_count; j++) { int pred = cfg->predecessors[blocks[i].predecessor_offset + j]; /* A join edge is one for which the predecessor does not immediately dominate the successor. */ if (blocks[i].idom == pred) { continue; } /* In a loop back-edge (back-join edge), the successor dominates the predecessor. */ if (dominates(blocks, i, pred)) { blocks[i].flags |= ZEND_BB_LOOP_HEADER; flag &= ~ZEND_FUNC_NO_LOOPS; zend_worklist_push(&work, pred); } else { /* Otherwise it's a cross-join edge. See if it's a branch to an ancestor on the dominator spanning tree. */ int dj_parent = pred; while (dj_parent >= 0) { if (dj_parent == i) { /* An sp-back edge: mark as irreducible. */ blocks[i].flags |= ZEND_BB_IRREDUCIBLE_LOOP; flag |= ZEND_FUNC_IRREDUCIBLE; flag &= ~ZEND_FUNC_NO_LOOPS; break; } else { dj_parent = dj_spanning_tree[dj_parent]; } } } } while (zend_worklist_len(&work)) { j = zend_worklist_pop(&work); if (blocks[j].loop_header < 0 && j != i) { blocks[j].loop_header = i; for (k = 0; k < blocks[j].predecessors_count; k++) { zend_worklist_push(&work, cfg->predecessors[blocks[j].predecessor_offset + k]); } } } } } free_alloca(dj_spanning_tree, tree_use_heap); ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap); *flags |= flag; return SUCCESS; }
test_results_t test1_33_Mutator::executeTest() { int pvalue; unsigned int i; if (isMutateeFortran(appImage)) { return SKIPPED; } BPatch_Vector<BPatch_function *> bpfv; const char *fn = "test1_33_func2"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Unable to find function %s\n", fn); return FAILED; } BPatch_function *func2 = bpfv[0]; BPatch_flowGraph *cfg = func2->getCFG(); if (cfg == NULL) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Unable to get control flow graph of %s\n", fn); return FAILED; } /* * Test for consistency of entry basic blocks. */ BPatch_Vector<BPatch_basicBlock*> entry_blocks; cfg->getEntryBasicBlock(entry_blocks); if (entry_blocks.size() != 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d entry basic blocks in %s, should have been one.\n", entry_blocks.size(), fn); return FAILED; } for (i = 0; i < entry_blocks.size(); i++) { BPatch_Vector<BPatch_basicBlock*> sources; entry_blocks[i]->getSources(sources); if (sources.size() > 0) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" An entry basic block has incoming edges in the control flow graph\n"); return FAILED; } BPatch_Vector<BPatch_basicBlock*> targets; entry_blocks[i]->getTargets(targets); if (targets.size() < 1) { logerror("**Failed** test #33 (control flow graphs\n"); logerror(" An entry basic block has no outgoing edges in the control flow graph\n"); return FAILED; } } /* * Test for consistency of exit basic blocks. */ BPatch_Vector<BPatch_basicBlock*> exit_blocks; cfg->getExitBasicBlock(exit_blocks); if (exit_blocks.size() != 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d exit basic blocks in %s, should have been one.\n", exit_blocks.size(), fn); return FAILED; } for (i = 0; i < exit_blocks.size(); i++) { BPatch_Vector<BPatch_basicBlock*> sources; exit_blocks[i]->getSources(sources); if (sources.size() < 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" An exit basic block has no incoming edges in the control flow graph\n"); return FAILED; } BPatch_Vector<BPatch_basicBlock*> targets; exit_blocks[i]->getTargets(targets); if (targets.size() > 0) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" An exit basic block has outgoing edges in the control flow graph\n"); return FAILED; } } /* * Check structure of control flow graph. */ std::set<BPatch_basicBlock*> blocks; cfg->getAllBasicBlocks(blocks); if (blocks.size() < 4) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d basic blocks in %s, should be at least four.\n", blocks.size(), fn); return FAILED; } bool foundOutDegreeTwo = false; bool foundInDegreeTwo = false; int blocksNoIn = 0, blocksNoOut = 0; for (std::set<BPatch_basicBlock *>::iterator iter = blocks.begin(); iter != blocks.end(); ++iter) { BPatch_Vector<BPatch_basicBlock*> in; BPatch_Vector<BPatch_basicBlock*> out; (*iter)->getSources(in); (*iter)->getTargets(out); if (in.size() == 0) blocksNoIn++; if (out.size() == 0) blocksNoOut++; if (in.size() > 2 || out.size() > 2) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size()); logerror(" outgoing edges - neither should be greater than two.\n"); return FAILED; } else if (in.size() > 1 && out.size() > 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size()); logerror(" outgoing edges - only one should be greater than one.\n"); return FAILED; } else if (in.size() == 0 && out.size() == 0) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected a basic block in %s with no incoming or outgoing edges.\n", fn); return FAILED; } else if (in.size() == 2) { assert(out.size() <= 1); if (foundInDegreeTwo) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected two basic blocks in %s with in degree two, there should only\n", fn); logerror(" be one.\n"); return FAILED; } foundInDegreeTwo = true; if (in[0]->getBlockNumber() == in[1]->getBlockNumber()) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Two edges go to the same block (number %d).\n", in[0]->getBlockNumber()); return FAILED; } } else if (out.size() == 2) { assert(in.size() <= 1); if (foundOutDegreeTwo) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected two basic blocks in %s with out degree two, there should only\n", fn); logerror(" be one.\n"); return FAILED; } foundOutDegreeTwo = true; if (out[0]->getBlockNumber() == out[1]->getBlockNumber()) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Two edges go to the same block (number %d).\n", out[0]->getBlockNumber()); return FAILED; } } else if (in.size() > 1 || out.size() > 1) { /* Shouldn't be able to get here. */ logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size()); logerror(" outgoing edges.\n"); return FAILED; } } if (blocksNoIn > 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected more than one block in %s with no incoming edges.\n", fn); return FAILED; } if (blocksNoOut > 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected more than block in %s with no outgoing edges.\n", fn); return FAILED; } if (!foundOutDegreeTwo) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Did not detect the \"if\" statement in %s.\n", fn); return FAILED; } /* * Check for loops (there aren't any in the function we're looking at). */ std::set<int> empty; if (hasBackEdge(entry_blocks[0], empty)) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected a loop in %s, there should not be one.\n", fn); return FAILED; } /* * Now check a function with a switch statement. */ bpfv.clear(); const char *fn2 = "test1_33_func3"; // Bernat, 8JUN05 -- include uninstrumentable here... if (NULL == appImage->findFunction(fn2, bpfv, false, false, true) || !bpfv.size() || NULL == bpfv[0]) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Unable to find function %s\n", fn2); return FAILED; } BPatch_function *func3 = bpfv[0]; BPatch_flowGraph *cfg3 = func3->getCFG(); if (cfg3 == NULL) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Unable to get control flow graph of %s\n", fn2); return FAILED; } std::set<BPatch_basicBlock*> blocks3; cfg3->getAllBasicBlocks(blocks3); if (blocks3.size() < 10) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d basic blocks in %s, should be at least ten.\n", blocks3.size(), fn2); return FAILED; } bool foundSwitchIn = false; bool foundSwitchOut = false; bool foundRangeCheck = false; for (std::set<BPatch_basicBlock *>::iterator iter = blocks3.begin(); iter != blocks3.end(); ++iter) { BPatch_basicBlock *block = *iter; BPatch_Vector<BPatch_basicBlock*> in; BPatch_Vector<BPatch_basicBlock*> out; block->getSources(in); block->getTargets(out); if (!foundSwitchOut && out.size() >= 10 && in.size() <= 1) { foundSwitchOut = true; } else if (!foundSwitchIn && in.size() >= 10 && out.size() <= 1) { foundSwitchIn = true; } else if (!foundRangeCheck && out.size() == 2 && in.size() <= 1) { foundRangeCheck = true; } else if (in.size() > 1 && out.size() > 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Found basic block in %s with unexpected number of edges.\n", fn2); logerror(" %d incoming edges, %d outgoing edges.\n", in.size(), out.size()); return FAILED; } } if (!foundSwitchIn || !foundSwitchOut) { logerror("**Failed** test #33 (control flow graphs)\n"); if (!foundSwitchIn) logerror(" Did not find \"switch\" statement in %s.\n", fn2); if (!foundSwitchOut) logerror(" Did not find block after \"switch\" statement.\n"); return FAILED; } /* Check dominator info. */ BPatch_Vector<BPatch_basicBlock*> entry3; cfg3->getEntryBasicBlock(entry3); if (entry3.size() != 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d entry basic blocks in %s, should have been one.\n", entry_blocks.size(), fn2); return FAILED; } for (std::set<BPatch_basicBlock *>::iterator iter2 = blocks3.begin(); iter2 != blocks3.end(); ++iter2) { if (!entry3[0]->dominates(*iter2)) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Entry block does not dominate all blocks in %s\n", fn2); return FAILED; } } BPatch_Vector<BPatch_basicBlock*> exit3; cfg3->getExitBasicBlock(exit3); if (exit3.size() != 1) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Detected %d exit basic blocks in %s, should have been one.\n", exit3.size(), fn2); for (unsigned i = 0; i < exit3.size(); ++i) { logerror("\t%d: 0x%lx\n", i, exit3[i]->getStartAddress()); } return FAILED; } for (i = 0; i < (unsigned int) exit3.size(); i++) { if (!exit3[i]->postdominates(entry3[0])) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Exit block %d does not postdominate all entry blocks in %s\n", i, fn2); return FAILED; } } #if !defined(os_windows_test) && defined(ENABLE_PARSE_API_GRAPHS) logerror("Testing parseAPI dominators\n"); ParseAPI::Function* parse_func = ParseAPI::convert(func3); assert(parse_func); Block* parse_entry = parse_func->entry(); bool parse_idoms_ok = true; for(Function::blocklist::const_iterator bl = parse_func->blocks().begin(); bl != parse_func->blocks().end(); ++bl) { if(*bl == parse_entry) continue; if(!dominates(*parse_func, parse_entry, *bl)) { parse_idoms_ok = false; } } if(!parse_idoms_ok) { logerror("**Failed** test #33 (CFG)\n"); logerror(" ParseAPI dominator algorithm does not have entry block dominating all blocks in function\n"); return FAILED; } #endif BPatch_variableExpr *expr33_1 = appImage->findVariable("test1_33_globalVariable1"); if (expr33_1 == NULL) { logerror("**Failed** test #33 (control flow graphs)\n"); logerror(" Unable to locate test1_33_globalVariable1\n"); return FAILED; } pvalue = 1; expr33_1->writeValue(&pvalue); return PASSED; }
void MOGA::compute_ranking() { // Reset rank and crowding. for ( unsigned int i = 0; i < population_.size(); ++i ) { population_[i].rank = 0; population_[i].crowding = 0; } // While there is elements with no rank for ( unsigned int r = 1, num_hidden = 0; num_hidden < population_.size(); ++r ) { // Compare each non-ranked solution with other non-ranked solutions std::vector<bool> nondominated( population_.size(), true ); std::vector<int> same_rank; for ( unsigned int i = 0; i < population_.size(); ++i ) { // If i has no rank assigned if ( population_[i].rank == 0 ) { for ( std::size_t j = 0; j < population_.size() && nondominated[i]; ++j ) { // If j has no rank assigned if ( population_[j].rank == 0 && i != j ) { // If j dominates i if ( dominates( population_[j], population_[i] ) ) { nondominated[i] = false; } } } } } // Assign ranks to non-dominated solutions hide them for ( unsigned int i = 0; i < population_.size(); ++i ) { if ( population_[i].rank == 0 && nondominated[i] ) { population_[i].rank = r; ++num_hidden; same_rank.push_back( i ); // Retrieve same-rank indices for crowding measure } } // Compute crowding measure for ( int k = 0; k < getNbObjective(); ++k ) { // Sort to have first which have objective k to min and last to max std::sort( same_rank.begin(), same_rank.end(), compare_objective( population_, k ) ); double zI = population_[same_rank.front()].obj[k], zA = population_[same_rank.back() ].obj[k], denominator = zA - zI; // First and last are infinity population_[same_rank.front()].crowding = std::numeric_limits<double>::infinity(); population_[same_rank.back() ].crowding = std::numeric_limits<double>::infinity(); for ( unsigned int i = 1; i < same_rank.size()-1; ++i ) { if ( population_[same_rank[i]].crowding == zI || population_[same_rank[i]].crowding == zA ) { population_[same_rank[i]].crowding = std::numeric_limits<double>::infinity(); } else if ( population_[same_rank[i]].crowding != std::numeric_limits<double>::infinity() ) { population_[same_rank[i]].crowding += ( population_[same_rank[i+1]].obj[k] - population_[same_rank[i-1]].obj[k] ) / denominator; } } } } // Sort to have best solutions on the top. std::sort( population_.begin(), population_.end(), compare_ranking() ); }
/** This virtual function directly call \c dominates(). \param x The right-hand side object -- \b IN. \return A boolean equal to \c true if \c *this \c < \c x. */ virtual bool operator < ( const NOMAD::Set_Element<NOMAD::Eval_Point> & x ) const { return dominates ( x ); }
bool DominanceInfo::dominates(CfgNode *dominator, CfgNode *dominatee) const { return dominates(get_number(dominator), get_number(dominatee)); }
/** * Adds node @a n as an immediate ancestor to this node. * @pre If this node is not a ::UNION node, then node @a n shall dominate it. */ void dependent_node::insert_pred(node *n) { assert(dominates(n, this) || type == UNION); n->succ.insert(this); pred.push_back(n); }
int getscore(int obj,int tau,int missingnumber, int sc){ double sigma; // σ, missing rate int i,j,l; int sum,lastu,average,bin; int pando; int ar; int omiga; int retval; /* *calculate the incomparable set with obj O(N*D) */ incomparablenumber=0; for(i=0;i<N;++i){ for(j=0;j<D;++j) if(dataset[obj].missing[j]+dataset[i].missing[j]!=1) break; incomparablenumber+=incomparable[i]=(j==D); } /* * calculate the bin size of each bin as well as the domain of each bin * use a method of greedy * when the sum of all values approach average value, go to next bin */ sigma = (missingnumber+0.0)/(N*D); for(i=0;i<D;i++){ ari[0]=0; // put all existing values in ari for(j=0;j<N;++j) if(!dataset[j].missing[i]) ari[++ari[0]]=j; quicksort(ari,i,1,ari[0]); goods[0]=goods[1]=1; goodv[1]=dataset[ari[1]].value[i]; for(j=2;j<=ari[0];++j)//calculate the number of a certain value if(dataset[ari[j]].value[i]==dataset[ari[j-1]].value[i]) // calculate the number of an identical value ++goods[goods[0]]; else{ goods[++goods[0]]=1; goodv[goods[0]]=dataset[ari[j]].value[i]; } kesai[i]=(int)(sqrt(sigma*N/(log(sigma*N)-1))); if(kesai[i]<=0) kesai[i] = goods[0]; average=(int)(ari[0]/kesai[i]); if(goods[0]<=kesai[i]){ //if goods are less than bins, each bin contains a single value kesai[i]=goods[0]; bin=goods[0]; for(j=1;j<=goods[0];++j) lbound[j]=ubound[j]=goodv[j]; } else{ sum=0,bin=0,lastu=1; for(j=1;j<=goods[0];++j) if(bin==kesai[i]-1){ // this is the last bin lbound[bin]=goodv[lastu]; ubound[bin]=goodv[goods[0]]; j=goods[0]; ++bin; break; } else if(sum>average){ // sum is over average, go to next bin sum=goods[j]; lbound[bin]=goodv[lastu]; ubound[bin]=goodv[j-1]; lastu=j; ++bin; } else if(sum+goods[j]<average) sum+=goods[j]; else if((average-sum)<=(sum+goods[j]-average)){ // when putting a value into a bin exactly over the sum, calculate the difference to decide put in into current bin or next bin sum=goods[j]; ubound[bin]=goodv[j-1]; lbound[bin]=goodv[lastu]; lastu=j; ++bin; } else{ sum = 0; ubound[bin]=goodv[j]; lbound[bin]=goodv[lastu]; lastu=j+1; ++bin; } } /* * identify which bin is each object in */ for(j=0;j<N;++j){ if(dataset[j].missing[i]){ whichbin[j]=0; } else{ l=0; while(dominates(dataset[j].value[i],ubound[++l]) == -1); whichbin[j]=l; } } /* * establish Qi,Pi */ if(dataset[obj].missing[i]){ for(j=0;j<N;++j) Pi[i][j]=Qi[i][j]=1; } else{ for(j=0;j<N;++j){ Qi[i][j]=whichbin[obj]<=whichbin[j]; Pi[i][j]=whichbin[obj]<whichbin[j]; } } } /* * to this step calculate Q and P using Pi and Qi */ Qc=-1; for(i=0;i<N;++i){ for(j=0;j<D;++j) if(Qi[j][i]==0) break; if(j==D){ ++Qc; Q[i]=1; } else Q[i]=0; } Q[obj]=0; if(sc==K && Qc<=tau) retval = 0; else{ Pc=0; for(i=0;i<N;++i){ for(j=0;j<D;++j) if(Pi[j][i]==0) break; if(j==D){ ++Pc; P[i]=1; } else P[i]=0; } /* * to this step, P is attained */ omiga=0; for(i=0;i<N;++i) if(P[i]==1 && incomparable[i]==0) ++omiga; nonD[0]=0; for(i=0;i<N;++i) if(P[i]==0 && Q[i]==1){ tagT[i]=0; for(j=0;j<D;++j) if(!dataset[obj].missing[j]){ if(dataset[i].value[j]==dataset[obj].value[j]) tagT[i]++; else if(dominates(dataset[i].value[j],dataset[obj].value[j])==1){ nonD[++nonD[0]]=i; if(sc==K && nonD[0]>Qc-incomparablenumber-tau) return 0; } } pando=0; for(j=0;j<D;++j) pando+=(dataset[i].missing[j]==0 && dataset[obj].missing[j]==0); if(pando==tagT[i]) nonD[++nonD[0]]=i; } /* * calculate the cardinality of two sets and return */ ar=0; for(i=1;i<=nonD[0];++i) Q[nonD[i]]=0; for(i=0;i<N;++i) ar+=(Q[i]==1 && P[i]==0); retval = ar+omiga; } return retval; }