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/InitializePasses.h" |
19 | using namespace llvm; |
20 | |
21 | #define DEBUG_TYPE "livestacks" |
22 | |
23 | char LiveStacks::ID = 0; |
24 | INITIALIZE_PASS_BEGIN(LiveStacks, DEBUG_TYPE, |
25 | "Live Stack Slot Analysis" , false, false) |
26 | INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) |
27 | INITIALIZE_PASS_END(LiveStacks, DEBUG_TYPE, |
28 | "Live Stack Slot Analysis" , false, false) |
29 | |
30 | char &llvm::LiveStacksID = LiveStacks::ID; |
31 | |
32 | void LiveStacks::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 | bool LiveStacks::runOnMachineFunction(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 | return false; |
51 | } |
52 | |
53 | LiveInterval & |
54 | LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { |
55 | assert(Slot >= 0 && "Spill slot indice must be >= 0" ); |
56 | SS2IntervalMap::iterator I = S2IMap.find(x: Slot); |
57 | if (I == S2IMap.end()) { |
58 | I = S2IMap |
59 | .emplace( |
60 | args: std::piecewise_construct, args: std::forward_as_tuple(args&: Slot), |
61 | args: std::forward_as_tuple(args: Register::index2StackSlot(FI: Slot), args: 0.0F)) |
62 | .first; |
63 | S2RCMap.insert(x: std::make_pair(x&: Slot, y&: RC)); |
64 | } else { |
65 | // Use the largest common subclass register class. |
66 | const TargetRegisterClass *OldRC = S2RCMap[Slot]; |
67 | S2RCMap[Slot] = TRI->getCommonSubClass(A: OldRC, B: RC); |
68 | } |
69 | return I->second; |
70 | } |
71 | |
72 | /// print - Implement the dump method. |
73 | void LiveStacks::print(raw_ostream &OS, const Module*) const { |
74 | |
75 | OS << "********** INTERVALS **********\n" ; |
76 | for (const_iterator I = begin(), E = end(); I != E; ++I) { |
77 | I->second.print(OS); |
78 | int Slot = I->first; |
79 | const TargetRegisterClass *RC = getIntervalRegClass(Slot); |
80 | if (RC) |
81 | OS << " [" << TRI->getRegClassName(Class: RC) << "]\n" ; |
82 | else |
83 | OS << " [Unknown]\n" ; |
84 | } |
85 | } |
86 | |