Home | History | Annotate | Download | only in CodeGen
      1 //===- lib/CodeGen/CalcSpillWeights.h ---------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
     11 #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/CodeGen/SlotIndexes.h"
     15 
     16 namespace llvm {
     17 
     18 class LiveInterval;
     19 class LiveIntervals;
     20 class MachineBlockFrequencyInfo;
     21 class MachineFunction;
     22 class MachineLoopInfo;
     23 class VirtRegMap;
     24 
     25   /// \brief Normalize the spill weight of a live interval
     26   ///
     27   /// The spill weight of a live interval is computed as:
     28   ///
     29   ///   (sum(use freq) + sum(def freq)) / (K + size)
     30   ///
     31   /// @param UseDefFreq Expected number of executed use and def instructions
     32   ///                   per function call. Derived from block frequencies.
     33   /// @param Size       Size of live interval as returnexd by getSize()
     34   /// @param NumInstr   Number of instructions using this live interval
     35   static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size,
     36                                            unsigned NumInstr) {
     37     // The constant 25 instructions is added to avoid depending too much on
     38     // accidental SlotIndex gaps for small intervals. The effect is that small
     39     // intervals have a spill weight that is mostly proportional to the number
     40     // of uses, while large intervals get a spill weight that is closer to a use
     41     // density.
     42     return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
     43   }
     44 
     45   /// \brief Calculate auxiliary information for a virtual register such as its
     46   /// spill weight and allocation hint.
     47   class VirtRegAuxInfo {
     48   public:
     49     using NormalizingFn = float (*)(float, unsigned, unsigned);
     50 
     51   private:
     52     MachineFunction &MF;
     53     LiveIntervals &LIS;
     54     VirtRegMap *VRM;
     55     const MachineLoopInfo &Loops;
     56     const MachineBlockFrequencyInfo &MBFI;
     57     DenseMap<unsigned, float> Hint;
     58     NormalizingFn normalize;
     59 
     60   public:
     61     VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
     62                    VirtRegMap *vrm, const MachineLoopInfo &loops,
     63                    const MachineBlockFrequencyInfo &mbfi,
     64                    NormalizingFn norm = normalizeSpillWeight)
     65         : MF(mf), LIS(lis), VRM(vrm), Loops(loops), MBFI(mbfi), normalize(norm) {}
     66 
     67     /// \brief (re)compute li's spill weight and allocation hint.
     68     void calculateSpillWeightAndHint(LiveInterval &li);
     69   };
     70 
     71   /// \brief Compute spill weights and allocation hints for all virtual register
     72   /// live intervals.
     73   void calculateSpillWeightsAndHints(LiveIntervals &LIS, MachineFunction &MF,
     74                                      VirtRegMap *VRM,
     75                                      const MachineLoopInfo &MLI,
     76                                      const MachineBlockFrequencyInfo &MBFI,
     77                                      VirtRegAuxInfo::NormalizingFn norm =
     78                                          normalizeSpillWeight);
     79 
     80 } // end namespace llvm
     81 
     82 #endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H
     83