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