Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:27

0001 //===- lib/CodeGen/CalcSpillWeights.h ---------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
0010 #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
0011 
0012 #include "llvm/CodeGen/SlotIndexes.h"
0013 
0014 namespace llvm {
0015 
0016 class LiveInterval;
0017 class LiveIntervals;
0018 class MachineBlockFrequencyInfo;
0019 class MachineFunction;
0020 class MachineLoopInfo;
0021 class ProfileSummaryInfo;
0022 class VirtRegMap;
0023 
0024   /// Normalize the spill weight of a live interval
0025   ///
0026   /// The spill weight of a live interval is computed as:
0027   ///
0028   ///   (sum(use freq) + sum(def freq)) / (K + size)
0029   ///
0030   /// @param UseDefFreq Expected number of executed use and def instructions
0031   ///                   per function call. Derived from block frequencies.
0032   /// @param Size       Size of live interval as returnexd by getSize()
0033   /// @param NumInstr   Number of instructions using this live interval
0034   static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size,
0035                                            unsigned NumInstr) {
0036     // The constant 25 instructions is added to avoid depending too much on
0037     // accidental SlotIndex gaps for small intervals. The effect is that small
0038     // intervals have a spill weight that is mostly proportional to the number
0039     // of uses, while large intervals get a spill weight that is closer to a use
0040     // density.
0041     return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
0042   }
0043 
0044   /// Calculate auxiliary information for a virtual register such as its
0045   /// spill weight and allocation hint.
0046   class VirtRegAuxInfo {
0047     MachineFunction &MF;
0048     LiveIntervals &LIS;
0049     const VirtRegMap &VRM;
0050     const MachineLoopInfo &Loops;
0051     ProfileSummaryInfo *PSI;
0052     const MachineBlockFrequencyInfo &MBFI;
0053 
0054     /// Returns true if Reg of live interval LI is used in instruction with many
0055     /// operands like STATEPOINT.
0056     bool isLiveAtStatepointVarArg(LiveInterval &LI);
0057 
0058   public:
0059     VirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS,
0060                    const VirtRegMap &VRM, const MachineLoopInfo &Loops,
0061                    const MachineBlockFrequencyInfo &MBFI,
0062                    ProfileSummaryInfo *PSI = nullptr)
0063         : MF(MF), LIS(LIS), VRM(VRM), Loops(Loops), PSI(PSI), MBFI(MBFI) {}
0064 
0065     virtual ~VirtRegAuxInfo() = default;
0066 
0067     /// (re)compute li's spill weight and allocation hint.
0068     void calculateSpillWeightAndHint(LiveInterval &LI);
0069 
0070     /// Compute spill weights and allocation hints for all virtual register
0071     /// live intervals.
0072     void calculateSpillWeightsAndHints();
0073 
0074     /// Return the preferred allocation register for reg, given a COPY
0075     /// instruction.
0076     static Register copyHint(const MachineInstr *MI, unsigned Reg,
0077                              const TargetRegisterInfo &TRI,
0078                              const MachineRegisterInfo &MRI);
0079 
0080     /// Determine if all values in LI are rematerializable.
0081     static bool isRematerializable(const LiveInterval &LI,
0082                                    const LiveIntervals &LIS,
0083                                    const VirtRegMap &VRM,
0084                                    const TargetInstrInfo &TII);
0085 
0086   protected:
0087     /// Helper function for weight calculations.
0088     /// (Re)compute LI's spill weight and allocation hint, or, for non null
0089     /// start and end - compute future expected spill weight of a split
0090     /// artifact of LI that will span between start and end slot indexes.
0091     /// \param LI     The live interval for which to compute the weight.
0092     /// \param Start  The expected beginning of the split artifact. Instructions
0093     ///               before start will not affect the weight. Relevant for
0094     ///               weight calculation of future split artifact.
0095     /// \param End    The expected end of the split artifact. Instructions
0096     ///               after end will not affect the weight. Relevant for
0097     ///               weight calculation of future split artifact.
0098     /// \return The spill weight. Returns negative weight for unspillable LI.
0099     float weightCalcHelper(LiveInterval &LI, SlotIndex *Start = nullptr,
0100                            SlotIndex *End = nullptr);
0101 
0102     /// Weight normalization function.
0103     virtual float normalize(float UseDefFreq, unsigned Size,
0104                             unsigned NumInstr) {
0105       return normalizeSpillWeight(UseDefFreq, Size, NumInstr);
0106     }
0107   };
0108 } // end namespace llvm
0109 
0110 #endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H