1 //===- bolt/Passes/StackReachingUses.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_STACKREACHINGUSES_H 10 #define BOLT_PASSES_STACKREACHINGUSES_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 class FrameAnalysis; 23 struct FrameIndexEntry; 24 25 class StackReachingUses 26 : public InstrsDataflowAnalysis<StackReachingUses, /*Backward=*/true> { 27 friend class DataflowAnalysis<StackReachingUses, BitVector, true>; 28 29 public: 30 StackReachingUses(const FrameAnalysis &FA, BinaryFunction &BF, 31 MCPlusBuilder::AllocatorIdTy AllocId = 0) InstrsDataflowAnalysis(BF,AllocId)32 : InstrsDataflowAnalysis(BF, AllocId), FA(FA) {} ~StackReachingUses()33 virtual ~StackReachingUses() {} 34 35 /// Return true if the stack position written by the store in \p StoreFIE was 36 /// later consumed by a load to a different register (not the same one used in 37 /// the store). Useful for identifying loads/stores of callee-saved regs. 38 bool isLoadedInDifferentReg(const FrameIndexEntry &StoreFIE, 39 ExprIterator Candidates) const; 40 41 /// Answer whether the stack position written by the store represented in 42 /// \p StoreFIE is loaded from or consumed in any way. The set of all 43 /// relevant expressions reaching this store should be in \p Candidates. 44 /// If \p IncludelocalAccesses is false, we only consider whether there is 45 /// a callee that consumes this stack position. 46 bool isStoreUsed(const FrameIndexEntry &StoreFIE, ExprIterator Candidates, 47 bool IncludeLocalAccesses = true) const; 48 run()49 void run() { InstrsDataflowAnalysis<StackReachingUses, true>::run(); } 50 51 protected: 52 // Reference to the result of stack frame analysis 53 const FrameAnalysis &FA; 54 55 void preflight(); 56 getStartingStateAtBB(const BinaryBasicBlock & BB)57 BitVector getStartingStateAtBB(const BinaryBasicBlock &BB) { 58 return BitVector(NumInstrs, false); 59 } 60 getStartingStateAtPoint(const MCInst & Point)61 BitVector getStartingStateAtPoint(const MCInst &Point) { 62 return BitVector(NumInstrs, false); 63 } 64 doConfluence(BitVector & StateOut,const BitVector & StateIn)65 void doConfluence(BitVector &StateOut, const BitVector &StateIn) { 66 StateOut |= StateIn; 67 } 68 69 // Define the function computing the kill set -- whether expression Y, a 70 // tracked expression, will be considered to be dead after executing X. 71 bool doesXKillsY(const MCInst *X, const MCInst *Y); 72 BitVector computeNext(const MCInst &Point, const BitVector &Cur); 73 getAnnotationName()74 StringRef getAnnotationName() const { return StringRef("StackReachingUses"); } 75 }; 76 77 } // end namespace bolt 78 } // end namespace llvm 79 80 #endif 81