xref: /llvm-project/llvm/include/llvm/CodeGen/LiveStacks.h (revision 2c7ece2e8cf58d607f870ca9f02302df8aaa75d4)
1 //===- LiveStacks.h - Live Stack Slot Analysis ------------------*- 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 // This file implements the live stack slot analysis pass. It is analogous to
10 // live interval analysis except it's analyzing liveness of stack slots rather
11 // than registers.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_LIVESTACKS_H
16 #define LLVM_CODEGEN_LIVESTACKS_H
17 
18 #include "llvm/CodeGen/LiveInterval.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/PassRegistry.h"
23 #include <cassert>
24 #include <map>
25 #include <unordered_map>
26 
27 namespace llvm {
28 
29 class AnalysisUsage;
30 class MachineFunction;
31 class Module;
32 class raw_ostream;
33 class TargetRegisterClass;
34 class TargetRegisterInfo;
35 
36 class LiveStacks {
37   const TargetRegisterInfo *TRI = nullptr;
38 
39   /// Special pool allocator for VNInfo's (LiveInterval val#).
40   ///
41   VNInfo::Allocator VNInfoAllocator;
42 
43   /// S2IMap - Stack slot indices to live interval mapping.
44   using SS2IntervalMap = std::unordered_map<int, LiveInterval>;
45   SS2IntervalMap S2IMap;
46 
47   /// S2RCMap - Stack slot indices to register class mapping.
48   std::map<int, const TargetRegisterClass *> S2RCMap;
49 
50 public:
51   using iterator = SS2IntervalMap::iterator;
52   using const_iterator = SS2IntervalMap::const_iterator;
53 
54   const_iterator begin() const { return S2IMap.begin(); }
55   const_iterator end() const { return S2IMap.end(); }
56   iterator begin() { return S2IMap.begin(); }
57   iterator end() { return S2IMap.end(); }
58 
59   unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
60 
61   LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
62 
63   LiveInterval &getInterval(int Slot) {
64     assert(Slot >= 0 && "Spill slot indice must be >= 0");
65     SS2IntervalMap::iterator I = S2IMap.find(Slot);
66     assert(I != S2IMap.end() && "Interval does not exist for stack slot");
67     return I->second;
68   }
69 
70   const LiveInterval &getInterval(int Slot) const {
71     assert(Slot >= 0 && "Spill slot indice must be >= 0");
72     SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
73     assert(I != S2IMap.end() && "Interval does not exist for stack slot");
74     return I->second;
75   }
76 
77   bool hasInterval(int Slot) const { return S2IMap.count(Slot); }
78 
79   const TargetRegisterClass *getIntervalRegClass(int Slot) const {
80     assert(Slot >= 0 && "Spill slot indice must be >= 0");
81     std::map<int, const TargetRegisterClass *>::const_iterator I =
82         S2RCMap.find(Slot);
83     assert(I != S2RCMap.end() &&
84            "Register class info does not exist for stack slot");
85     return I->second;
86   }
87 
88   VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }
89 
90   void releaseMemory();
91   /// init - analysis entry point
92   void init(MachineFunction &MF);
93   void print(raw_ostream &O, const Module *M = nullptr) const;
94 };
95 
96 class LiveStacksWrapperLegacy : public MachineFunctionPass {
97   LiveStacks Impl;
98 
99 public:
100   static char ID; // Pass identification, replacement for typeid
101 
102   LiveStacksWrapperLegacy() : MachineFunctionPass(ID) {
103     initializeLiveStacksWrapperLegacyPass(*PassRegistry::getPassRegistry());
104   }
105 
106   LiveStacks &getLS() { return Impl; }
107   const LiveStacks &getLS() const { return Impl; }
108 
109   void getAnalysisUsage(AnalysisUsage &AU) const override;
110   void releaseMemory() override;
111 
112   /// runOnMachineFunction - pass entry point
113   bool runOnMachineFunction(MachineFunction &) override;
114 
115   /// print - Implement the dump method.
116   void print(raw_ostream &O, const Module * = nullptr) const override;
117 };
118 
119 class LiveStacksAnalysis : public AnalysisInfoMixin<LiveStacksAnalysis> {
120   static AnalysisKey Key;
121   friend AnalysisInfoMixin<LiveStacksAnalysis>;
122 
123 public:
124   using Result = LiveStacks;
125 
126   LiveStacks run(MachineFunction &MF, MachineFunctionAnalysisManager &);
127 };
128 
129 class LiveStacksPrinterPass : public PassInfoMixin<LiveStacksPrinterPass> {
130   raw_ostream &OS;
131 
132 public:
133   LiveStacksPrinterPass(raw_ostream &OS) : OS(OS) {}
134   PreservedAnalyses run(MachineFunction &MF,
135                         MachineFunctionAnalysisManager &AM);
136 };
137 } // end namespace llvm
138 
139 #endif
140