1 | //===-- LiveStacks.cpp - Live Stack Slot Analysis -------------------------===// |
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 | #include "llvm/CodeGen/LiveStacks.h" |
16 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
17 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
18 | #include "llvm/IR/Function.h" |
19 | using namespace llvm; |
20 | |
21 | #define DEBUG_TYPE "livestacks" |
22 | |
23 | char LiveStacksWrapperLegacy::ID = 0; |
24 | INITIALIZE_PASS_BEGIN(LiveStacksWrapperLegacy, DEBUG_TYPE, |
25 | "Live Stack Slot Analysis" , false, false) |
26 | INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) |
27 | INITIALIZE_PASS_END(LiveStacksWrapperLegacy, DEBUG_TYPE, |
28 | "Live Stack Slot Analysis" , false, true) |
29 | |
30 | char &llvm::LiveStacksID = LiveStacksWrapperLegacy::ID; |
31 | |
32 | void LiveStacksWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const { |
33 | AU.setPreservesAll(); |
34 | AU.addPreserved<SlotIndexesWrapperPass>(); |
35 | AU.addRequiredTransitive<SlotIndexesWrapperPass>(); |
36 | MachineFunctionPass::getAnalysisUsage(AU); |
37 | } |
38 | |
39 | void LiveStacks::releaseMemory() { |
40 | // Release VNInfo memory regions, VNInfo objects don't need to be dtor'd. |
41 | VNInfoAllocator.Reset(); |
42 | S2IMap.clear(); |
43 | S2RCMap.clear(); |
44 | } |
45 | |
46 | void LiveStacks::init(MachineFunction &MF) { |
47 | TRI = MF.getSubtarget().getRegisterInfo(); |
48 | // FIXME: No analysis is being done right now. We are relying on the |
49 | // register allocators to provide the information. |
50 | } |
51 | |
52 | LiveInterval & |
53 | LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { |
54 | assert(Slot >= 0 && "Spill slot indice must be >= 0" ); |
55 | SS2IntervalMap::iterator I = S2IMap.find(x: Slot); |
56 | if (I == S2IMap.end()) { |
57 | I = S2IMap |
58 | .emplace( |
59 | args: std::piecewise_construct, args: std::forward_as_tuple(args&: Slot), |
60 | args: std::forward_as_tuple(args: Register::index2StackSlot(FI: Slot), args: 0.0F)) |
61 | .first; |
62 | S2RCMap.insert(x: std::make_pair(x&: Slot, y&: RC)); |
63 | } else { |
64 | // Use the largest common subclass register class. |
65 | const TargetRegisterClass *&OldRC = S2RCMap[Slot]; |
66 | OldRC = TRI->getCommonSubClass(A: OldRC, B: RC); |
67 | } |
68 | return I->second; |
69 | } |
70 | |
71 | AnalysisKey LiveStacksAnalysis::Key; |
72 | |
73 | LiveStacks LiveStacksAnalysis::run(MachineFunction &MF, |
74 | MachineFunctionAnalysisManager &) { |
75 | LiveStacks Impl; |
76 | Impl.init(MF); |
77 | return Impl; |
78 | } |
79 | PreservedAnalyses |
80 | LiveStacksPrinterPass::run(MachineFunction &MF, |
81 | MachineFunctionAnalysisManager &AM) { |
82 | AM.getResult<LiveStacksAnalysis>(IR&: MF).print(O&: OS, M: MF.getFunction().getParent()); |
83 | return PreservedAnalyses::all(); |
84 | } |
85 | |
86 | bool LiveStacksWrapperLegacy::runOnMachineFunction(MachineFunction &MF) { |
87 | Impl = LiveStacks(); |
88 | Impl.init(MF); |
89 | return false; |
90 | } |
91 | |
92 | void LiveStacksWrapperLegacy::releaseMemory() { Impl = LiveStacks(); } |
93 | |
94 | void LiveStacksWrapperLegacy::print(raw_ostream &OS, const Module *) const { |
95 | Impl.print(O&: OS); |
96 | } |
97 | |
98 | /// print - Implement the dump method. |
99 | void LiveStacks::print(raw_ostream &OS, const Module*) const { |
100 | |
101 | OS << "********** INTERVALS **********\n" ; |
102 | for (const_iterator I = begin(), E = end(); I != E; ++I) { |
103 | I->second.print(OS); |
104 | int Slot = I->first; |
105 | const TargetRegisterClass *RC = getIntervalRegClass(Slot); |
106 | if (RC) |
107 | OS << " [" << TRI->getRegClassName(Class: RC) << "]\n" ; |
108 | else |
109 | OS << " [Unknown]\n" ; |
110 | } |
111 | } |
112 | |