blob: f741b35ab9c3c42f8e08c3b95e90b7db64565e9c [file] [log] [blame]
Philip Reames89f22412018-03-20 17:09:21 +00001//===- MustExecute.cpp - Printer for isGuaranteedToExecute ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Analysis/LoopInfo.h"
11#include "llvm/Analysis/Passes.h"
12#include "llvm/Analysis/ValueTracking.h"
Philip Reamesce998ad2018-03-20 18:43:44 +000013#include "llvm/IR/AssemblyAnnotationWriter.h"
Philip Reames89f22412018-03-20 17:09:21 +000014#include "llvm/IR/DataLayout.h"
15#include "llvm/IR/InstIterator.h"
16#include "llvm/IR/LLVMContext.h"
17#include "llvm/IR/Module.h"
18#include "llvm/Support/ErrorHandling.h"
Philip Reamesce998ad2018-03-20 18:43:44 +000019#include "llvm/Support/FormattedStream.h"
Philip Reames89f22412018-03-20 17:09:21 +000020#include "llvm/Support/raw_ostream.h"
21#include "llvm/Transforms/Utils/LoopUtils.h"
22using namespace llvm;
23
24namespace {
25 struct MustExecutePrinter : public FunctionPass {
Philip Reames89f22412018-03-20 17:09:21 +000026
27 static char ID; // Pass identification, replacement for typeid
28 MustExecutePrinter() : FunctionPass(ID) {
29 initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
30 }
31 void getAnalysisUsage(AnalysisUsage &AU) const override {
32 AU.setPreservesAll();
33 AU.addRequired<DominatorTreeWrapperPass>();
34 AU.addRequired<LoopInfoWrapperPass>();
35 }
36 bool runOnFunction(Function &F) override;
Philip Reames89f22412018-03-20 17:09:21 +000037 };
38}
39
40char MustExecutePrinter::ID = 0;
41INITIALIZE_PASS_BEGIN(MustExecutePrinter, "print-mustexecute",
42 "Instructions which execute on loop entry", false, true)
43INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
44INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
45INITIALIZE_PASS_END(MustExecutePrinter, "print-mustexecute",
46 "Instructions which execute on loop entry", false, true)
47
48FunctionPass *llvm::createMustExecutePrinter() {
49 return new MustExecutePrinter();
50}
51
Philip Reamesce998ad2018-03-20 18:43:44 +000052bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT) {
Philip Reames89f22412018-03-20 17:09:21 +000053 // TODO: move loop specific code to analysis
54 //LoopSafetyInfo LSI;
55 //computeLoopSafetyInfo(&LSI, L);
56 //return isGuaranteedToExecute(I, DT, L, &LSI);
57 return isGuaranteedToExecuteForEveryIteration(&I, L);
58}
59
Philip Reamesce998ad2018-03-20 18:43:44 +000060/// \brief An assembly annotator class to print must execute information in
61/// comments.
62class MustExecuteAnnotatedWriter : public AssemblyAnnotationWriter {
63 DenseMap<const Value*, SmallVector<Loop*, 4> > MustExec;
Philip Reames89f22412018-03-20 17:09:21 +000064
Philip Reamesce998ad2018-03-20 18:43:44 +000065public:
66 MustExecuteAnnotatedWriter(const Function &F,
67 DominatorTree &DT, LoopInfo &LI) {
68 for (auto &I: instructions(F)) {
69 Loop *L = LI.getLoopFor(I.getParent());
70 while (L) {
71 if (isMustExecuteIn(I, L, &DT)) {
72 MustExec[&I].push_back(L);
73 }
74 L = L->getParentLoop();
75 };
76 }
77 }
78 MustExecuteAnnotatedWriter(const Module &M,
79 DominatorTree &DT, LoopInfo &LI) {
80 for (auto &F : M)
81 for (auto &I: instructions(F)) {
82 Loop *L = LI.getLoopFor(I.getParent());
83 while (L) {
84 if (isMustExecuteIn(I, L, &DT)) {
85 MustExec[&I].push_back(L);
86 }
87 L = L->getParentLoop();
88 };
89 }
90 }
91
92
93 void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
94 if (!MustExec.count(&V))
95 return;
96
97 const auto &Loops = MustExec.lookup(&V);
98 const auto NumLoops = Loops.size();
Philip Reames89f22412018-03-20 17:09:21 +000099 if (NumLoops > 1)
Philip Reamesce998ad2018-03-20 18:43:44 +0000100 OS << " ; (mustexec in " << NumLoops << " loops: ";
Philip Reames89f22412018-03-20 17:09:21 +0000101 else
Philip Reamesce998ad2018-03-20 18:43:44 +0000102 OS << " ; (mustexec in: ";
Philip Reames89f22412018-03-20 17:09:21 +0000103
104 bool first = true;
Philip Reamesce998ad2018-03-20 18:43:44 +0000105 for (const Loop *L : Loops) {
Philip Reames89f22412018-03-20 17:09:21 +0000106 if (!first)
107 OS << ", ";
108 first = false;
109 OS << L->getHeader()->getName();
110 }
Philip Reamesce998ad2018-03-20 18:43:44 +0000111 OS << ")";
Philip Reames89f22412018-03-20 17:09:21 +0000112 }
Philip Reamesce998ad2018-03-20 18:43:44 +0000113};
114
115bool MustExecutePrinter::runOnFunction(Function &F) {
116 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
117 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
118
119 MustExecuteAnnotatedWriter Writer(F, DT, LI);
120 F.print(dbgs(), &Writer);
121
122 return false;
Philip Reames89f22412018-03-20 17:09:21 +0000123}