Exemple #1
0
// Return true if the call-site has an argument which is a PHI with only
// constant incoming values.
static bool isPredicatedOnPHI(CallSite CS) {
  Instruction *Instr = CS.getInstruction();
  BasicBlock *Parent = Instr->getParent();
  if (Instr != Parent->getFirstNonPHIOrDbg())
    return false;

  for (auto &BI : *Parent) {
    if (PHINode *PN = dyn_cast<PHINode>(&BI)) {
      for (auto &I : CS.args())
        if (&*I == PN) {
          assert(PN->getNumIncomingValues() == 2 &&
                 "Unexpected number of incoming values");
          if (PN->getIncomingBlock(0) == PN->getIncomingBlock(1))
            return false;
          if (PN->getIncomingValue(0) == PN->getIncomingValue(1))
            continue;
          if (isa<Constant>(PN->getIncomingValue(0)) &&
              isa<Constant>(PN->getIncomingValue(1)))
            return true;
        }
    }
    break;
  }
  return false;
}
static bool eliminateTailRecursion(Function &F, const TargetTransformInfo *TTI) {
  if (F.getFnAttribute("disable-tail-calls").getValueAsString() == "true")
    return false;

  bool MadeChange = false;
  bool AllCallsAreTailCalls = false;
  MadeChange |= markTails(F, AllCallsAreTailCalls);
  if (!AllCallsAreTailCalls)
    return MadeChange;

  // If this function is a varargs function, we won't be able to PHI the args
  // right, so don't even try to convert it...
  if (F.getFunctionType()->isVarArg())
    return false;

  BasicBlock *OldEntry = nullptr;
  bool TailCallsAreMarkedTail = false;
  SmallVector<PHINode*, 8> ArgumentPHIs;

  // If false, we cannot perform TRE on tail calls marked with the 'tail'
  // attribute, because doing so would cause the stack size to increase (real
  // TRE would deallocate variable sized allocas, TRE doesn't).
  bool CanTRETailMarkedCall = canTRE(F);

  // Change any tail recursive calls to loops.
  //
  // FIXME: The code generator produces really bad code when an 'escaping
  // alloca' is changed from being a static alloca to being a dynamic alloca.
  // Until this is resolved, disable this transformation if that would ever
  // happen.  This bug is PR962.
  for (Function::iterator BBI = F.begin(), E = F.end(); BBI != E; /*in loop*/) {
    BasicBlock *BB = &*BBI++; // foldReturnAndProcessPred may delete BB.
    if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator())) {
      bool Change =
          processReturningBlock(Ret, OldEntry, TailCallsAreMarkedTail,
                                ArgumentPHIs, !CanTRETailMarkedCall, TTI);
      if (!Change && BB->getFirstNonPHIOrDbg() == Ret)
        Change =
            foldReturnAndProcessPred(BB, Ret, OldEntry, TailCallsAreMarkedTail,
                                     ArgumentPHIs, !CanTRETailMarkedCall, TTI);
      MadeChange |= Change;
    }
  }

  // If we eliminated any tail recursions, it's possible that we inserted some
  // silly PHI nodes which just merge an initial value (the incoming operand)
  // with themselves.  Check to see if we did and clean up our mess if so.  This
  // occurs when a function passes an argument straight through to its tail
  // call.
  for (PHINode *PN : ArgumentPHIs) {
    // If the PHI Node is a dynamic constant, replace it with the value it is.
    if (Value *PNV = SimplifyInstruction(PN, F.getParent()->getDataLayout())) {
      PN->replaceAllUsesWith(PNV);
      PN->eraseFromParent();
    }
  }

  return MadeChange;
}
Exemple #3
0
    void BBTraversalHelper::getAllReachableBBs(BasicBlock *startBB, std::vector<BasicBlock*> &targetBBs,
                                            std::vector<BasicBlock*> &reachableBBs) {
        for(unsigned int i=0; i < targetBBs.size(); i++) {
            BasicBlock *endBB = targetBBs[i];
            Instruction *dstInst = endBB->getFirstNonPHIOrDbg();
            if (BBTraversalHelper::isPotentiallyReachable(startBB->getFirstNonPHIOrDbg(), dstInst)) {
                reachableBBs.insert(reachableBBs.end(), endBB);
            }

        }
    }
Exemple #4
0
/// MoveExceptionValueCalls - Ensure that eh.exception is only ever called from
/// landing pads by replacing calls outside of landing pads with direct use of
/// a register holding the appropriate value; this requires adding calls inside
/// all landing pads to initialize the register.  Also, move eh.exception calls
/// inside landing pads to the start of the landing pad (optional, but may make
/// things simpler for later passes).
bool DwarfEHPrepare::MoveExceptionValueCalls() {
  // If the eh.exception intrinsic is not declared in the module then there is
  // nothing to do.  Speed up compilation by checking for this common case.
  if (!ExceptionValueIntrinsic &&
      !F->getParent()->getFunction(Intrinsic::getName(Intrinsic::eh_exception)))
    return false;

  bool Changed = false;

  // Move calls to eh.exception that are inside a landing pad to the start of
  // the landing pad.
  for (BBSet::const_iterator LI = LandingPads.begin(), LE = LandingPads.end();
       LI != LE; ++LI) {
    BasicBlock *LP = *LI;
    for (BasicBlock::iterator II = LP->getFirstNonPHIOrDbg(), IE = LP->end();
         II != IE;)
      if (EHExceptionInst *EI = dyn_cast<EHExceptionInst>(II++)) {
        // Found a call to eh.exception.
        if (!EI->use_empty()) {
          // If there is already a call to eh.exception at the start of the
          // landing pad, then get hold of it; otherwise create such a call.
          Value *CallAtStart = CreateExceptionValueCall(LP);

          // If the call was at the start of a landing pad then leave it alone.
          if (EI == CallAtStart)
            continue;
          EI->replaceAllUsesWith(CallAtStart);
        }
        EI->eraseFromParent();
        ++NumExceptionValuesMoved;
        Changed = true;
      }
  }

  // Look for calls to eh.exception that are not in a landing pad.  If one is
  // found, then a register that holds the exception value will be created in
  // each landing pad, and the SSAUpdater will be used to compute the values
  // returned by eh.exception calls outside of landing pads.
  SSAUpdater SSA;

  // Remember where we found the eh.exception call, to avoid rescanning earlier
  // basic blocks which we already know contain no eh.exception calls.
  bool FoundCallOutsideLandingPad = false;
  Function::iterator BB = F->begin();
  for (Function::iterator BE = F->end(); BB != BE; ++BB) {
    // Skip over landing pads.
    if (LandingPads.count(BB))
      continue;

    for (BasicBlock::iterator II = BB->getFirstNonPHIOrDbg(), IE = BB->end();
         II != IE; ++II)
      if (isa<EHExceptionInst>(II)) {
        SSA.Initialize(II->getType(), II->getName());
        FoundCallOutsideLandingPad = true;
        break;
      }

    if (FoundCallOutsideLandingPad)
      break;
  }

  // If all calls to eh.exception are in landing pads then we are done.
  if (!FoundCallOutsideLandingPad)
    return Changed;

  // Add a call to eh.exception at the start of each landing pad, and tell the
  // SSAUpdater that this is the value produced by the landing pad.
  for (BBSet::iterator LI = LandingPads.begin(), LE = LandingPads.end();
       LI != LE; ++LI)
    SSA.AddAvailableValue(*LI, CreateExceptionValueCall(*LI));

  // Now turn all calls to eh.exception that are not in a landing pad into a use
  // of the appropriate register.
  for (Function::iterator BE = F->end(); BB != BE; ++BB) {
    // Skip over landing pads.
    if (LandingPads.count(BB))
      continue;

    for (BasicBlock::iterator II = BB->getFirstNonPHIOrDbg(), IE = BB->end();
         II != IE;)
      if (EHExceptionInst *EI = dyn_cast<EHExceptionInst>(II++)) {
        // Found a call to eh.exception, replace it with the value from any
        // upstream landing pad(s).
        EI->replaceAllUsesWith(SSA.GetValueAtEndOfBlock(BB));
        EI->eraseFromParent();
        ++NumExceptionValuesMoved;
      }
  }

  return true;
}