189f22417SPhilip Reames //===- MustExecute.cpp - Printer for isGuaranteedToExecute ----------------===//
289f22417SPhilip Reames //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
689f22417SPhilip Reames //
789f22417SPhilip Reames //===----------------------------------------------------------------------===//
889f22417SPhilip Reames
9e4b728e8SPhilip Reames #include "llvm/Analysis/MustExecute.h"
10a5b10b46SJohannes Doerfert #include "llvm/ADT/PostOrderIterator.h"
116cedffc0SKazu Hirata #include "llvm/ADT/StringExtras.h"
12a5b10b46SJohannes Doerfert #include "llvm/Analysis/CFG.h"
1323aed5efSPhilip Reames #include "llvm/Analysis/InstructionSimplify.h"
1489f22417SPhilip Reames #include "llvm/Analysis/LoopInfo.h"
1589f22417SPhilip Reames #include "llvm/Analysis/Passes.h"
16fe799c97SJohannes Doerfert #include "llvm/Analysis/PostDominators.h"
1705da2fe5SReid Kleckner #include "llvm/Analysis/ValueTracking.h"
18ce998adfSPhilip Reames #include "llvm/IR/AssemblyAnnotationWriter.h"
1906926e0fSArthur Eubanks #include "llvm/IR/Dominators.h"
2089f22417SPhilip Reames #include "llvm/IR/InstIterator.h"
2189f22417SPhilip Reames #include "llvm/IR/Module.h"
2206926e0fSArthur Eubanks #include "llvm/IR/PassManager.h"
2305da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
24ce998adfSPhilip Reames #include "llvm/Support/FormattedStream.h"
2589f22417SPhilip Reames #include "llvm/Support/raw_ostream.h"
26a5b10b46SJohannes Doerfert
2789f22417SPhilip Reames using namespace llvm;
2889f22417SPhilip Reames
29a5b10b46SJohannes Doerfert #define DEBUG_TYPE "must-execute"
30a5b10b46SJohannes Doerfert
318d56be70SMax Kazantsev const DenseMap<BasicBlock *, ColorVector> &
getBlockColors() const328d56be70SMax Kazantsev LoopSafetyInfo::getBlockColors() const {
338d56be70SMax Kazantsev return BlockColors;
348d56be70SMax Kazantsev }
358d56be70SMax Kazantsev
copyColors(BasicBlock * New,BasicBlock * Old)368d56be70SMax Kazantsev void LoopSafetyInfo::copyColors(BasicBlock *New, BasicBlock *Old) {
378d56be70SMax Kazantsev ColorVector &ColorsForNewBlock = BlockColors[New];
388d56be70SMax Kazantsev ColorVector &ColorsForOldBlock = BlockColors[Old];
398d56be70SMax Kazantsev ColorsForNewBlock = ColorsForOldBlock;
408d56be70SMax Kazantsev }
418d56be70SMax Kazantsev
blockMayThrow(const BasicBlock * BB) const429c90ec2fSMax Kazantsev bool SimpleLoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const {
436a4f5e2aSMax Kazantsev (void)BB;
446a4f5e2aSMax Kazantsev return anyBlockMayThrow();
456a4f5e2aSMax Kazantsev }
466a4f5e2aSMax Kazantsev
anyBlockMayThrow() const479c90ec2fSMax Kazantsev bool SimpleLoopSafetyInfo::anyBlockMayThrow() const {
48530b8d1cSMax Kazantsev return MayThrow;
49530b8d1cSMax Kazantsev }
50530b8d1cSMax Kazantsev
computeLoopSafetyInfo(const Loop * CurLoop)519c90ec2fSMax Kazantsev void SimpleLoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
52a57d7139SShoaib Meenai assert(CurLoop != nullptr && "CurLoop can't be null");
5323aed5efSPhilip Reames BasicBlock *Header = CurLoop->getHeader();
5423aed5efSPhilip Reames // Iterate over header and compute safety info.
55530b8d1cSMax Kazantsev HeaderMayThrow = !isGuaranteedToTransferExecutionToSuccessor(Header);
56530b8d1cSMax Kazantsev MayThrow = HeaderMayThrow;
5723aed5efSPhilip Reames // Iterate over loop instructions and compute safety info.
5823aed5efSPhilip Reames // Skip header as it has been computed and stored in HeaderMayThrow.
5923aed5efSPhilip Reames // The first block in loopinfo.Blocks is guaranteed to be the header.
6023aed5efSPhilip Reames assert(Header == *CurLoop->getBlocks().begin() &&
6123aed5efSPhilip Reames "First block must be header");
6223aed5efSPhilip Reames for (Loop::block_iterator BB = std::next(CurLoop->block_begin()),
6323aed5efSPhilip Reames BBE = CurLoop->block_end();
64530b8d1cSMax Kazantsev (BB != BBE) && !MayThrow; ++BB)
65530b8d1cSMax Kazantsev MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(*BB);
6623aed5efSPhilip Reames
678d56be70SMax Kazantsev computeBlockColors(CurLoop);
688d56be70SMax Kazantsev }
698d56be70SMax Kazantsev
blockMayThrow(const BasicBlock * BB) const705f9acd27SMax Kazantsev bool ICFLoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const {
715f9acd27SMax Kazantsev return ICF.hasICF(BB);
725f9acd27SMax Kazantsev }
735f9acd27SMax Kazantsev
anyBlockMayThrow() const745f9acd27SMax Kazantsev bool ICFLoopSafetyInfo::anyBlockMayThrow() const {
755f9acd27SMax Kazantsev return MayThrow;
765f9acd27SMax Kazantsev }
775f9acd27SMax Kazantsev
computeLoopSafetyInfo(const Loop * CurLoop)785f9acd27SMax Kazantsev void ICFLoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
795f9acd27SMax Kazantsev assert(CurLoop != nullptr && "CurLoop can't be null");
805f9acd27SMax Kazantsev ICF.clear();
817d49a3a8SMax Kazantsev MW.clear();
825f9acd27SMax Kazantsev MayThrow = false;
835f9acd27SMax Kazantsev // Figure out the fact that at least one block may throw.
84*601b3a13SKazu Hirata for (const auto &BB : CurLoop->blocks())
855f9acd27SMax Kazantsev if (ICF.hasICF(&*BB)) {
865f9acd27SMax Kazantsev MayThrow = true;
875f9acd27SMax Kazantsev break;
885f9acd27SMax Kazantsev }
895f9acd27SMax Kazantsev computeBlockColors(CurLoop);
905f9acd27SMax Kazantsev }
915f9acd27SMax Kazantsev
insertInstructionTo(const Instruction * Inst,const BasicBlock * BB)924615a505SMax Kazantsev void ICFLoopSafetyInfo::insertInstructionTo(const Instruction *Inst,
934615a505SMax Kazantsev const BasicBlock *BB) {
944615a505SMax Kazantsev ICF.insertInstructionTo(Inst, BB);
954615a505SMax Kazantsev MW.insertInstructionTo(Inst, BB);
965f9acd27SMax Kazantsev }
975f9acd27SMax Kazantsev
removeInstruction(const Instruction * Inst)98bb84407fSMax Kazantsev void ICFLoopSafetyInfo::removeInstruction(const Instruction *Inst) {
994615a505SMax Kazantsev ICF.removeInstruction(Inst);
1004615a505SMax Kazantsev MW.removeInstruction(Inst);
101bb84407fSMax Kazantsev }
102bb84407fSMax Kazantsev
computeBlockColors(const Loop * CurLoop)1038d56be70SMax Kazantsev void LoopSafetyInfo::computeBlockColors(const Loop *CurLoop) {
10423aed5efSPhilip Reames // Compute funclet colors if we might sink/hoist in a function with a funclet
10523aed5efSPhilip Reames // personality routine.
10623aed5efSPhilip Reames Function *Fn = CurLoop->getHeader()->getParent();
10723aed5efSPhilip Reames if (Fn->hasPersonalityFn())
10823aed5efSPhilip Reames if (Constant *PersonalityFn = Fn->getPersonalityFn())
109b4be38fcSHeejin Ahn if (isScopedEHPersonality(classifyEHPersonality(PersonalityFn)))
110530b8d1cSMax Kazantsev BlockColors = colorEHFunclets(*Fn);
11123aed5efSPhilip Reames }
11223aed5efSPhilip Reames
11323aed5efSPhilip Reames /// Return true if we can prove that the given ExitBlock is not reached on the
11423aed5efSPhilip Reames /// first iteration of the given loop. That is, the backedge of the loop must
11523aed5efSPhilip Reames /// be executed before the ExitBlock is executed in any dynamic execution trace.
CanProveNotTakenFirstIteration(const BasicBlock * ExitBlock,const DominatorTree * DT,const Loop * CurLoop)116a7415874SMax Kazantsev static bool CanProveNotTakenFirstIteration(const BasicBlock *ExitBlock,
11723aed5efSPhilip Reames const DominatorTree *DT,
11823aed5efSPhilip Reames const Loop *CurLoop) {
11923aed5efSPhilip Reames auto *CondExitBlock = ExitBlock->getSinglePredecessor();
12023aed5efSPhilip Reames if (!CondExitBlock)
12123aed5efSPhilip Reames // expect unique exits
12223aed5efSPhilip Reames return false;
12323aed5efSPhilip Reames assert(CurLoop->contains(CondExitBlock) && "meaning of exit block");
12423aed5efSPhilip Reames auto *BI = dyn_cast<BranchInst>(CondExitBlock->getTerminator());
12523aed5efSPhilip Reames if (!BI || !BI->isConditional())
12623aed5efSPhilip Reames return false;
1275095883fSSerguei Katkov // If condition is constant and false leads to ExitBlock then we always
1285095883fSSerguei Katkov // execute the true branch.
1295095883fSSerguei Katkov if (auto *Cond = dyn_cast<ConstantInt>(BI->getCondition()))
1305095883fSSerguei Katkov return BI->getSuccessor(Cond->getZExtValue() ? 1 : 0) == ExitBlock;
13123aed5efSPhilip Reames auto *Cond = dyn_cast<CmpInst>(BI->getCondition());
13223aed5efSPhilip Reames if (!Cond)
13323aed5efSPhilip Reames return false;
13423aed5efSPhilip Reames // todo: this would be a lot more powerful if we used scev, but all the
13523aed5efSPhilip Reames // plumbing is currently missing to pass a pointer in from the pass
13623aed5efSPhilip Reames // Check for cmp (phi [x, preheader] ...), y where (pred x, y is known
13723aed5efSPhilip Reames auto *LHS = dyn_cast<PHINode>(Cond->getOperand(0));
13823aed5efSPhilip Reames auto *RHS = Cond->getOperand(1);
13923aed5efSPhilip Reames if (!LHS || LHS->getParent() != CurLoop->getHeader())
14023aed5efSPhilip Reames return false;
14123aed5efSPhilip Reames auto DL = ExitBlock->getModule()->getDataLayout();
14223aed5efSPhilip Reames auto *IVStart = LHS->getIncomingValueForBlock(CurLoop->getLoopPreheader());
143b8c2781fSSimon Moll auto *SimpleValOrNull = simplifyCmpInst(Cond->getPredicate(),
14423aed5efSPhilip Reames IVStart, RHS,
14523aed5efSPhilip Reames {DL, /*TLI*/ nullptr,
14623aed5efSPhilip Reames DT, /*AC*/ nullptr, BI});
14723aed5efSPhilip Reames auto *SimpleCst = dyn_cast_or_null<Constant>(SimpleValOrNull);
14823aed5efSPhilip Reames if (!SimpleCst)
14923aed5efSPhilip Reames return false;
15023aed5efSPhilip Reames if (ExitBlock == BI->getSuccessor(0))
15123aed5efSPhilip Reames return SimpleCst->isZeroValue();
15223aed5efSPhilip Reames assert(ExitBlock == BI->getSuccessor(1) && "implied by above");
15323aed5efSPhilip Reames return SimpleCst->isAllOnesValue();
15423aed5efSPhilip Reames }
15523aed5efSPhilip Reames
1564855b74fSMax Kazantsev /// Collect all blocks from \p CurLoop which lie on all possible paths from
1574855b74fSMax Kazantsev /// the header of \p CurLoop (inclusive) to BB (exclusive) into the set
1584855b74fSMax Kazantsev /// \p Predecessors. If \p BB is the header, \p Predecessors will be empty.
collectTransitivePredecessors(const Loop * CurLoop,const BasicBlock * BB,SmallPtrSetImpl<const BasicBlock * > & Predecessors)1594855b74fSMax Kazantsev static void collectTransitivePredecessors(
160bfbd4d1fSMax Kazantsev const Loop *CurLoop, const BasicBlock *BB,
1614855b74fSMax Kazantsev SmallPtrSetImpl<const BasicBlock *> &Predecessors) {
162bfbd4d1fSMax Kazantsev assert(Predecessors.empty() && "Garbage in predecessors set?");
1637b78d392SMax Kazantsev assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");
1647b78d392SMax Kazantsev if (BB == CurLoop->getHeader())
165bfbd4d1fSMax Kazantsev return;
1667b78d392SMax Kazantsev SmallVector<const BasicBlock *, 4> WorkList;
167*601b3a13SKazu Hirata for (const auto *Pred : predecessors(BB)) {
1687b78d392SMax Kazantsev Predecessors.insert(Pred);
1697b78d392SMax Kazantsev WorkList.push_back(Pred);
1707b78d392SMax Kazantsev }
1717b78d392SMax Kazantsev while (!WorkList.empty()) {
1727b78d392SMax Kazantsev auto *Pred = WorkList.pop_back_val();
1737b78d392SMax Kazantsev assert(CurLoop->contains(Pred) && "Should only reach loop blocks!");
1747b78d392SMax Kazantsev // We are not interested in backedges and we don't want to leave loop.
1757b78d392SMax Kazantsev if (Pred == CurLoop->getHeader())
1767b78d392SMax Kazantsev continue;
1777b78d392SMax Kazantsev // TODO: If BB lies in an inner loop of CurLoop, this will traverse over all
1787b78d392SMax Kazantsev // blocks of this inner loop, even those that are always executed AFTER the
1797b78d392SMax Kazantsev // BB. It may make our analysis more conservative than it could be, see test
1807b78d392SMax Kazantsev // @nested and @nested_no_throw in test/Analysis/MustExecute/loop-header.ll.
1817b78d392SMax Kazantsev // We can ignore backedge of all loops containing BB to get a sligtly more
1827b78d392SMax Kazantsev // optimistic result.
183*601b3a13SKazu Hirata for (const auto *PredPred : predecessors(Pred))
1847b78d392SMax Kazantsev if (Predecessors.insert(PredPred).second)
1857b78d392SMax Kazantsev WorkList.push_back(PredPred);
1867b78d392SMax Kazantsev }
187bfbd4d1fSMax Kazantsev }
188bfbd4d1fSMax Kazantsev
allLoopPathsLeadToBlock(const Loop * CurLoop,const BasicBlock * BB,const DominatorTree * DT) const189bfbd4d1fSMax Kazantsev bool LoopSafetyInfo::allLoopPathsLeadToBlock(const Loop *CurLoop,
190bfbd4d1fSMax Kazantsev const BasicBlock *BB,
191bfbd4d1fSMax Kazantsev const DominatorTree *DT) const {
192bfbd4d1fSMax Kazantsev assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");
193bfbd4d1fSMax Kazantsev
194bfbd4d1fSMax Kazantsev // Fast path: header is always reached once the loop is entered.
195bfbd4d1fSMax Kazantsev if (BB == CurLoop->getHeader())
196bfbd4d1fSMax Kazantsev return true;
197bfbd4d1fSMax Kazantsev
198bfbd4d1fSMax Kazantsev // Collect all transitive predecessors of BB in the same loop. This set will
199bfbd4d1fSMax Kazantsev // be a subset of the blocks within the loop.
200bfbd4d1fSMax Kazantsev SmallPtrSet<const BasicBlock *, 4> Predecessors;
201bfbd4d1fSMax Kazantsev collectTransitivePredecessors(CurLoop, BB, Predecessors);
2027b78d392SMax Kazantsev
2033860aad6SXing Xue // Make sure that all successors of, all predecessors of BB which are not
2043860aad6SXing Xue // dominated by BB, are either:
2057b78d392SMax Kazantsev // 1) BB,
2067b78d392SMax Kazantsev // 2) Also predecessors of BB,
2077b78d392SMax Kazantsev // 3) Exit blocks which are not taken on 1st iteration.
2087b78d392SMax Kazantsev // Memoize blocks we've already checked.
2097b78d392SMax Kazantsev SmallPtrSet<const BasicBlock *, 4> CheckedSuccessors;
210*601b3a13SKazu Hirata for (const auto *Pred : Predecessors) {
2116a4f5e2aSMax Kazantsev // Predecessor block may throw, so it has a side exit.
2126a4f5e2aSMax Kazantsev if (blockMayThrow(Pred))
2136a4f5e2aSMax Kazantsev return false;
2143860aad6SXing Xue
2153860aad6SXing Xue // BB dominates Pred, so if Pred runs, BB must run.
2163860aad6SXing Xue // This is true when Pred is a loop latch.
2173860aad6SXing Xue if (DT->dominates(BB, Pred))
2183860aad6SXing Xue continue;
2193860aad6SXing Xue
220*601b3a13SKazu Hirata for (const auto *Succ : successors(Pred))
2217b78d392SMax Kazantsev if (CheckedSuccessors.insert(Succ).second &&
2227b78d392SMax Kazantsev Succ != BB && !Predecessors.count(Succ))
2237b78d392SMax Kazantsev // By discharging conditions that are not executed on the 1st iteration,
2247b78d392SMax Kazantsev // we guarantee that *at least* on the first iteration all paths from
2257b78d392SMax Kazantsev // header that *may* execute will lead us to the block of interest. So
2267b78d392SMax Kazantsev // that if we had virtually peeled one iteration away, in this peeled
2277b78d392SMax Kazantsev // iteration the set of predecessors would contain only paths from
2287b78d392SMax Kazantsev // header to BB without any exiting edges that may execute.
2297b78d392SMax Kazantsev //
2307b78d392SMax Kazantsev // TODO: We only do it for exiting edges currently. We could use the
2317b78d392SMax Kazantsev // same function to skip some of the edges within the loop if we know
2327b78d392SMax Kazantsev // that they will not be taken on the 1st iteration.
2337b78d392SMax Kazantsev //
2347b78d392SMax Kazantsev // TODO: If we somehow know the number of iterations in loop, the same
2357b78d392SMax Kazantsev // check may be done for any arbitrary N-th iteration as long as N is
2367b78d392SMax Kazantsev // not greater than minimum number of iterations in this loop.
2377b78d392SMax Kazantsev if (CurLoop->contains(Succ) ||
2387b78d392SMax Kazantsev !CanProveNotTakenFirstIteration(Succ, DT, CurLoop))
2397b78d392SMax Kazantsev return false;
2406a4f5e2aSMax Kazantsev }
2417b78d392SMax Kazantsev
2427b78d392SMax Kazantsev // All predecessors can only lead us to BB.
2437b78d392SMax Kazantsev return true;
2447b78d392SMax Kazantsev }
2457b78d392SMax Kazantsev
24623aed5efSPhilip Reames /// Returns true if the instruction in a loop is guaranteed to execute at least
24723aed5efSPhilip Reames /// once.
isGuaranteedToExecute(const Instruction & Inst,const DominatorTree * DT,const Loop * CurLoop) const2489c90ec2fSMax Kazantsev bool SimpleLoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,
249c8466f93SMax Kazantsev const DominatorTree *DT,
250c8466f93SMax Kazantsev const Loop *CurLoop) const {
25123aed5efSPhilip Reames // If the instruction is in the header block for the loop (which is very
25223aed5efSPhilip Reames // common), it is always guaranteed to dominate the exit blocks. Since this
25323aed5efSPhilip Reames // is a common case, and can save some work, check it now.
25423aed5efSPhilip Reames if (Inst.getParent() == CurLoop->getHeader())
25523aed5efSPhilip Reames // If there's a throw in the header block, we can't guarantee we'll reach
256e4ec473bSPhilip Reames // Inst unless we can prove that Inst comes before the potential implicit
257e4ec473bSPhilip Reames // exit. At the moment, we use a (cheap) hack for the common case where
258e4ec473bSPhilip Reames // the instruction of interest is the first one in the block.
25987de55adSMax Kazantsev return !HeaderMayThrow ||
26005b6a533SDavid Stenberg Inst.getParent()->getFirstNonPHIOrDbg() == &Inst;
26123aed5efSPhilip Reames
2627b78d392SMax Kazantsev // If there is a path from header to exit or latch that doesn't lead to our
2637b78d392SMax Kazantsev // instruction's block, return false.
26487de55adSMax Kazantsev return allLoopPathsLeadToBlock(CurLoop, Inst.getParent(), DT);
26523aed5efSPhilip Reames }
26623aed5efSPhilip Reames
isGuaranteedToExecute(const Instruction & Inst,const DominatorTree * DT,const Loop * CurLoop) const2675f9acd27SMax Kazantsev bool ICFLoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,
2685f9acd27SMax Kazantsev const DominatorTree *DT,
2695f9acd27SMax Kazantsev const Loop *CurLoop) const {
2705f9acd27SMax Kazantsev return !ICF.isDominatedByICFIFromSameBlock(&Inst) &&
2715f9acd27SMax Kazantsev allLoopPathsLeadToBlock(CurLoop, Inst.getParent(), DT);
2725f9acd27SMax Kazantsev }
27323aed5efSPhilip Reames
doesNotWriteMemoryBefore(const BasicBlock * BB,const Loop * CurLoop) const2747d49a3a8SMax Kazantsev bool ICFLoopSafetyInfo::doesNotWriteMemoryBefore(const BasicBlock *BB,
2757d49a3a8SMax Kazantsev const Loop *CurLoop) const {
2767d49a3a8SMax Kazantsev assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");
2777d49a3a8SMax Kazantsev
2787d49a3a8SMax Kazantsev // Fast path: there are no instructions before header.
2797d49a3a8SMax Kazantsev if (BB == CurLoop->getHeader())
2807d49a3a8SMax Kazantsev return true;
2817d49a3a8SMax Kazantsev
2827d49a3a8SMax Kazantsev // Collect all transitive predecessors of BB in the same loop. This set will
2837d49a3a8SMax Kazantsev // be a subset of the blocks within the loop.
2847d49a3a8SMax Kazantsev SmallPtrSet<const BasicBlock *, 4> Predecessors;
2857d49a3a8SMax Kazantsev collectTransitivePredecessors(CurLoop, BB, Predecessors);
2867d49a3a8SMax Kazantsev // Find if there any instruction in either predecessor that could write
2877d49a3a8SMax Kazantsev // to memory.
288*601b3a13SKazu Hirata for (const auto *Pred : Predecessors)
2897d49a3a8SMax Kazantsev if (MW.mayWriteToMemory(Pred))
2907d49a3a8SMax Kazantsev return false;
2917d49a3a8SMax Kazantsev return true;
2927d49a3a8SMax Kazantsev }
2937d49a3a8SMax Kazantsev
doesNotWriteMemoryBefore(const Instruction & I,const Loop * CurLoop) const2947d49a3a8SMax Kazantsev bool ICFLoopSafetyInfo::doesNotWriteMemoryBefore(const Instruction &I,
2957d49a3a8SMax Kazantsev const Loop *CurLoop) const {
2967d49a3a8SMax Kazantsev auto *BB = I.getParent();
2977d49a3a8SMax Kazantsev assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");
2987d49a3a8SMax Kazantsev return !MW.isDominatedByMemoryWriteFromSameBlock(&I) &&
2997d49a3a8SMax Kazantsev doesNotWriteMemoryBefore(BB, CurLoop);
3007d49a3a8SMax Kazantsev }
3017d49a3a8SMax Kazantsev
30289f22417SPhilip Reames namespace {
30389f22417SPhilip Reames struct MustExecutePrinter : public FunctionPass {
30489f22417SPhilip Reames
30589f22417SPhilip Reames static char ID; // Pass identification, replacement for typeid
MustExecutePrinter__anon1111126f0111::MustExecutePrinter30689f22417SPhilip Reames MustExecutePrinter() : FunctionPass(ID) {
30789f22417SPhilip Reames initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
30889f22417SPhilip Reames }
getAnalysisUsage__anon1111126f0111::MustExecutePrinter30989f22417SPhilip Reames void getAnalysisUsage(AnalysisUsage &AU) const override {
31089f22417SPhilip Reames AU.setPreservesAll();
31189f22417SPhilip Reames AU.addRequired<DominatorTreeWrapperPass>();
31289f22417SPhilip Reames AU.addRequired<LoopInfoWrapperPass>();
31389f22417SPhilip Reames }
31489f22417SPhilip Reames bool runOnFunction(Function &F) override;
31589f22417SPhilip Reames };
316a5b10b46SJohannes Doerfert struct MustBeExecutedContextPrinter : public ModulePass {
317a5b10b46SJohannes Doerfert static char ID;
318a5b10b46SJohannes Doerfert
MustBeExecutedContextPrinter__anon1111126f0111::MustBeExecutedContextPrinter319a5b10b46SJohannes Doerfert MustBeExecutedContextPrinter() : ModulePass(ID) {
32006926e0fSArthur Eubanks initializeMustBeExecutedContextPrinterPass(
32106926e0fSArthur Eubanks *PassRegistry::getPassRegistry());
322a5b10b46SJohannes Doerfert }
getAnalysisUsage__anon1111126f0111::MustBeExecutedContextPrinter323a5b10b46SJohannes Doerfert void getAnalysisUsage(AnalysisUsage &AU) const override {
324a5b10b46SJohannes Doerfert AU.setPreservesAll();
325a5b10b46SJohannes Doerfert }
326a5b10b46SJohannes Doerfert bool runOnModule(Module &M) override;
327a5b10b46SJohannes Doerfert };
32889f22417SPhilip Reames }
32989f22417SPhilip Reames
33089f22417SPhilip Reames char MustExecutePrinter::ID = 0;
33189f22417SPhilip Reames INITIALIZE_PASS_BEGIN(MustExecutePrinter, "print-mustexecute",
33289f22417SPhilip Reames "Instructions which execute on loop entry", false, true)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)33389f22417SPhilip Reames INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
33489f22417SPhilip Reames INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
33589f22417SPhilip Reames INITIALIZE_PASS_END(MustExecutePrinter, "print-mustexecute",
33689f22417SPhilip Reames "Instructions which execute on loop entry", false, true)
33789f22417SPhilip Reames
33889f22417SPhilip Reames FunctionPass *llvm::createMustExecutePrinter() {
33989f22417SPhilip Reames return new MustExecutePrinter();
34089f22417SPhilip Reames }
34189f22417SPhilip Reames
342a5b10b46SJohannes Doerfert char MustBeExecutedContextPrinter::ID = 0;
34306926e0fSArthur Eubanks INITIALIZE_PASS_BEGIN(MustBeExecutedContextPrinter,
34406926e0fSArthur Eubanks "print-must-be-executed-contexts",
34506926e0fSArthur Eubanks "print the must-be-executed-context for all instructions",
34606926e0fSArthur Eubanks false, true)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)347a5b10b46SJohannes Doerfert INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
348a5b10b46SJohannes Doerfert INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
349a5b10b46SJohannes Doerfert INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
350a5b10b46SJohannes Doerfert INITIALIZE_PASS_END(MustBeExecutedContextPrinter,
351a5b10b46SJohannes Doerfert "print-must-be-executed-contexts",
35206926e0fSArthur Eubanks "print the must-be-executed-context for all instructions",
353a5b10b46SJohannes Doerfert false, true)
354a5b10b46SJohannes Doerfert
355a5b10b46SJohannes Doerfert ModulePass *llvm::createMustBeExecutedContextPrinter() {
356a5b10b46SJohannes Doerfert return new MustBeExecutedContextPrinter();
357a5b10b46SJohannes Doerfert }
358a5b10b46SJohannes Doerfert
runOnModule(Module & M)359a5b10b46SJohannes Doerfert bool MustBeExecutedContextPrinter::runOnModule(Module &M) {
360fe799c97SJohannes Doerfert // We provide non-PM analysis here because the old PM doesn't like to query
361cb19ea45SJohannes Doerfert // function passes from a module pass.
3621b569808SDavid Blaikie SmallVector<std::unique_ptr<PostDominatorTree>, 8> PDTs;
3631b569808SDavid Blaikie SmallVector<std::unique_ptr<DominatorTree>, 8> DTs;
3641b569808SDavid Blaikie SmallVector<std::unique_ptr<LoopInfo>, 8> LIs;
365cb19ea45SJohannes Doerfert
366cb19ea45SJohannes Doerfert GetterTy<LoopInfo> LIGetter = [&](const Function &F) {
3671b569808SDavid Blaikie DTs.push_back(std::make_unique<DominatorTree>(const_cast<Function &>(F)));
3681b569808SDavid Blaikie LIs.push_back(std::make_unique<LoopInfo>(*DTs.back()));
3691b569808SDavid Blaikie return LIs.back().get();
370fe799c97SJohannes Doerfert };
371e253cddaSHideto Ueno GetterTy<DominatorTree> DTGetter = [&](const Function &F) {
3721b569808SDavid Blaikie DTs.push_back(std::make_unique<DominatorTree>(const_cast<Function&>(F)));
3731b569808SDavid Blaikie return DTs.back().get();
374e253cddaSHideto Ueno };
375cb19ea45SJohannes Doerfert GetterTy<PostDominatorTree> PDTGetter = [&](const Function &F) {
3761b569808SDavid Blaikie PDTs.push_back(
3771b569808SDavid Blaikie std::make_unique<PostDominatorTree>(const_cast<Function &>(F)));
3781b569808SDavid Blaikie return PDTs.back().get();
379fe799c97SJohannes Doerfert };
380e253cddaSHideto Ueno MustBeExecutedContextExplorer Explorer(
381e253cddaSHideto Ueno /* ExploreInterBlock */ true,
382e253cddaSHideto Ueno /* ExploreCFGForward */ true,
383e253cddaSHideto Ueno /* ExploreCFGBackward */ true, LIGetter, DTGetter, PDTGetter);
384e253cddaSHideto Ueno
385a5b10b46SJohannes Doerfert for (Function &F : M) {
386a5b10b46SJohannes Doerfert for (Instruction &I : instructions(F)) {
387a5b10b46SJohannes Doerfert dbgs() << "-- Explore context of: " << I << "\n";
388a5b10b46SJohannes Doerfert for (const Instruction *CI : Explorer.range(&I))
389a5b10b46SJohannes Doerfert dbgs() << " [F: " << CI->getFunction()->getName() << "] " << *CI
390a5b10b46SJohannes Doerfert << "\n";
391a5b10b46SJohannes Doerfert }
392a5b10b46SJohannes Doerfert }
393a5b10b46SJohannes Doerfert
394a5b10b46SJohannes Doerfert return false;
395a5b10b46SJohannes Doerfert }
396a5b10b46SJohannes Doerfert
isMustExecuteIn(const Instruction & I,Loop * L,DominatorTree * DT)3971fc0da48SBenjamin Kramer static bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT) {
39837a1a29fSPhilip Reames // TODO: merge these two routines. For the moment, we display the best
39937a1a29fSPhilip Reames // result obtained by *either* implementation. This is a bit unfair since no
40037a1a29fSPhilip Reames // caller actually gets the full power at the moment.
4019c90ec2fSMax Kazantsev SimpleLoopSafetyInfo LSI;
402530b8d1cSMax Kazantsev LSI.computeLoopSafetyInfo(L);
403c8466f93SMax Kazantsev return LSI.isGuaranteedToExecute(I, DT, L) ||
40437a1a29fSPhilip Reames isGuaranteedToExecuteForEveryIteration(&I, L);
40589f22417SPhilip Reames }
40689f22417SPhilip Reames
4071fc0da48SBenjamin Kramer namespace {
4085f8f34e4SAdrian Prantl /// An assembly annotator class to print must execute information in
409ce998adfSPhilip Reames /// comments.
410ce998adfSPhilip Reames class MustExecuteAnnotatedWriter : public AssemblyAnnotationWriter {
411ce998adfSPhilip Reames DenseMap<const Value*, SmallVector<Loop*, 4> > MustExec;
412ce998adfSPhilip Reames
413ce998adfSPhilip Reames public:
MustExecuteAnnotatedWriter(const Function & F,DominatorTree & DT,LoopInfo & LI)414ce998adfSPhilip Reames MustExecuteAnnotatedWriter(const Function &F,
415ce998adfSPhilip Reames DominatorTree &DT, LoopInfo &LI) {
416*601b3a13SKazu Hirata for (const auto &I: instructions(F)) {
41789f22417SPhilip Reames Loop *L = LI.getLoopFor(I.getParent());
41889f22417SPhilip Reames while (L) {
41989f22417SPhilip Reames if (isMustExecuteIn(I, L, &DT)) {
42089f22417SPhilip Reames MustExec[&I].push_back(L);
42189f22417SPhilip Reames }
42289f22417SPhilip Reames L = L->getParentLoop();
42389f22417SPhilip Reames };
42489f22417SPhilip Reames }
425ce998adfSPhilip Reames }
MustExecuteAnnotatedWriter(const Module & M,DominatorTree & DT,LoopInfo & LI)426ce998adfSPhilip Reames MustExecuteAnnotatedWriter(const Module &M,
427ce998adfSPhilip Reames DominatorTree &DT, LoopInfo &LI) {
428*601b3a13SKazu Hirata for (const auto &F : M)
429*601b3a13SKazu Hirata for (const auto &I: instructions(F)) {
430ce998adfSPhilip Reames Loop *L = LI.getLoopFor(I.getParent());
431ce998adfSPhilip Reames while (L) {
432ce998adfSPhilip Reames if (isMustExecuteIn(I, L, &DT)) {
433ce998adfSPhilip Reames MustExec[&I].push_back(L);
434ce998adfSPhilip Reames }
435ce998adfSPhilip Reames L = L->getParentLoop();
436ce998adfSPhilip Reames };
437ce998adfSPhilip Reames }
43889f22417SPhilip Reames }
43989f22417SPhilip Reames
440ce998adfSPhilip Reames
printInfoComment(const Value & V,formatted_raw_ostream & OS)441ce998adfSPhilip Reames void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
442ce998adfSPhilip Reames if (!MustExec.count(&V))
443ce998adfSPhilip Reames return;
444ce998adfSPhilip Reames
445ce998adfSPhilip Reames const auto &Loops = MustExec.lookup(&V);
446ce998adfSPhilip Reames const auto NumLoops = Loops.size();
44789f22417SPhilip Reames if (NumLoops > 1)
448ce998adfSPhilip Reames OS << " ; (mustexec in " << NumLoops << " loops: ";
44989f22417SPhilip Reames else
450ce998adfSPhilip Reames OS << " ; (mustexec in: ";
45189f22417SPhilip Reames
4526cedffc0SKazu Hirata ListSeparator LS;
4536cedffc0SKazu Hirata for (const Loop *L : Loops)
4546cedffc0SKazu Hirata OS << LS << L->getHeader()->getName();
455ce998adfSPhilip Reames OS << ")";
45689f22417SPhilip Reames }
457ce998adfSPhilip Reames };
4581fc0da48SBenjamin Kramer } // namespace
459ce998adfSPhilip Reames
runOnFunction(Function & F)460ce998adfSPhilip Reames bool MustExecutePrinter::runOnFunction(Function &F) {
461ce998adfSPhilip Reames auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
462ce998adfSPhilip Reames auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
463ce998adfSPhilip Reames
464ce998adfSPhilip Reames MustExecuteAnnotatedWriter Writer(F, DT, LI);
465ce998adfSPhilip Reames F.print(dbgs(), &Writer);
466ce998adfSPhilip Reames
467ce998adfSPhilip Reames return false;
46889f22417SPhilip Reames }
469a5b10b46SJohannes Doerfert
470fe799c97SJohannes Doerfert /// Return true if \p L might be an endless loop.
maybeEndlessLoop(const Loop & L)471fe799c97SJohannes Doerfert static bool maybeEndlessLoop(const Loop &L) {
472fe799c97SJohannes Doerfert if (L.getHeader()->getParent()->hasFnAttribute(Attribute::WillReturn))
473fe799c97SJohannes Doerfert return false;
474fe799c97SJohannes Doerfert // TODO: Actually try to prove it is not.
475fe799c97SJohannes Doerfert // TODO: If maybeEndlessLoop is going to be expensive, cache it.
476fe799c97SJohannes Doerfert return true;
477fe799c97SJohannes Doerfert }
478fe799c97SJohannes Doerfert
mayContainIrreducibleControl(const Function & F,const LoopInfo * LI)479b285b333Somarahmed1111 bool llvm::mayContainIrreducibleControl(const Function &F, const LoopInfo *LI) {
480fe799c97SJohannes Doerfert if (!LI)
481fe799c97SJohannes Doerfert return false;
482fe799c97SJohannes Doerfert using RPOTraversal = ReversePostOrderTraversal<const Function *>;
483fe799c97SJohannes Doerfert RPOTraversal FuncRPOT(&F);
484b285b333Somarahmed1111 return containsIrreducibleCFG<const BasicBlock *, const RPOTraversal,
485fe799c97SJohannes Doerfert const LoopInfo>(FuncRPOT, *LI);
486fe799c97SJohannes Doerfert }
487fe799c97SJohannes Doerfert
488fe799c97SJohannes Doerfert /// Lookup \p Key in \p Map and return the result, potentially after
489fe799c97SJohannes Doerfert /// initializing the optional through \p Fn(\p args).
490fe799c97SJohannes Doerfert template <typename K, typename V, typename FnTy, typename... ArgsTy>
getOrCreateCachedOptional(K Key,DenseMap<K,Optional<V>> & Map,FnTy && Fn,ArgsTy &&...args)491fe799c97SJohannes Doerfert static V getOrCreateCachedOptional(K Key, DenseMap<K, Optional<V>> &Map,
492fe799c97SJohannes Doerfert FnTy &&Fn, ArgsTy&&... args) {
493fe799c97SJohannes Doerfert Optional<V> &OptVal = Map[Key];
494a7938c74SKazu Hirata if (!OptVal)
495fe799c97SJohannes Doerfert OptVal = Fn(std::forward<ArgsTy>(args)...);
496611ffcf4SKazu Hirata return OptVal.value();
497fe799c97SJohannes Doerfert }
498fe799c97SJohannes Doerfert
499fe799c97SJohannes Doerfert const BasicBlock *
findForwardJoinPoint(const BasicBlock * InitBB)500fe799c97SJohannes Doerfert MustBeExecutedContextExplorer::findForwardJoinPoint(const BasicBlock *InitBB) {
501fe799c97SJohannes Doerfert const LoopInfo *LI = LIGetter(*InitBB->getParent());
502fe799c97SJohannes Doerfert const PostDominatorTree *PDT = PDTGetter(*InitBB->getParent());
503fe799c97SJohannes Doerfert
504fe799c97SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tFind forward join point for " << InitBB->getName()
505fe799c97SJohannes Doerfert << (LI ? " [LI]" : "") << (PDT ? " [PDT]" : ""));
506fe799c97SJohannes Doerfert
507fe799c97SJohannes Doerfert const Function &F = *InitBB->getParent();
508fe799c97SJohannes Doerfert const Loop *L = LI ? LI->getLoopFor(InitBB) : nullptr;
509fe799c97SJohannes Doerfert const BasicBlock *HeaderBB = L ? L->getHeader() : InitBB;
510fe799c97SJohannes Doerfert bool WillReturnAndNoThrow = (F.hasFnAttribute(Attribute::WillReturn) ||
511fe799c97SJohannes Doerfert (L && !maybeEndlessLoop(*L))) &&
512fe799c97SJohannes Doerfert F.doesNotThrow();
513fe799c97SJohannes Doerfert LLVM_DEBUG(dbgs() << (L ? " [in loop]" : "")
514fe799c97SJohannes Doerfert << (WillReturnAndNoThrow ? " [WillReturn] [NoUnwind]" : "")
515fe799c97SJohannes Doerfert << "\n");
516fe799c97SJohannes Doerfert
517fe799c97SJohannes Doerfert // Determine the adjacent blocks in the given direction but exclude (self)
518fe799c97SJohannes Doerfert // loops under certain circumstances.
519fe799c97SJohannes Doerfert SmallVector<const BasicBlock *, 8> Worklist;
520fe799c97SJohannes Doerfert for (const BasicBlock *SuccBB : successors(InitBB)) {
521fe799c97SJohannes Doerfert bool IsLatch = SuccBB == HeaderBB;
522fe799c97SJohannes Doerfert // Loop latches are ignored in forward propagation if the loop cannot be
523fe799c97SJohannes Doerfert // endless and may not throw: control has to go somewhere.
524fe799c97SJohannes Doerfert if (!WillReturnAndNoThrow || !IsLatch)
525fe799c97SJohannes Doerfert Worklist.push_back(SuccBB);
526fe799c97SJohannes Doerfert }
527fe799c97SJohannes Doerfert LLVM_DEBUG(dbgs() << "\t\t#Worklist: " << Worklist.size() << "\n");
528fe799c97SJohannes Doerfert
529fe799c97SJohannes Doerfert // If there are no other adjacent blocks, there is no join point.
530fe799c97SJohannes Doerfert if (Worklist.empty())
531fe799c97SJohannes Doerfert return nullptr;
532fe799c97SJohannes Doerfert
533fe799c97SJohannes Doerfert // If there is one adjacent block, it is the join point.
534fe799c97SJohannes Doerfert if (Worklist.size() == 1)
535fe799c97SJohannes Doerfert return Worklist[0];
536fe799c97SJohannes Doerfert
537fe799c97SJohannes Doerfert // Try to determine a join block through the help of the post-dominance
538fe799c97SJohannes Doerfert // tree. If no tree was provided, we perform simple pattern matching for one
539fe799c97SJohannes Doerfert // block conditionals and one block loops only.
540fe799c97SJohannes Doerfert const BasicBlock *JoinBB = nullptr;
541fe799c97SJohannes Doerfert if (PDT)
542fe799c97SJohannes Doerfert if (const auto *InitNode = PDT->getNode(InitBB))
543fe799c97SJohannes Doerfert if (const auto *IDomNode = InitNode->getIDom())
544fe799c97SJohannes Doerfert JoinBB = IDomNode->getBlock();
545fe799c97SJohannes Doerfert
546fe799c97SJohannes Doerfert if (!JoinBB && Worklist.size() == 2) {
547fe799c97SJohannes Doerfert const BasicBlock *Succ0 = Worklist[0];
548fe799c97SJohannes Doerfert const BasicBlock *Succ1 = Worklist[1];
549fe799c97SJohannes Doerfert const BasicBlock *Succ0UniqueSucc = Succ0->getUniqueSuccessor();
550fe799c97SJohannes Doerfert const BasicBlock *Succ1UniqueSucc = Succ1->getUniqueSuccessor();
551fe799c97SJohannes Doerfert if (Succ0UniqueSucc == InitBB) {
552fe799c97SJohannes Doerfert // InitBB -> Succ0 -> InitBB
553fe799c97SJohannes Doerfert // InitBB -> Succ1 = JoinBB
554fe799c97SJohannes Doerfert JoinBB = Succ1;
555fe799c97SJohannes Doerfert } else if (Succ1UniqueSucc == InitBB) {
556fe799c97SJohannes Doerfert // InitBB -> Succ1 -> InitBB
557fe799c97SJohannes Doerfert // InitBB -> Succ0 = JoinBB
558fe799c97SJohannes Doerfert JoinBB = Succ0;
559fe799c97SJohannes Doerfert } else if (Succ0 == Succ1UniqueSucc) {
560fe799c97SJohannes Doerfert // InitBB -> Succ0 = JoinBB
561fe799c97SJohannes Doerfert // InitBB -> Succ1 -> Succ0 = JoinBB
562fe799c97SJohannes Doerfert JoinBB = Succ0;
563fe799c97SJohannes Doerfert } else if (Succ1 == Succ0UniqueSucc) {
564fe799c97SJohannes Doerfert // InitBB -> Succ0 -> Succ1 = JoinBB
565fe799c97SJohannes Doerfert // InitBB -> Succ1 = JoinBB
566fe799c97SJohannes Doerfert JoinBB = Succ1;
567fe799c97SJohannes Doerfert } else if (Succ0UniqueSucc == Succ1UniqueSucc) {
568fe799c97SJohannes Doerfert // InitBB -> Succ0 -> JoinBB
569fe799c97SJohannes Doerfert // InitBB -> Succ1 -> JoinBB
570fe799c97SJohannes Doerfert JoinBB = Succ0UniqueSucc;
571fe799c97SJohannes Doerfert }
572fe799c97SJohannes Doerfert }
573fe799c97SJohannes Doerfert
574fe799c97SJohannes Doerfert if (!JoinBB && L)
575fe799c97SJohannes Doerfert JoinBB = L->getUniqueExitBlock();
576fe799c97SJohannes Doerfert
577fe799c97SJohannes Doerfert if (!JoinBB)
578fe799c97SJohannes Doerfert return nullptr;
579fe799c97SJohannes Doerfert
580fe799c97SJohannes Doerfert LLVM_DEBUG(dbgs() << "\t\tJoin block candidate: " << JoinBB->getName() << "\n");
581fe799c97SJohannes Doerfert
582fe799c97SJohannes Doerfert // In forward direction we check if control will for sure reach JoinBB from
583fe799c97SJohannes Doerfert // InitBB, thus it can not be "stopped" along the way. Ways to "stop" control
584fe799c97SJohannes Doerfert // are: infinite loops and instructions that do not necessarily transfer
585fe799c97SJohannes Doerfert // execution to their successor. To check for them we traverse the CFG from
586fe799c97SJohannes Doerfert // the adjacent blocks to the JoinBB, looking at all intermediate blocks.
587fe799c97SJohannes Doerfert
588fe799c97SJohannes Doerfert // If we know the function is "will-return" and "no-throw" there is no need
589fe799c97SJohannes Doerfert // for futher checks.
590fe799c97SJohannes Doerfert if (!F.hasFnAttribute(Attribute::WillReturn) || !F.doesNotThrow()) {
591fe799c97SJohannes Doerfert
592fe799c97SJohannes Doerfert auto BlockTransfersExecutionToSuccessor = [](const BasicBlock *BB) {
593fe799c97SJohannes Doerfert return isGuaranteedToTransferExecutionToSuccessor(BB);
594fe799c97SJohannes Doerfert };
595fe799c97SJohannes Doerfert
596fe799c97SJohannes Doerfert SmallPtrSet<const BasicBlock *, 16> Visited;
597fe799c97SJohannes Doerfert while (!Worklist.empty()) {
598fe799c97SJohannes Doerfert const BasicBlock *ToBB = Worklist.pop_back_val();
599fe799c97SJohannes Doerfert if (ToBB == JoinBB)
600fe799c97SJohannes Doerfert continue;
601fe799c97SJohannes Doerfert
602fe799c97SJohannes Doerfert // Make sure all loops in-between are finite.
603fe799c97SJohannes Doerfert if (!Visited.insert(ToBB).second) {
604fe799c97SJohannes Doerfert if (!F.hasFnAttribute(Attribute::WillReturn)) {
605fe799c97SJohannes Doerfert if (!LI)
606fe799c97SJohannes Doerfert return nullptr;
607fe799c97SJohannes Doerfert
608fe799c97SJohannes Doerfert bool MayContainIrreducibleControl = getOrCreateCachedOptional(
609fe799c97SJohannes Doerfert &F, IrreducibleControlMap, mayContainIrreducibleControl, F, LI);
610fe799c97SJohannes Doerfert if (MayContainIrreducibleControl)
611fe799c97SJohannes Doerfert return nullptr;
612fe799c97SJohannes Doerfert
613fe799c97SJohannes Doerfert const Loop *L = LI->getLoopFor(ToBB);
614fe799c97SJohannes Doerfert if (L && maybeEndlessLoop(*L))
615fe799c97SJohannes Doerfert return nullptr;
616fe799c97SJohannes Doerfert }
617fe799c97SJohannes Doerfert
618fe799c97SJohannes Doerfert continue;
619fe799c97SJohannes Doerfert }
620fe799c97SJohannes Doerfert
621fe799c97SJohannes Doerfert // Make sure the block has no instructions that could stop control
622fe799c97SJohannes Doerfert // transfer.
623fe799c97SJohannes Doerfert bool TransfersExecution = getOrCreateCachedOptional(
624fe799c97SJohannes Doerfert ToBB, BlockTransferMap, BlockTransfersExecutionToSuccessor, ToBB);
625fe799c97SJohannes Doerfert if (!TransfersExecution)
626fe799c97SJohannes Doerfert return nullptr;
627fe799c97SJohannes Doerfert
628a3254904SKazu Hirata append_range(Worklist, successors(ToBB));
629fe799c97SJohannes Doerfert }
630fe799c97SJohannes Doerfert }
631fe799c97SJohannes Doerfert
632fe799c97SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tJoin block: " << JoinBB->getName() << "\n");
633fe799c97SJohannes Doerfert return JoinBB;
634fe799c97SJohannes Doerfert }
635e253cddaSHideto Ueno const BasicBlock *
findBackwardJoinPoint(const BasicBlock * InitBB)636e253cddaSHideto Ueno MustBeExecutedContextExplorer::findBackwardJoinPoint(const BasicBlock *InitBB) {
637e253cddaSHideto Ueno const LoopInfo *LI = LIGetter(*InitBB->getParent());
638e253cddaSHideto Ueno const DominatorTree *DT = DTGetter(*InitBB->getParent());
639e253cddaSHideto Ueno LLVM_DEBUG(dbgs() << "\tFind backward join point for " << InitBB->getName()
640e253cddaSHideto Ueno << (LI ? " [LI]" : "") << (DT ? " [DT]" : ""));
641e253cddaSHideto Ueno
642e253cddaSHideto Ueno // Try to determine a join block through the help of the dominance tree. If no
643e253cddaSHideto Ueno // tree was provided, we perform simple pattern matching for one block
644e253cddaSHideto Ueno // conditionals only.
645e253cddaSHideto Ueno if (DT)
646e253cddaSHideto Ueno if (const auto *InitNode = DT->getNode(InitBB))
647e253cddaSHideto Ueno if (const auto *IDomNode = InitNode->getIDom())
648e253cddaSHideto Ueno return IDomNode->getBlock();
649e253cddaSHideto Ueno
650e253cddaSHideto Ueno const Loop *L = LI ? LI->getLoopFor(InitBB) : nullptr;
651e253cddaSHideto Ueno const BasicBlock *HeaderBB = L ? L->getHeader() : nullptr;
652e253cddaSHideto Ueno
653e253cddaSHideto Ueno // Determine the predecessor blocks but ignore backedges.
654e253cddaSHideto Ueno SmallVector<const BasicBlock *, 8> Worklist;
655e253cddaSHideto Ueno for (const BasicBlock *PredBB : predecessors(InitBB)) {
656e253cddaSHideto Ueno bool IsBackedge =
657e253cddaSHideto Ueno (PredBB == InitBB) || (HeaderBB == InitBB && L->contains(PredBB));
658e253cddaSHideto Ueno // Loop backedges are ignored in backwards propagation: control has to come
659e253cddaSHideto Ueno // from somewhere.
660e253cddaSHideto Ueno if (!IsBackedge)
661e253cddaSHideto Ueno Worklist.push_back(PredBB);
662e253cddaSHideto Ueno }
663e253cddaSHideto Ueno
664e253cddaSHideto Ueno // If there are no other predecessor blocks, there is no join point.
665e253cddaSHideto Ueno if (Worklist.empty())
666e253cddaSHideto Ueno return nullptr;
667e253cddaSHideto Ueno
668e253cddaSHideto Ueno // If there is one predecessor block, it is the join point.
669e253cddaSHideto Ueno if (Worklist.size() == 1)
670e253cddaSHideto Ueno return Worklist[0];
671e253cddaSHideto Ueno
672e253cddaSHideto Ueno const BasicBlock *JoinBB = nullptr;
673e253cddaSHideto Ueno if (Worklist.size() == 2) {
674e253cddaSHideto Ueno const BasicBlock *Pred0 = Worklist[0];
675e253cddaSHideto Ueno const BasicBlock *Pred1 = Worklist[1];
676e253cddaSHideto Ueno const BasicBlock *Pred0UniquePred = Pred0->getUniquePredecessor();
677e253cddaSHideto Ueno const BasicBlock *Pred1UniquePred = Pred1->getUniquePredecessor();
678e253cddaSHideto Ueno if (Pred0 == Pred1UniquePred) {
679e253cddaSHideto Ueno // InitBB <- Pred0 = JoinBB
680e253cddaSHideto Ueno // InitBB <- Pred1 <- Pred0 = JoinBB
681e253cddaSHideto Ueno JoinBB = Pred0;
682e253cddaSHideto Ueno } else if (Pred1 == Pred0UniquePred) {
683e253cddaSHideto Ueno // InitBB <- Pred0 <- Pred1 = JoinBB
684e253cddaSHideto Ueno // InitBB <- Pred1 = JoinBB
685e253cddaSHideto Ueno JoinBB = Pred1;
686e253cddaSHideto Ueno } else if (Pred0UniquePred == Pred1UniquePred) {
687e253cddaSHideto Ueno // InitBB <- Pred0 <- JoinBB
688e253cddaSHideto Ueno // InitBB <- Pred1 <- JoinBB
689e253cddaSHideto Ueno JoinBB = Pred0UniquePred;
690e253cddaSHideto Ueno }
691e253cddaSHideto Ueno }
692e253cddaSHideto Ueno
693e253cddaSHideto Ueno if (!JoinBB && L)
694e253cddaSHideto Ueno JoinBB = L->getHeader();
695e253cddaSHideto Ueno
696e253cddaSHideto Ueno // In backwards direction there is no need to show termination of previous
697e253cddaSHideto Ueno // instructions. If they do not terminate, the code afterward is dead, making
698e253cddaSHideto Ueno // any information/transformation correct anyway.
699e253cddaSHideto Ueno return JoinBB;
700e253cddaSHideto Ueno }
701fe799c97SJohannes Doerfert
702a5b10b46SJohannes Doerfert const Instruction *
getMustBeExecutedNextInstruction(MustBeExecutedIterator & It,const Instruction * PP)703a5b10b46SJohannes Doerfert MustBeExecutedContextExplorer::getMustBeExecutedNextInstruction(
704a5b10b46SJohannes Doerfert MustBeExecutedIterator &It, const Instruction *PP) {
705a5b10b46SJohannes Doerfert if (!PP)
706a5b10b46SJohannes Doerfert return PP;
707a5b10b46SJohannes Doerfert LLVM_DEBUG(dbgs() << "Find next instruction for " << *PP << "\n");
708a5b10b46SJohannes Doerfert
709a5b10b46SJohannes Doerfert // If we explore only inside a given basic block we stop at terminators.
710a5b10b46SJohannes Doerfert if (!ExploreInterBlock && PP->isTerminator()) {
711a5b10b46SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tReached terminator in intra-block mode, done\n");
712a5b10b46SJohannes Doerfert return nullptr;
713a5b10b46SJohannes Doerfert }
714a5b10b46SJohannes Doerfert
715a5b10b46SJohannes Doerfert // If we do not traverse the call graph we check if we can make progress in
716a5b10b46SJohannes Doerfert // the current function. First, check if the instruction is guaranteed to
717a5b10b46SJohannes Doerfert // transfer execution to the successor.
718a5b10b46SJohannes Doerfert bool TransfersExecution = isGuaranteedToTransferExecutionToSuccessor(PP);
719a5b10b46SJohannes Doerfert if (!TransfersExecution)
720a5b10b46SJohannes Doerfert return nullptr;
721a5b10b46SJohannes Doerfert
722a5b10b46SJohannes Doerfert // If this is not a terminator we know that there is a single instruction
723a5b10b46SJohannes Doerfert // after this one that is executed next if control is transfered. If not,
724a5b10b46SJohannes Doerfert // we can try to go back to a call site we entered earlier. If none exists, we
725a5b10b46SJohannes Doerfert // do not know any instruction that has to be executd next.
726a5b10b46SJohannes Doerfert if (!PP->isTerminator()) {
727a5b10b46SJohannes Doerfert const Instruction *NextPP = PP->getNextNode();
728a5b10b46SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tIntermediate instruction does transfer control\n");
729a5b10b46SJohannes Doerfert return NextPP;
730a5b10b46SJohannes Doerfert }
731a5b10b46SJohannes Doerfert
732a5b10b46SJohannes Doerfert // Finally, we have to handle terminators, trivial ones first.
733a5b10b46SJohannes Doerfert assert(PP->isTerminator() && "Expected a terminator!");
734a5b10b46SJohannes Doerfert
735a5b10b46SJohannes Doerfert // A terminator without a successor is not handled yet.
736a5b10b46SJohannes Doerfert if (PP->getNumSuccessors() == 0) {
737a5b10b46SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tUnhandled terminator\n");
738a5b10b46SJohannes Doerfert return nullptr;
739a5b10b46SJohannes Doerfert }
740a5b10b46SJohannes Doerfert
741a5b10b46SJohannes Doerfert // A terminator with a single successor, we will continue at the beginning of
742a5b10b46SJohannes Doerfert // that one.
743a5b10b46SJohannes Doerfert if (PP->getNumSuccessors() == 1) {
744a5b10b46SJohannes Doerfert LLVM_DEBUG(
745a5b10b46SJohannes Doerfert dbgs() << "\tUnconditional terminator, continue with successor\n");
746a5b10b46SJohannes Doerfert return &PP->getSuccessor(0)->front();
747a5b10b46SJohannes Doerfert }
748a5b10b46SJohannes Doerfert
749fe799c97SJohannes Doerfert // Multiple successors mean we need to find the join point where control flow
750fe799c97SJohannes Doerfert // converges again. We use the findForwardJoinPoint helper function with
751fe799c97SJohannes Doerfert // information about the function and helper analyses, if available.
752fe799c97SJohannes Doerfert if (const BasicBlock *JoinBB = findForwardJoinPoint(PP->getParent()))
753fe799c97SJohannes Doerfert return &JoinBB->front();
754fe799c97SJohannes Doerfert
755a5b10b46SJohannes Doerfert LLVM_DEBUG(dbgs() << "\tNo join point found\n");
756a5b10b46SJohannes Doerfert return nullptr;
757a5b10b46SJohannes Doerfert }
758a5b10b46SJohannes Doerfert
759e253cddaSHideto Ueno const Instruction *
getMustBeExecutedPrevInstruction(MustBeExecutedIterator & It,const Instruction * PP)760e253cddaSHideto Ueno MustBeExecutedContextExplorer::getMustBeExecutedPrevInstruction(
761e253cddaSHideto Ueno MustBeExecutedIterator &It, const Instruction *PP) {
762e253cddaSHideto Ueno if (!PP)
763e253cddaSHideto Ueno return PP;
764e253cddaSHideto Ueno
765e253cddaSHideto Ueno bool IsFirst = !(PP->getPrevNode());
766e253cddaSHideto Ueno LLVM_DEBUG(dbgs() << "Find next instruction for " << *PP
767e253cddaSHideto Ueno << (IsFirst ? " [IsFirst]" : "") << "\n");
768e253cddaSHideto Ueno
769e253cddaSHideto Ueno // If we explore only inside a given basic block we stop at the first
770e253cddaSHideto Ueno // instruction.
771e253cddaSHideto Ueno if (!ExploreInterBlock && IsFirst) {
772e253cddaSHideto Ueno LLVM_DEBUG(dbgs() << "\tReached block front in intra-block mode, done\n");
773e253cddaSHideto Ueno return nullptr;
774e253cddaSHideto Ueno }
775e253cddaSHideto Ueno
776e253cddaSHideto Ueno // The block and function that contains the current position.
777e253cddaSHideto Ueno const BasicBlock *PPBlock = PP->getParent();
778e253cddaSHideto Ueno
779e253cddaSHideto Ueno // If we are inside a block we know what instruction was executed before, the
780e253cddaSHideto Ueno // previous one.
781e253cddaSHideto Ueno if (!IsFirst) {
782e253cddaSHideto Ueno const Instruction *PrevPP = PP->getPrevNode();
783e253cddaSHideto Ueno LLVM_DEBUG(
784e253cddaSHideto Ueno dbgs() << "\tIntermediate instruction, continue with previous\n");
785e253cddaSHideto Ueno // We did not enter a callee so we simply return the previous instruction.
786e253cddaSHideto Ueno return PrevPP;
787e253cddaSHideto Ueno }
788e253cddaSHideto Ueno
789e253cddaSHideto Ueno // Finally, we have to handle the case where the program point is the first in
790e253cddaSHideto Ueno // a block but not in the function. We use the findBackwardJoinPoint helper
791e253cddaSHideto Ueno // function with information about the function and helper analyses, if
792e253cddaSHideto Ueno // available.
793e253cddaSHideto Ueno if (const BasicBlock *JoinBB = findBackwardJoinPoint(PPBlock))
794e253cddaSHideto Ueno return &JoinBB->back();
795e253cddaSHideto Ueno
796e253cddaSHideto Ueno LLVM_DEBUG(dbgs() << "\tNo join point found\n");
797e253cddaSHideto Ueno return nullptr;
798e253cddaSHideto Ueno }
799e253cddaSHideto Ueno
MustBeExecutedIterator(MustBeExecutedContextExplorer & Explorer,const Instruction * I)800a5b10b46SJohannes Doerfert MustBeExecutedIterator::MustBeExecutedIterator(
801a5b10b46SJohannes Doerfert MustBeExecutedContextExplorer &Explorer, const Instruction *I)
802a5b10b46SJohannes Doerfert : Explorer(Explorer), CurInst(I) {
803a5b10b46SJohannes Doerfert reset(I);
804a5b10b46SJohannes Doerfert }
805a5b10b46SJohannes Doerfert
reset(const Instruction * I)806a5b10b46SJohannes Doerfert void MustBeExecutedIterator::reset(const Instruction *I) {
807a5b10b46SJohannes Doerfert Visited.clear();
808e253cddaSHideto Ueno resetInstruction(I);
809e253cddaSHideto Ueno }
810e253cddaSHideto Ueno
resetInstruction(const Instruction * I)811e253cddaSHideto Ueno void MustBeExecutedIterator::resetInstruction(const Instruction *I) {
812e253cddaSHideto Ueno CurInst = I;
813e253cddaSHideto Ueno Head = Tail = nullptr;
814e253cddaSHideto Ueno Visited.insert({I, ExplorationDirection::FORWARD});
815e253cddaSHideto Ueno Visited.insert({I, ExplorationDirection::BACKWARD});
816e253cddaSHideto Ueno if (Explorer.ExploreCFGForward)
817e253cddaSHideto Ueno Head = I;
818e253cddaSHideto Ueno if (Explorer.ExploreCFGBackward)
819e253cddaSHideto Ueno Tail = I;
820a5b10b46SJohannes Doerfert }
821a5b10b46SJohannes Doerfert
advance()822a5b10b46SJohannes Doerfert const Instruction *MustBeExecutedIterator::advance() {
823a5b10b46SJohannes Doerfert assert(CurInst && "Cannot advance an end iterator!");
824e253cddaSHideto Ueno Head = Explorer.getMustBeExecutedNextInstruction(*this, Head);
825e253cddaSHideto Ueno if (Head && Visited.insert({Head, ExplorationDirection ::FORWARD}).second)
826e253cddaSHideto Ueno return Head;
827e253cddaSHideto Ueno Head = nullptr;
828e253cddaSHideto Ueno
829e253cddaSHideto Ueno Tail = Explorer.getMustBeExecutedPrevInstruction(*this, Tail);
830e253cddaSHideto Ueno if (Tail && Visited.insert({Tail, ExplorationDirection ::BACKWARD}).second)
831e253cddaSHideto Ueno return Tail;
832e253cddaSHideto Ueno Tail = nullptr;
833e253cddaSHideto Ueno return nullptr;
834a5b10b46SJohannes Doerfert }
83506926e0fSArthur Eubanks
run(Function & F,FunctionAnalysisManager & AM)83606926e0fSArthur Eubanks PreservedAnalyses MustExecutePrinterPass::run(Function &F,
83706926e0fSArthur Eubanks FunctionAnalysisManager &AM) {
83806926e0fSArthur Eubanks auto &LI = AM.getResult<LoopAnalysis>(F);
83906926e0fSArthur Eubanks auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
84006926e0fSArthur Eubanks
84106926e0fSArthur Eubanks MustExecuteAnnotatedWriter Writer(F, DT, LI);
84206926e0fSArthur Eubanks F.print(OS, &Writer);
84306926e0fSArthur Eubanks return PreservedAnalyses::all();
84406926e0fSArthur Eubanks }
84506926e0fSArthur Eubanks
84606926e0fSArthur Eubanks PreservedAnalyses
run(Module & M,ModuleAnalysisManager & AM)84706926e0fSArthur Eubanks MustBeExecutedContextPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
84806926e0fSArthur Eubanks FunctionAnalysisManager &FAM =
84906926e0fSArthur Eubanks AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
85006926e0fSArthur Eubanks GetterTy<const LoopInfo> LIGetter = [&](const Function &F) {
85106926e0fSArthur Eubanks return &FAM.getResult<LoopAnalysis>(const_cast<Function &>(F));
85206926e0fSArthur Eubanks };
85306926e0fSArthur Eubanks GetterTy<const DominatorTree> DTGetter = [&](const Function &F) {
85406926e0fSArthur Eubanks return &FAM.getResult<DominatorTreeAnalysis>(const_cast<Function &>(F));
85506926e0fSArthur Eubanks };
85606926e0fSArthur Eubanks GetterTy<const PostDominatorTree> PDTGetter = [&](const Function &F) {
85706926e0fSArthur Eubanks return &FAM.getResult<PostDominatorTreeAnalysis>(const_cast<Function &>(F));
85806926e0fSArthur Eubanks };
85906926e0fSArthur Eubanks
86006926e0fSArthur Eubanks MustBeExecutedContextExplorer Explorer(
86106926e0fSArthur Eubanks /* ExploreInterBlock */ true,
86206926e0fSArthur Eubanks /* ExploreCFGForward */ true,
86306926e0fSArthur Eubanks /* ExploreCFGBackward */ true, LIGetter, DTGetter, PDTGetter);
86406926e0fSArthur Eubanks
86506926e0fSArthur Eubanks for (Function &F : M) {
86606926e0fSArthur Eubanks for (Instruction &I : instructions(F)) {
86706926e0fSArthur Eubanks OS << "-- Explore context of: " << I << "\n";
86806926e0fSArthur Eubanks for (const Instruction *CI : Explorer.range(&I))
86906926e0fSArthur Eubanks OS << " [F: " << CI->getFunction()->getName() << "] " << *CI << "\n";
87006926e0fSArthur Eubanks }
87106926e0fSArthur Eubanks }
87206926e0fSArthur Eubanks return PreservedAnalyses::all();
87306926e0fSArthur Eubanks }
874