brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.0 KiB · aed68af Raw
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