//===- lib/CodeGen/CalcSpillWeights.h ---------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H #include "llvm/CodeGen/SlotIndexes.h" namespace llvm { class LiveInterval; class LiveIntervals; class MachineBlockFrequencyInfo; class MachineFunction; class MachineLoopInfo; class VirtRegMap; /// Normalize the spill weight of a live interval /// /// The spill weight of a live interval is computed as: /// /// (sum(use freq) + sum(def freq)) / (K + size) /// /// @param UseDefFreq Expected number of executed use and def instructions /// per function call. Derived from block frequencies. /// @param Size Size of live interval as returnexd by getSize() /// @param NumInstr Number of instructions using this live interval static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size, unsigned NumInstr) { // The constant 25 instructions is added to avoid depending too much on // accidental SlotIndex gaps for small intervals. The effect is that small // intervals have a spill weight that is mostly proportional to the number // of uses, while large intervals get a spill weight that is closer to a use // density. return UseDefFreq / (Size + 25*SlotIndex::InstrDist); } /// Calculate auxiliary information for a virtual register such as its /// spill weight and allocation hint. class VirtRegAuxInfo { MachineFunction &MF; LiveIntervals &LIS; const VirtRegMap &VRM; const MachineLoopInfo &Loops; const MachineBlockFrequencyInfo &MBFI; /// Returns true if Reg of live interval LI is used in instruction with many /// operands like STATEPOINT. bool isLiveAtStatepointVarArg(LiveInterval &LI); public: VirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, const VirtRegMap &VRM, const MachineLoopInfo &Loops, const MachineBlockFrequencyInfo &MBFI) : MF(MF), LIS(LIS), VRM(VRM), Loops(Loops), MBFI(MBFI) {} virtual ~VirtRegAuxInfo() = default; /// (re)compute li's spill weight and allocation hint. void calculateSpillWeightAndHint(LiveInterval &LI); /// Compute spill weights and allocation hints for all virtual register /// live intervals. void calculateSpillWeightsAndHints(); /// Return the preferred allocation register for reg, given a COPY /// instruction. static Register copyHint(const MachineInstr *MI, unsigned Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI); /// Determine if all values in LI are rematerializable. static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const TargetInstrInfo &TII); protected: /// Helper function for weight calculations. /// (Re)compute LI's spill weight and allocation hint, or, for non null /// start and end - compute future expected spill weight of a split /// artifact of LI that will span between start and end slot indexes. /// \param LI The live interval for which to compute the weight. /// \param Start The expected beginning of the split artifact. Instructions /// before start will not affect the weight. Relevant for /// weight calculation of future split artifact. /// \param End The expected end of the split artifact. Instructions /// after end will not affect the weight. Relevant for /// weight calculation of future split artifact. /// \return The spill weight. Returns negative weight for unspillable LI. float weightCalcHelper(LiveInterval &LI, SlotIndex *Start = nullptr, SlotIndex *End = nullptr); /// Weight normalization function. virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) { return normalizeSpillWeight(UseDefFreq, Size, NumInstr); } }; } // end namespace llvm #endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H