xref: /llvm-project/bolt/include/bolt/Passes/ReachingInsns.h (revision fd38366e4525c5507bbb2a2fc1f7d113a964224e)
1 //===- bolt/Passes/ReachingInsns.h ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef BOLT_PASSES_REACHINGINSNS_H
10 #define BOLT_PASSES_REACHINGINSNS_H
11 
12 #include "bolt/Passes/DataflowAnalysis.h"
13 #include "llvm/Support/CommandLine.h"
14 
15 namespace opts {
16 extern llvm::cl::opt<bool> TimeOpts;
17 }
18 
19 namespace llvm {
20 namespace bolt {
21 
22 template <bool Backward = false>
23 class ReachingInsns
24     : public InstrsDataflowAnalysis<ReachingInsns<Backward>, Backward> {
25   friend class DataflowAnalysis<ReachingInsns<Backward>, BitVector, Backward>;
26 
27 public:
28   ReachingInsns(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId = 0)
29       : InstrsDataflowAnalysis<ReachingInsns, Backward>(BF, AllocId) {}
~ReachingInsns()30   virtual ~ReachingInsns() {}
31 
isInLoop(const BinaryBasicBlock & BB)32   bool isInLoop(const BinaryBasicBlock &BB) {
33     const MCInst *First = BB.begin() != BB.end() ? &*BB.begin() : nullptr;
34     assert(First && "This analysis does not work for empty BB");
35     return ((*this->getStateAt(BB))[this->ExprToIdx[First]]);
36   }
37 
isInLoop(const MCInst & Inst)38   bool isInLoop(const MCInst &Inst) {
39     const BinaryBasicBlock *BB = InsnToBB[&Inst];
40     assert(BB && "Unknown instruction");
41     return isInLoop(*BB);
42   }
43 
run()44   void run() {
45     InstrsDataflowAnalysis<ReachingInsns<Backward>, Backward>::run();
46   }
47 
48 protected:
49   std::unordered_map<const MCInst *, BinaryBasicBlock *> InsnToBB;
50 
preflight()51   void preflight() {
52     for (BinaryBasicBlock &BB : this->Func) {
53       for (MCInst &Inst : BB) {
54         this->Expressions.push_back(&Inst);
55         this->ExprToIdx[&Inst] = this->NumInstrs++;
56         InsnToBB[&Inst] = &BB;
57       }
58     }
59   }
60 
getStartingStateAtBB(const BinaryBasicBlock & BB)61   BitVector getStartingStateAtBB(const BinaryBasicBlock &BB) {
62     return BitVector(this->NumInstrs, false);
63   }
64 
getStartingStateAtPoint(const MCInst & Point)65   BitVector getStartingStateAtPoint(const MCInst &Point) {
66     return BitVector(this->NumInstrs, false);
67   }
68 
doConfluence(BitVector & StateOut,const BitVector & StateIn)69   void doConfluence(BitVector &StateOut, const BitVector &StateIn) {
70     StateOut |= StateIn;
71   }
72 
computeNext(const MCInst & Point,const BitVector & Cur)73   BitVector computeNext(const MCInst &Point, const BitVector &Cur) {
74     BitVector Next = Cur;
75     // Gen
76     if (!this->BC.MIB->isCFI(Point))
77       Next.set(this->ExprToIdx[&Point]);
78     return Next;
79   }
80 
getAnnotationName()81   StringRef getAnnotationName() const {
82     if (Backward)
83       return StringRef("ReachingInsnsBackward");
84     return StringRef("ReachingInsns");
85   }
86 };
87 
88 } // end namespace bolt
89 } // end namespace llvm
90 
91 #endif
92