328 lines · c
1//===-- ARMMachineFunctionInfo.h - ARM machine function info ----*- C++ -*-===//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// This file declares ARM-specific per-machine-function information.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H14#define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H15 16#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/SmallPtrSet.h"18#include "llvm/CodeGen/MIRYamlMapping.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/IR/GlobalVariable.h"21#include "llvm/Support/ErrorHandling.h"22 23namespace llvm {24 25namespace yaml {26struct ARMFunctionInfo;27} // end namespace yaml28 29class ARMSubtarget;30 31/// ARMFunctionInfo - This class is derived from MachineFunctionInfo and32/// contains private ARM-specific information for each MachineFunction.33class ARMFunctionInfo : public MachineFunctionInfo {34 virtual void anchor();35 36 /// isThumb - True if this function is compiled under Thumb mode.37 /// Used to initialized Align, so must precede it.38 bool isThumb = false;39 40 /// hasThumb2 - True if the target architecture supports Thumb2. Do not use41 /// to determine if function is compiled under Thumb mode, for that use42 /// 'isThumb'.43 bool hasThumb2 = false;44 45 /// ArgsRegSaveSize - Size of the register save area for vararg functions or46 /// those making guaranteed tail calls that need more stack argument space47 /// than is provided by this functions incoming parameters.48 ///49 unsigned ArgRegsSaveSize = 0;50 51 /// ReturnRegsCount - Number of registers used up in the return.52 unsigned ReturnRegsCount = 0;53 54 /// HasStackFrame - True if this function has a stack frame. Set by55 /// determineCalleeSaves().56 bool HasStackFrame = false;57 58 /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by59 /// emitPrologue.60 bool RestoreSPFromFP = false;61 62 /// LRSpilled - True if the LR register has been for spilled for63 /// any reason, so it's legal to emit an ARM::tBfar (i.e. "bl").64 bool LRSpilled = false;65 66 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer67 /// spill stack offset.68 unsigned FramePtrSpillOffset = 0;69 70 /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved71 /// register spills areas. For Mac OS X:72 ///73 /// GPR callee-saved (1) : r4, r5, r6, r7, lr74 /// --------------------------------------------75 /// GPR callee-saved (2) : r8, r10, r1176 /// --------------------------------------------77 /// DPR callee-saved : d8 - d1578 ///79 /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.80 /// Some may be spilled after the stack has been realigned.81 unsigned GPRCS1Offset = 0;82 unsigned GPRCS2Offset = 0;83 unsigned DPRCS1Offset = 0;84 85 /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills86 /// areas.87 unsigned FPCXTSaveSize = 0;88 unsigned FRSaveSize = 0;89 unsigned GPRCS1Size = 0;90 unsigned GPRCS2Size = 0;91 unsigned FPStatusSize = 0;92 unsigned DPRCSAlignGapSize = 0;93 unsigned DPRCS1Size = 0;94 unsigned GPRCS3Size = 0;95 96 /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in97 /// the aligned portion of the stack frame. This is always a contiguous98 /// sequence of D-registers starting from d8.99 ///100 /// We do not keep track of the frame indices used for these registers - they101 /// behave like any other frame index in the aligned stack frame. These102 /// registers also aren't included in DPRCSSize above.103 unsigned NumAlignedDPRCS2Regs = 0;104 105 unsigned PICLabelUId = 0;106 107 /// VarArgsFrameIndex - FrameIndex for start of varargs area.108 int VarArgsFrameIndex = 0;109 110 /// HasITBlocks - True if IT blocks have been inserted.111 bool HasITBlocks = false;112 113 // Security Extensions114 bool IsCmseNSEntry;115 bool IsCmseNSCall;116 117 /// CPEClones - Track constant pool entries clones created by Constant Island118 /// pass.119 DenseMap<unsigned, unsigned> CPEClones;120 121 /// ArgumentStackSize - amount of bytes on stack consumed by the arguments122 /// being passed on the stack123 unsigned ArgumentStackSize = 0;124 125 /// ArgumentStackToRestore - amount of bytes on stack consumed that we must126 /// restore on return.127 unsigned ArgumentStackToRestore = 0;128 129 /// CoalescedWeights - mapping of basic blocks to the rolling counter of130 /// coalesced weights.131 DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights;132 133 /// True if this function has a subset of CSRs that is handled explicitly via134 /// copies.135 bool IsSplitCSR = false;136 137 /// Globals that have had their storage promoted into the constant pool.138 SmallPtrSet<const GlobalVariable*,2> PromotedGlobals;139 140 /// The amount the literal pool has been increasedby due to promoted globals.141 int PromotedGlobalsIncrease = 0;142 143 /// True if r0 will be preserved by a call to this function (e.g. C++144 /// con/destructors).145 bool PreservesR0 = false;146 147 /// True if the function should sign its return address.148 bool SignReturnAddress = false;149 150 /// True if the fucntion should sign its return address, even if LR is not151 /// saved.152 bool SignReturnAddressAll = false;153 154 /// True if BTI instructions should be placed at potential indirect jump155 /// destinations.156 bool BranchTargetEnforcement = false;157 158public:159 ARMFunctionInfo() = default;160 161 explicit ARMFunctionInfo(const Function &F, const ARMSubtarget *STI);162 163 MachineFunctionInfo *164 clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,165 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)166 const override;167 168 bool isThumbFunction() const { return isThumb; }169 bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }170 bool isThumb2Function() const { return isThumb && hasThumb2; }171 172 bool isCmseNSEntryFunction() const { return IsCmseNSEntry; }173 bool isCmseNSCallFunction() const { return IsCmseNSCall; }174 175 unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; }176 void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }177 178 unsigned getReturnRegsCount() const { return ReturnRegsCount; }179 void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }180 181 bool hasStackFrame() const { return HasStackFrame; }182 void setHasStackFrame(bool s) { HasStackFrame = s; }183 184 bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }185 void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }186 187 bool isLRSpilled() const { return LRSpilled; }188 void setLRIsSpilled(bool s) { LRSpilled = s; }189 190 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }191 void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }192 193 unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }194 void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }195 196 unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }197 unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }198 unsigned getDPRCalleeSavedArea1Offset() const { return DPRCS1Offset; }199 200 void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }201 void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }202 void setDPRCalleeSavedArea1Offset(unsigned o) { DPRCS1Offset = o; }203 204 unsigned getFPCXTSaveAreaSize() const { return FPCXTSaveSize; }205 unsigned getFrameRecordSavedAreaSize() const { return FRSaveSize; }206 unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }207 unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }208 unsigned getFPStatusSavesSize() const { return FPStatusSize; }209 unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; }210 unsigned getDPRCalleeSavedArea1Size() const { return DPRCS1Size; }211 unsigned getGPRCalleeSavedArea3Size() const { return GPRCS3Size; }212 213 void setFPCXTSaveAreaSize(unsigned s) { FPCXTSaveSize = s; }214 void setFrameRecordSavedAreaSize(unsigned s) { FRSaveSize = s; }215 void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }216 void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }217 void setFPStatusSavesSize(unsigned s) { FPStatusSize = s; }218 void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; }219 void setDPRCalleeSavedArea1Size(unsigned s) { DPRCS1Size = s; }220 void setGPRCalleeSavedArea3Size(unsigned s) { GPRCS3Size = s; }221 222 unsigned getArgumentStackSize() const { return ArgumentStackSize; }223 void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }224 225 unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore; }226 void setArgumentStackToRestore(unsigned v) { ArgumentStackToRestore = v; }227 228 void initPICLabelUId(unsigned UId) {229 PICLabelUId = UId;230 }231 232 unsigned getNumPICLabels() const {233 return PICLabelUId;234 }235 236 unsigned createPICLabelUId() {237 return PICLabelUId++;238 }239 240 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }241 void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }242 243 bool hasITBlocks() const { return HasITBlocks; }244 void setHasITBlocks(bool h) { HasITBlocks = h; }245 246 bool isSplitCSR() const { return IsSplitCSR; }247 void setIsSplitCSR(bool s) { IsSplitCSR = s; }248 249 void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {250 if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)251 llvm_unreachable("Duplicate entries!");252 }253 254 unsigned getOriginalCPIdx(unsigned CloneIdx) const {255 DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);256 if (I != CPEClones.end())257 return I->second;258 else259 return -1U;260 }261 262 DenseMap<const MachineBasicBlock *, unsigned>::iterator263 getCoalescedWeight(MachineBasicBlock *MBB) {264 return CoalescedWeights.try_emplace(MBB, 0).first;265 }266 267 /// Indicate to the backend that \c GV has had its storage changed to inside268 /// a constant pool. This means it no longer needs to be emitted as a269 /// global variable.270 void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV) {271 PromotedGlobals.insert(GV);272 }273 SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() {274 return PromotedGlobals;275 }276 int getPromotedConstpoolIncrease() const {277 return PromotedGlobalsIncrease;278 }279 void setPromotedConstpoolIncrease(int Sz) {280 PromotedGlobalsIncrease = Sz;281 }282 283 DenseMap<unsigned, unsigned> EHPrologueRemappedRegs;284 DenseMap<unsigned, unsigned> EHPrologueOffsetInRegs;285 286 void setPreservesR0() { PreservesR0 = true; }287 bool getPreservesR0() const { return PreservesR0; }288 289 bool shouldSignReturnAddress() const {290 return shouldSignReturnAddress(LRSpilled);291 }292 293 bool shouldSignReturnAddress(bool SpillsLR) const {294 if (!SignReturnAddress)295 return false;296 if (SignReturnAddressAll)297 return true;298 return SpillsLR;299 }300 301 bool branchTargetEnforcement() const { return BranchTargetEnforcement; }302 303 void initializeBaseYamlFields(const yaml::ARMFunctionInfo &YamlMFI);304};305 306namespace yaml {307struct ARMFunctionInfo final : public yaml::MachineFunctionInfo {308 bool LRSpilled;309 310 ARMFunctionInfo() = default;311 ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI);312 313 void mappingImpl(yaml::IO &YamlIO) override;314 ~ARMFunctionInfo() override = default;315};316 317template <> struct MappingTraits<ARMFunctionInfo> {318 static void mapping(IO &YamlIO, ARMFunctionInfo &MFI) {319 YamlIO.mapOptional("isLRSpilled", MFI.LRSpilled);320 }321};322 323} // end namespace yaml324 325} // end namespace llvm326 327#endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H328