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