xref: /src/contrib/llvm-project/llvm/lib/CodeGen/LiveStacks.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1c7dac04cSDimitry Andric //===-- LiveStacks.cpp - Live Stack Slot Analysis -------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file implements the live stack slot analysis pass. It is analogous to
10009b1c42SEd Schouten // live interval analysis except it's analyzing liveness of stack slots rather
11009b1c42SEd Schouten // than registers.
12009b1c42SEd Schouten //
13009b1c42SEd Schouten //===----------------------------------------------------------------------===//
14009b1c42SEd Schouten 
15c7dac04cSDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
16044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
17044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
18145449b1SDimitry Andric #include "llvm/InitializePasses.h"
19009b1c42SEd Schouten using namespace llvm;
20009b1c42SEd Schouten 
215ca98fd9SDimitry Andric #define DEBUG_TYPE "livestacks"
225ca98fd9SDimitry Andric 
23009b1c42SEd Schouten char LiveStacks::ID = 0;
24ab44ce3dSDimitry Andric INITIALIZE_PASS_BEGIN(LiveStacks, DEBUG_TYPE,
25522600a2SDimitry Andric                 "Live Stack Slot Analysis", false, false)
26ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
27ab44ce3dSDimitry Andric INITIALIZE_PASS_END(LiveStacks, DEBUG_TYPE,
28cf099d11SDimitry Andric                 "Live Stack Slot Analysis", false, false)
29cf099d11SDimitry Andric 
30cf099d11SDimitry Andric char &llvm::LiveStacksID = LiveStacks::ID;
31009b1c42SEd Schouten 
getAnalysisUsage(AnalysisUsage & AU) const32009b1c42SEd Schouten void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const {
33009b1c42SEd Schouten   AU.setPreservesAll();
34ac9a064cSDimitry Andric   AU.addPreserved<SlotIndexesWrapperPass>();
35ac9a064cSDimitry Andric   AU.addRequiredTransitive<SlotIndexesWrapperPass>();
36009b1c42SEd Schouten   MachineFunctionPass::getAnalysisUsage(AU);
37009b1c42SEd Schouten }
38009b1c42SEd Schouten 
releaseMemory()39009b1c42SEd Schouten void LiveStacks::releaseMemory() {
4066e41e3cSRoman Divacky   // Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
4166e41e3cSRoman Divacky   VNInfoAllocator.Reset();
42009b1c42SEd Schouten   S2IMap.clear();
43009b1c42SEd Schouten   S2RCMap.clear();
44009b1c42SEd Schouten }
45009b1c42SEd Schouten 
runOnMachineFunction(MachineFunction & MF)4630815c53SDimitry Andric bool LiveStacks::runOnMachineFunction(MachineFunction &MF) {
4767c32a98SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
48009b1c42SEd Schouten   // FIXME: No analysis is being done right now. We are relying on the
49009b1c42SEd Schouten   // register allocators to provide the information.
50009b1c42SEd Schouten   return false;
51009b1c42SEd Schouten }
52009b1c42SEd Schouten 
53cf099d11SDimitry Andric LiveInterval &
getOrCreateInterval(int Slot,const TargetRegisterClass * RC)54cf099d11SDimitry Andric LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
55cf099d11SDimitry Andric   assert(Slot >= 0 && "Spill slot indice must be >= 0");
56cf099d11SDimitry Andric   SS2IntervalMap::iterator I = S2IMap.find(Slot);
57cf099d11SDimitry Andric   if (I == S2IMap.end()) {
581d5ae102SDimitry Andric     I = S2IMap
591d5ae102SDimitry Andric             .emplace(
601d5ae102SDimitry Andric                 std::piecewise_construct, std::forward_as_tuple(Slot),
611d5ae102SDimitry Andric                 std::forward_as_tuple(Register::index2StackSlot(Slot), 0.0F))
625a5ac124SDimitry Andric             .first;
63cf099d11SDimitry Andric     S2RCMap.insert(std::make_pair(Slot, RC));
64cf099d11SDimitry Andric   } else {
65cf099d11SDimitry Andric     // Use the largest common subclass register class.
66cf099d11SDimitry Andric     const TargetRegisterClass *OldRC = S2RCMap[Slot];
6730815c53SDimitry Andric     S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC);
68cf099d11SDimitry Andric   }
69cf099d11SDimitry Andric   return I->second;
70cf099d11SDimitry Andric }
71cf099d11SDimitry Andric 
72009b1c42SEd Schouten /// print - Implement the dump method.
print(raw_ostream & OS,const Module *) const7359850d08SRoman Divacky void LiveStacks::print(raw_ostream &OS, const Module*) const {
7459850d08SRoman Divacky 
7559850d08SRoman Divacky   OS << "********** INTERVALS **********\n";
76009b1c42SEd Schouten   for (const_iterator I = begin(), E = end(); I != E; ++I) {
7759850d08SRoman Divacky     I->second.print(OS);
78009b1c42SEd Schouten     int Slot = I->first;
79009b1c42SEd Schouten     const TargetRegisterClass *RC = getIntervalRegClass(Slot);
80009b1c42SEd Schouten     if (RC)
8167c32a98SDimitry Andric       OS << " [" << TRI->getRegClassName(RC) << "]\n";
82009b1c42SEd Schouten     else
8359850d08SRoman Divacky       OS << " [Unknown]\n";
84009b1c42SEd Schouten   }
85009b1c42SEd Schouten }
86