// 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; }
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); } } }
/// 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; }