Exemplo n.º 1
0
// Partition blocks in an outer/inner loop pair into blocks before and after
// the loop
static bool partitionOuterLoopBlocks(Loop *L, Loop *SubLoop,
                                     BasicBlockSet &ForeBlocks,
                                     BasicBlockSet &SubLoopBlocks,
                                     BasicBlockSet &AftBlocks,
                                     DominatorTree *DT) {
  BasicBlock *SubLoopLatch = SubLoop->getLoopLatch();
  SubLoopBlocks.insert(SubLoop->block_begin(), SubLoop->block_end());

  for (BasicBlock *BB : L->blocks()) {
    if (!SubLoop->contains(BB)) {
      if (DT->dominates(SubLoopLatch, BB))
        AftBlocks.insert(BB);
      else
        ForeBlocks.insert(BB);
    }
  }

  // Check that all blocks in ForeBlocks together dominate the subloop
  // TODO: This might ideally be done better with a dominator/postdominators.
  BasicBlock *SubLoopPreHeader = SubLoop->getLoopPreheader();
  for (BasicBlock *BB : ForeBlocks) {
    if (BB == SubLoopPreHeader)
      continue;
    TerminatorInst *TI = BB->getTerminator();
    for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
      if (!ForeBlocks.count(TI->getSuccessor(i)))
        return false;
  }

  return true;
}
Exemplo n.º 2
0
/**
 * Starting with an Instruction, traverse the CFG backward on all possible
 * paths, stopping on each path when we hit a task boundary.  Return the set of
 * these task boundaries, sorted by distance (closest first).
 */
void DINOGlobal::CollectBBsPredicated(BasicBlock &BB,
                                      BasicBlockList &visited,
                                      BasicBlockSet &BL,
                                      BBPredicate &Collect,
                                      BBPredicate &Stop){
    for( auto &VB : visited ){
      if( &BB == VB ){
        return;
      }
    }


    if( Collect(BB) ){
        BL.insert(&BB);
    } 

    if( Stop(BB) ){
        return;
    }
   
    /*This fixed a bug where visited was carried along other future
      paths, rather than being popped off after this recursive call
      was complete
    */ 
    BasicBlockList nextVisited(visited);
    nextVisited.push_back(&BB);

    for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); PI != E; ++PI) {
        CollectBBsPredicated(*(*PI), nextVisited, BL, Collect, Stop);
    }

}
Exemplo n.º 3
0
LowerEmAsyncify::BasicBlockSet LowerEmAsyncify::FindReachableBlocksFrom(BasicBlock *src) {
  BasicBlockSet ReachableBlockSet;
  std::vector<BasicBlock*> pending;
  ReachableBlockSet.insert(src);
  pending.push_back(src);
  while (!pending.empty()) {
    BasicBlock *CurBlock = pending.back();
    pending.pop_back();
    for (succ_iterator SI = succ_begin(CurBlock), SE = succ_end(CurBlock); SI != SE; ++SI) {
      if (ReachableBlockSet.count(*SI) == 0) {
        ReachableBlockSet.insert(*SI);
        pending.push_back(*SI);
      }
    }
  }
  return ReachableBlockSet;
}
Exemplo n.º 4
0
/*! Computes the dominator tree from a CFG using algorithm __*/
void PostdominatorTree::computeDT() {
    int end_node = blocksToIndex[cfg->get_exit_block()];

    bool changed = true;
    p_dom[end_node] = end_node;

    report( " Computing tree" );

    while (changed) {
        changed = false;

        // post-order
        for (int b_ind = 0; b_ind < (int)blocks.size(); b_ind++) {
            if (b_ind == end_node)  continue;

            ir::ControlFlowGraph::iterator b = blocks[b_ind];
            assert(!b->successors.empty());
            int new_pdom = 0;
            bool processed = false;

            ir::ControlFlowGraph::pointer_iterator
            succ_it = b->successors.begin();
            for (; succ_it != b->successors.end(); ++succ_it) {
                int p = blocksToIndex[*succ_it];
                assert(p<(int)p_dom.size());
                if (p_dom[p] != -1) {
                    if( !processed ) {
                        new_pdom = p;
                        processed = true;
                    }
                    else {
                        new_pdom = intersect(p, new_pdom);
                    }
                }
            }

            if( processed ) {
                if (p_dom[b_ind] != new_pdom) {
                    p_dom[b_ind] = new_pdom;
                    changed = true;
                }
            }
        }
    }

    dominated.resize(blocks.size());
    for (int n = 0; n < (int)blocks.size(); n++) {
        if (p_dom[n] >= 0) {
            dominated[p_dom[n]].push_back(n);
        }
    }

    report(" Computing frontiers")

    frontiers.resize(blocks.size());
    for (int b_ind = 0; b_ind < (int)blocks.size(); b_ind++) {

        ir::ControlFlowGraph::iterator block = blocks[b_ind];

        if(block->successors.size() < 2) continue;

        typedef std::unordered_set<int> BasicBlockSet;

        BasicBlockSet blocksWithThisBlockInTheirFrontier;

        for (auto successor : block->successors) {
            auto runner = successor;

            while (runner != getPostDominator(block)) {
                blocksWithThisBlockInTheirFrontier.insert(
                    blocksToIndex[runner]);

                runner = getPostDominator(runner);
            }
        }

        for (auto frontierBlock : blocksWithThisBlockInTheirFrontier) {
            frontiers[b_ind].push_back(frontierBlock);
        }
    }
}