Beispiel #1
0
// moveExitCondition - Move exit condition EC into split condition block CondBB.
void LoopIndexSplit::moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB,
                                       BasicBlock *ExitBB, ICmpInst *EC, 
                                       ICmpInst *SC, PHINode *IV, 
                                       Instruction *IVAdd, Loop *LP,
                                       unsigned ExitValueNum) {

  BasicBlock *ExitingBB = EC->getParent();
  Instruction *CurrentBR = CondBB->getTerminator();

  // Move exit condition into split condition block.
  EC->moveBefore(CurrentBR);
  EC->setOperand(ExitValueNum == 0 ? 1 : 0, IV);

  // Move exiting block's branch into split condition block. Update its branch
  // destination.
  BranchInst *ExitingBR = cast<BranchInst>(ExitingBB->getTerminator());
  ExitingBR->moveBefore(CurrentBR);
  BasicBlock *OrigDestBB = NULL;
  if (ExitingBR->getSuccessor(0) == ExitBB) {
    OrigDestBB = ExitingBR->getSuccessor(1);
    ExitingBR->setSuccessor(1, ActiveBB);
  }
  else {
    OrigDestBB = ExitingBR->getSuccessor(0);
    ExitingBR->setSuccessor(0, ActiveBB);
  }
    
  // Remove split condition and current split condition branch.
  SC->eraseFromParent();
  CurrentBR->eraseFromParent();

  // Connect exiting block to original destination.
  BranchInst::Create(OrigDestBB, ExitingBB);

  // Update PHINodes
  updatePHINodes(ExitBB, ExitingBB, CondBB, IV, IVAdd, LP);

  // Fix dominator info.
  // ExitBB is now dominated by CondBB
  DT->changeImmediateDominator(ExitBB, CondBB);
  DF->changeImmediateDominator(ExitBB, CondBB, DT);

  // Blocks outside the loop may have been in the dominance frontier of blocks
  // inside the condition; this is now impossible because the blocks inside the
  // condition no loger dominate the exit.  Remove the relevant blocks from
  // the dominance frontiers.
  for (Loop::block_iterator I = LP->block_begin(), E = LP->block_end();
       I != E; ++I) {
    if (*I == CondBB || !DT->dominates(CondBB, *I)) continue;
    DominanceFrontier::iterator BBDF = DF->find(*I);
    DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin();
    DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end();
    while (DomSetI != DomSetE) {
      DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI;
      ++DomSetI;
      BasicBlock *DFBB = *CurrentItr;
      if (!LP->contains(DFBB))
        BBDF->second.erase(DFBB);
    }
  }
}
bool LoopBogusCF::runOnLoop(Loop *loop, LPPassManager &LPM) {
  if (disableLoopBcf)
    return false;

  ++NumLoops;
  DEBUG(errs() << "LoopBogusCF: Dumping loop info\n");
  // DEBUG(loop->dump());

  BasicBlock *header = loop->getHeader();

  BranchInst *branch = dyn_cast<BranchInst>(header->getTerminator());
  if (!branch || !branch->isConditional()) {
    DEBUG(errs() << "\t Not trivial loop -- skipping\n");
    return false;
  }

  if (!loop->isLoopSimplifyForm()) {
    DEBUG(errs() << "\t Not simplified loop -- skipping\n");
    return false;
  }

  BasicBlock *exitBlock = loop->getUniqueExitBlock();
  if (!exitBlock) {
    DEBUG(errs() << "\t No unique exit block -- skipping\n");
    return false;
  }

  if (branch->getSuccessor(0) != exitBlock &&
      branch->getSuccessor(1) != exitBlock) {
    DEBUG(errs() << "\t Not trivial loop -- skipping\n");
    return false;
  }

  ++NumLoopsObf;
  // DEBUG(header->getParent()->viewCFG());

  DEBUG(errs() << "\tCreating dummy block\n");
  LoopInfo &info = getAnalysis<LoopInfo>();
  // Split header block
  BasicBlock *dummy = header->splitBasicBlock(header->getTerminator());
  loop->addBasicBlockToLoop(dummy, info.getBase());

  BasicBlock *trueBlock, *falseBlock = exitBlock;

  if (branch->getSuccessor(0) == exitBlock) {
    trueBlock = branch->getSuccessor(1);
    branch->setSuccessor(1, dummy);
  } else {
    trueBlock = branch->getSuccessor(0);
    branch->setSuccessor(0, dummy);
  }

  branch->moveBefore(header->getTerminator());
  header->getTerminator()->eraseFromParent();

  OpaquePredicate::createStub(dummy, trueBlock, falseBlock,
                              OpaquePredicate::PredicateTrue, false);

  // DEBUG(header->getParent()->viewCFG());

  return true;
}