10b57cec5SDimitry Andric //===-- LiveStacks.cpp - Live Stack Slot Analysis -------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the live stack slot analysis pass. It is analogous to 100b57cec5SDimitry Andric // live interval analysis except it's analyzing liveness of stack slots rather 110b57cec5SDimitry Andric // than registers. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/CodeGen/LiveStacks.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 1881ad6265SDimitry Andric #include "llvm/InitializePasses.h" 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #define DEBUG_TYPE "livestacks" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric char LiveStacks::ID = 0; 240b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(LiveStacks, DEBUG_TYPE, 250b57cec5SDimitry Andric "Live Stack Slot Analysis", false, false) 26*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) 270b57cec5SDimitry Andric INITIALIZE_PASS_END(LiveStacks, DEBUG_TYPE, 280b57cec5SDimitry Andric "Live Stack Slot Analysis", false, false) 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric char &llvm::LiveStacksID = LiveStacks::ID; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const { 330b57cec5SDimitry Andric AU.setPreservesAll(); 34*0fca6ea1SDimitry Andric AU.addPreserved<SlotIndexesWrapperPass>(); 35*0fca6ea1SDimitry Andric AU.addRequiredTransitive<SlotIndexesWrapperPass>(); 360b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric void LiveStacks::releaseMemory() { 400b57cec5SDimitry Andric // Release VNInfo memory regions, VNInfo objects don't need to be dtor'd. 410b57cec5SDimitry Andric VNInfoAllocator.Reset(); 420b57cec5SDimitry Andric S2IMap.clear(); 430b57cec5SDimitry Andric S2RCMap.clear(); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric bool LiveStacks::runOnMachineFunction(MachineFunction &MF) { 470b57cec5SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 480b57cec5SDimitry Andric // FIXME: No analysis is being done right now. We are relying on the 490b57cec5SDimitry Andric // register allocators to provide the information. 500b57cec5SDimitry Andric return false; 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric LiveInterval & 540b57cec5SDimitry Andric LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { 550b57cec5SDimitry Andric assert(Slot >= 0 && "Spill slot indice must be >= 0"); 560b57cec5SDimitry Andric SS2IntervalMap::iterator I = S2IMap.find(Slot); 570b57cec5SDimitry Andric if (I == S2IMap.end()) { 588bcb0991SDimitry Andric I = S2IMap 598bcb0991SDimitry Andric .emplace( 608bcb0991SDimitry Andric std::piecewise_construct, std::forward_as_tuple(Slot), 618bcb0991SDimitry Andric std::forward_as_tuple(Register::index2StackSlot(Slot), 0.0F)) 620b57cec5SDimitry Andric .first; 630b57cec5SDimitry Andric S2RCMap.insert(std::make_pair(Slot, RC)); 640b57cec5SDimitry Andric } else { 650b57cec5SDimitry Andric // Use the largest common subclass register class. 660b57cec5SDimitry Andric const TargetRegisterClass *OldRC = S2RCMap[Slot]; 670b57cec5SDimitry Andric S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric return I->second; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// print - Implement the dump method. 730b57cec5SDimitry Andric void LiveStacks::print(raw_ostream &OS, const Module*) const { 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric OS << "********** INTERVALS **********\n"; 760b57cec5SDimitry Andric for (const_iterator I = begin(), E = end(); I != E; ++I) { 770b57cec5SDimitry Andric I->second.print(OS); 780b57cec5SDimitry Andric int Slot = I->first; 790b57cec5SDimitry Andric const TargetRegisterClass *RC = getIntervalRegClass(Slot); 800b57cec5SDimitry Andric if (RC) 810b57cec5SDimitry Andric OS << " [" << TRI->getRegClassName(RC) << "]\n"; 820b57cec5SDimitry Andric else 830b57cec5SDimitry Andric OS << " [Unknown]\n"; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric } 86