xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/RegAllocScore.h (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
10eae32dcSDimitry Andric //==- RegAllocScore.h - evaluate regalloc policy quality  ----------*-C++-*-==//
20eae32dcSDimitry Andric //
30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60eae32dcSDimitry Andric //
70eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
80eae32dcSDimitry Andric /// Calculate a measure of the register allocation policy quality. This is used
90eae32dcSDimitry Andric /// to construct a reward for the training of the ML-driven allocation policy.
100eae32dcSDimitry Andric /// Currently, the score is the sum of the machine basic block frequency-weighed
110eae32dcSDimitry Andric /// number of loads, stores, copies, and remat instructions, each factored with
120eae32dcSDimitry Andric /// a relative weight.
130eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
140eae32dcSDimitry Andric 
150eae32dcSDimitry Andric #ifndef LLVM_CODEGEN_REGALLOCSCORE_H_
160eae32dcSDimitry Andric #define LLVM_CODEGEN_REGALLOCSCORE_H_
170eae32dcSDimitry Andric 
1881ad6265SDimitry Andric #include "llvm/ADT/STLFunctionalExtras.h"
190eae32dcSDimitry Andric 
200eae32dcSDimitry Andric namespace llvm {
210eae32dcSDimitry Andric 
2281ad6265SDimitry Andric class MachineBasicBlock;
2381ad6265SDimitry Andric class MachineBlockFrequencyInfo;
2481ad6265SDimitry Andric class MachineFunction;
2581ad6265SDimitry Andric class MachineInstr;
2681ad6265SDimitry Andric 
270eae32dcSDimitry Andric /// Regalloc score.
280eae32dcSDimitry Andric class RegAllocScore final {
290eae32dcSDimitry Andric   double CopyCounts = 0.0;
300eae32dcSDimitry Andric   double LoadCounts = 0.0;
310eae32dcSDimitry Andric   double StoreCounts = 0.0;
320eae32dcSDimitry Andric   double CheapRematCounts = 0.0;
330eae32dcSDimitry Andric   double LoadStoreCounts = 0.0;
340eae32dcSDimitry Andric   double ExpensiveRematCounts = 0.0;
350eae32dcSDimitry Andric 
360eae32dcSDimitry Andric public:
370eae32dcSDimitry Andric   RegAllocScore() = default;
380eae32dcSDimitry Andric   RegAllocScore(const RegAllocScore &) = default;
390eae32dcSDimitry Andric 
copyCounts()400eae32dcSDimitry Andric   double copyCounts() const { return CopyCounts; }
loadCounts()410eae32dcSDimitry Andric   double loadCounts() const { return LoadCounts; }
storeCounts()420eae32dcSDimitry Andric   double storeCounts() const { return StoreCounts; }
loadStoreCounts()430eae32dcSDimitry Andric   double loadStoreCounts() const { return LoadStoreCounts; }
expensiveRematCounts()440eae32dcSDimitry Andric   double expensiveRematCounts() const { return ExpensiveRematCounts; }
cheapRematCounts()450eae32dcSDimitry Andric   double cheapRematCounts() const { return CheapRematCounts; }
460eae32dcSDimitry Andric 
onCopy(double Freq)470eae32dcSDimitry Andric   void onCopy(double Freq) { CopyCounts += Freq; }
onLoad(double Freq)480eae32dcSDimitry Andric   void onLoad(double Freq) { LoadCounts += Freq; }
onStore(double Freq)490eae32dcSDimitry Andric   void onStore(double Freq) { StoreCounts += Freq; }
onLoadStore(double Freq)500eae32dcSDimitry Andric   void onLoadStore(double Freq) { LoadStoreCounts += Freq; }
onExpensiveRemat(double Freq)510eae32dcSDimitry Andric   void onExpensiveRemat(double Freq) { ExpensiveRematCounts += Freq; }
onCheapRemat(double Freq)520eae32dcSDimitry Andric   void onCheapRemat(double Freq) { CheapRematCounts += Freq; }
530eae32dcSDimitry Andric 
540eae32dcSDimitry Andric   RegAllocScore &operator+=(const RegAllocScore &Other);
550eae32dcSDimitry Andric   bool operator==(const RegAllocScore &Other) const;
560eae32dcSDimitry Andric   bool operator!=(const RegAllocScore &Other) const;
570eae32dcSDimitry Andric   double getScore() const;
580eae32dcSDimitry Andric };
590eae32dcSDimitry Andric 
600eae32dcSDimitry Andric /// Calculate a score. When comparing 2 scores for the same function but
610eae32dcSDimitry Andric /// different policies, the better policy would have a smaller score.
620eae32dcSDimitry Andric /// The implementation is the overload below (which is also easily unittestable)
630eae32dcSDimitry Andric RegAllocScore calculateRegAllocScore(const MachineFunction &MF,
64*fcaf7f86SDimitry Andric                                      const MachineBlockFrequencyInfo &MBFI);
650eae32dcSDimitry Andric 
660eae32dcSDimitry Andric /// Implementation of the above, which is also more easily unittestable.
670eae32dcSDimitry Andric RegAllocScore calculateRegAllocScore(
680eae32dcSDimitry Andric     const MachineFunction &MF,
690eae32dcSDimitry Andric     llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
700eae32dcSDimitry Andric     llvm::function_ref<bool(const MachineInstr &)> IsTriviallyRematerializable);
710eae32dcSDimitry Andric } // end namespace llvm
720eae32dcSDimitry Andric 
730eae32dcSDimitry Andric #endif // LLVM_CODEGEN_REGALLOCSCORE_H_
74