xref: /llvm-project/bolt/include/bolt/Passes/StackReachingUses.h (revision 1a2f83366b86433bb86f3b60fa19b3f096313a21)
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