270 lines · cpp
1//===-- MachineFrameInfo.cpp ---------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file Implements MachineFrameInfo that manages the stack frame.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/MachineFrameInfo.h"14 15#include "llvm/ADT/BitVector.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/MachineRegisterInfo.h"18#include "llvm/CodeGen/TargetFrameLowering.h"19#include "llvm/CodeGen/TargetInstrInfo.h"20#include "llvm/CodeGen/TargetRegisterInfo.h"21#include "llvm/CodeGen/TargetSubtargetInfo.h"22#include "llvm/Config/llvm-config.h"23#include "llvm/Support/Debug.h"24#include "llvm/Support/raw_ostream.h"25#include <cassert>26 27#define DEBUG_TYPE "codegen"28 29using namespace llvm;30 31void MachineFrameInfo::ensureMaxAlignment(Align Alignment) {32 if (!StackRealignable)33 assert(Alignment <= StackAlignment &&34 "For targets without stack realignment, Alignment is out of limit!");35 if (MaxAlignment < Alignment)36 MaxAlignment = Alignment;37}38 39/// Clamp the alignment if requested and emit a warning.40static inline Align clampStackAlignment(bool ShouldClamp, Align Alignment,41 Align StackAlignment) {42 if (!ShouldClamp || Alignment <= StackAlignment)43 return Alignment;44 LLVM_DEBUG(dbgs() << "Warning: requested alignment " << DebugStr(Alignment)45 << " exceeds the stack alignment "46 << DebugStr(StackAlignment)47 << " when stack realignment is off" << '\n');48 return StackAlignment;49}50 51int MachineFrameInfo::CreateStackObject(uint64_t Size, Align Alignment,52 bool IsSpillSlot,53 const AllocaInst *Alloca,54 uint8_t StackID) {55 assert(Size != 0 && "Cannot allocate zero size stack objects!");56 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);57 Objects.push_back(StackObject(Size, Alignment, 0, false, IsSpillSlot, Alloca,58 !IsSpillSlot, StackID));59 int Index = (int)Objects.size() - NumFixedObjects - 1;60 assert(Index >= 0 && "Bad frame index!");61 if (contributesToMaxAlignment(StackID))62 ensureMaxAlignment(Alignment);63 return Index;64}65 66int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, Align Alignment) {67 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);68 CreateStackObject(Size, Alignment, true);69 int Index = (int)Objects.size() - NumFixedObjects - 1;70 ensureMaxAlignment(Alignment);71 return Index;72}73 74int MachineFrameInfo::CreateVariableSizedObject(Align Alignment,75 const AllocaInst *Alloca) {76 HasVarSizedObjects = true;77 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);78 Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca, true));79 ensureMaxAlignment(Alignment);80 return (int)Objects.size()-NumFixedObjects-1;81}82 83int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset,84 bool IsImmutable, bool IsAliased) {85 assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");86 // The alignment of the frame index can be determined from its offset from87 // the incoming frame position. If the frame object is at offset 32 and88 // the stack is guaranteed to be 16-byte aligned, then we know that the89 // object is 16-byte aligned. Note that unlike the non-fixed case, if the90 // stack needs realignment, we can't assume that the stack will in fact be91 // aligned.92 Align Alignment =93 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);94 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);95 Objects.insert(Objects.begin(),96 StackObject(Size, Alignment, SPOffset, IsImmutable,97 /*IsSpillSlot=*/false, /*Alloca=*/nullptr,98 IsAliased));99 return -++NumFixedObjects;100}101 102int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size,103 int64_t SPOffset,104 bool IsImmutable) {105 Align Alignment =106 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);107 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);108 Objects.insert(Objects.begin(),109 StackObject(Size, Alignment, SPOffset, IsImmutable,110 /*IsSpillSlot=*/true, /*Alloca=*/nullptr,111 /*IsAliased=*/false));112 return -++NumFixedObjects;113}114 115BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const {116 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();117 BitVector BV(TRI->getNumRegs());118 119 // Before CSI is calculated, no registers are considered pristine. They can be120 // freely used and PEI will make sure they are saved.121 if (!isCalleeSavedInfoValid())122 return BV;123 124 const MachineRegisterInfo &MRI = MF.getRegInfo();125 for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR;126 ++CSR)127 BV.set(*CSR);128 129 // Saved CSRs are not pristine.130 for (const auto &I : getCalleeSavedInfo())131 for (MCPhysReg S : TRI->subregs_inclusive(I.getReg()))132 BV.reset(S);133 134 return BV;135}136 137uint64_t MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const {138 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();139 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();140 Align MaxAlign = getMaxAlign();141 int64_t Offset = 0;142 143 // This code is very, very similar to PEI::calculateFrameObjectOffsets().144 // It really should be refactored to share code. Until then, changes145 // should keep in mind that there's tight coupling between the two.146 147 for (int i = getObjectIndexBegin(); i != 0; ++i) {148 // Only estimate stack size of default stack.149 if (getStackID(i) != TargetStackID::Default)150 continue;151 int64_t FixedOff = -getObjectOffset(i);152 if (FixedOff > Offset) Offset = FixedOff;153 }154 for (unsigned i = 0, e = getObjectIndexEnd(); i != e; ++i) {155 // Only estimate stack size of live objects on default stack.156 if (isDeadObjectIndex(i) || getStackID(i) != TargetStackID::Default)157 continue;158 Offset += getObjectSize(i);159 Align Alignment = getObjectAlign(i);160 // Adjust to alignment boundary161 Offset = alignTo(Offset, Alignment);162 163 MaxAlign = std::max(Alignment, MaxAlign);164 }165 166 if (adjustsStack() && TFI->hasReservedCallFrame(MF))167 Offset += getMaxCallFrameSize();168 169 // Round up the size to a multiple of the alignment. If the function has170 // any calls or alloca's, align to the target's StackAlignment value to171 // ensure that the callee's frame or the alloca data is suitably aligned;172 // otherwise, for leaf functions, align to the TransientStackAlignment173 // value.174 Align StackAlign;175 if (adjustsStack() || hasVarSizedObjects() ||176 (RegInfo->hasStackRealignment(MF) && getObjectIndexEnd() != 0))177 StackAlign = TFI->getStackAlign();178 else179 StackAlign = TFI->getTransientStackAlign();180 181 // If the frame pointer is eliminated, all frame offsets will be relative to182 // SP not FP. Align to MaxAlign so this works.183 StackAlign = std::max(StackAlign, MaxAlign);184 return alignTo(Offset, StackAlign);185}186 187void MachineFrameInfo::computeMaxCallFrameSize(188 MachineFunction &MF, std::vector<MachineBasicBlock::iterator> *FrameSDOps) {189 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();190 unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();191 unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();192 assert(FrameSetupOpcode != ~0u && FrameDestroyOpcode != ~0u &&193 "Can only compute MaxCallFrameSize if Setup/Destroy opcode are known");194 195 MaxCallFrameSize = 0;196 for (MachineBasicBlock &MBB : MF) {197 for (MachineInstr &MI : MBB) {198 unsigned Opcode = MI.getOpcode();199 if (Opcode == FrameSetupOpcode || Opcode == FrameDestroyOpcode) {200 uint64_t Size = TII.getFrameSize(MI);201 MaxCallFrameSize = std::max(MaxCallFrameSize, Size);202 if (FrameSDOps != nullptr)203 FrameSDOps->push_back(&MI);204 }205 }206 }207}208 209void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{210 if (Objects.empty()) return;211 212 const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering();213 int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);214 215 OS << "Frame Objects:\n";216 217 for (unsigned i = 0, e = Objects.size(); i != e; ++i) {218 const StackObject &SO = Objects[i];219 OS << " fi#" << (int)(i-NumFixedObjects) << ": ";220 221 if (SO.StackID != 0)222 OS << "id=" << static_cast<unsigned>(SO.StackID) << ' ';223 224 if (SO.Size == ~0ULL) {225 OS << "dead\n";226 continue;227 }228 if (SO.Size == 0)229 OS << "variable sized";230 else231 OS << "size=" << SO.Size;232 OS << ", align=" << SO.Alignment.value();233 234 if (i < NumFixedObjects)235 OS << ", fixed";236 if (i < NumFixedObjects || SO.SPOffset != -1) {237 int64_t Off = SO.SPOffset - ValOffset;238 OS << ", at location [SP";239 if (Off > 0)240 OS << "+" << Off;241 else if (Off < 0)242 OS << Off;243 OS << "]";244 }245 OS << "\n";246 }247 OS << "save/restore points:\n";248 249 if (!SavePoints.empty()) {250 OS << "save points:\n";251 252 for (auto &item : SavePoints)253 OS << printMBBReference(*item.first) << "\n";254 } else255 OS << "save points are empty\n";256 257 if (!RestorePoints.empty()) {258 OS << "restore points:\n";259 for (auto &item : RestorePoints)260 OS << printMBBReference(*item.first) << "\n";261 } else262 OS << "restore points are empty\n";263}264 265#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)266LLVM_DUMP_METHOD void MachineFrameInfo::dump(const MachineFunction &MF) const {267 print(MF, dbgs());268}269#endif270