xref: /llvm-project/llvm/lib/CodeGen/RegAllocScore.cpp (revision 735ab61ac828bd61398e6847d60e308fdf2b54ec)
1fa99cb64SMircea Trofin //===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===//
2fa99cb64SMircea Trofin //
3fa99cb64SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fa99cb64SMircea Trofin // See https://llvm.org/LICENSE.txt for license information.
5fa99cb64SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fa99cb64SMircea Trofin //
7fa99cb64SMircea Trofin //===----------------------------------------------------------------------===//
8fa99cb64SMircea Trofin /// Calculate a measure of the register allocation policy quality. This is used
9fa99cb64SMircea Trofin /// to construct a reward for the training of the ML-driven allocation policy.
10fa99cb64SMircea Trofin /// Currently, the score is the sum of the machine basic block frequency-weighed
11fa99cb64SMircea Trofin /// number of loads, stores, copies, and remat instructions, each factored with
12fa99cb64SMircea Trofin /// a relative weight.
13fa99cb64SMircea Trofin //===----------------------------------------------------------------------===//
14fa99cb64SMircea Trofin 
15fa99cb64SMircea Trofin #include "RegAllocScore.h"
16ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineBasicBlock.h"
17ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
18ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineFunction.h"
19ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineInstr.h"
20fa99cb64SMircea Trofin #include "llvm/CodeGen/TargetInstrInfo.h"
21989f1c72Sserge-sans-paille #include "llvm/CodeGen/TargetSubtargetInfo.h"
22989f1c72Sserge-sans-paille #include "llvm/MC/MCInstrDesc.h"
23989f1c72Sserge-sans-paille #include "llvm/Support/CommandLine.h"
24fa99cb64SMircea Trofin 
25fa99cb64SMircea Trofin using namespace llvm;
26fa99cb64SMircea Trofin cl::opt<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden);
27fa99cb64SMircea Trofin cl::opt<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden);
28fa99cb64SMircea Trofin cl::opt<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden);
29fa99cb64SMircea Trofin cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2),
30fa99cb64SMircea Trofin                                  cl::Hidden);
31fa99cb64SMircea Trofin cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
32fa99cb64SMircea Trofin                                      cl::init(1.0), cl::Hidden);
33fa99cb64SMircea Trofin #define DEBUG_TYPE "regalloc-score"
34fa99cb64SMircea Trofin 
35fa99cb64SMircea Trofin RegAllocScore &RegAllocScore::operator+=(const RegAllocScore &Other) {
36fa99cb64SMircea Trofin   CopyCounts += Other.copyCounts();
37fa99cb64SMircea Trofin   LoadCounts += Other.loadCounts();
38fa99cb64SMircea Trofin   StoreCounts += Other.storeCounts();
39fa99cb64SMircea Trofin   LoadStoreCounts += Other.loadStoreCounts();
40fa99cb64SMircea Trofin   CheapRematCounts += Other.cheapRematCounts();
41fa99cb64SMircea Trofin   ExpensiveRematCounts += Other.expensiveRematCounts();
42fa99cb64SMircea Trofin   return *this;
43fa99cb64SMircea Trofin }
44fa99cb64SMircea Trofin 
45fa99cb64SMircea Trofin bool RegAllocScore::operator==(const RegAllocScore &Other) const {
46fa99cb64SMircea Trofin   return copyCounts() == Other.copyCounts() &&
47fa99cb64SMircea Trofin          loadCounts() == Other.loadCounts() &&
48fa99cb64SMircea Trofin          storeCounts() == Other.storeCounts() &&
49fa99cb64SMircea Trofin          loadStoreCounts() == Other.loadStoreCounts() &&
50fa99cb64SMircea Trofin          cheapRematCounts() == Other.cheapRematCounts() &&
51fa99cb64SMircea Trofin          expensiveRematCounts() == Other.expensiveRematCounts();
52fa99cb64SMircea Trofin }
53fa99cb64SMircea Trofin 
54fa99cb64SMircea Trofin bool RegAllocScore::operator!=(const RegAllocScore &Other) const {
55fa99cb64SMircea Trofin   return !(*this == Other);
56fa99cb64SMircea Trofin }
57fa99cb64SMircea Trofin 
58fa99cb64SMircea Trofin double RegAllocScore::getScore() const {
59fa99cb64SMircea Trofin   double Ret = 0.0;
60fa99cb64SMircea Trofin   Ret += CopyWeight * copyCounts();
61fa99cb64SMircea Trofin   Ret += LoadWeight * loadCounts();
62fa99cb64SMircea Trofin   Ret += StoreWeight * storeCounts();
63fa99cb64SMircea Trofin   Ret += (LoadWeight + StoreWeight) * loadStoreCounts();
64fa99cb64SMircea Trofin   Ret += CheapRematWeight * cheapRematCounts();
65fa99cb64SMircea Trofin   Ret += ExpensiveRematWeight * expensiveRematCounts();
66fa99cb64SMircea Trofin 
67fa99cb64SMircea Trofin   return Ret;
68fa99cb64SMircea Trofin }
69fa99cb64SMircea Trofin 
70fa99cb64SMircea Trofin RegAllocScore
71fa99cb64SMircea Trofin llvm::calculateRegAllocScore(const MachineFunction &MF,
72*8d0383ebSMatt Arsenault                              const MachineBlockFrequencyInfo &MBFI) {
73fa99cb64SMircea Trofin   return calculateRegAllocScore(
74fa99cb64SMircea Trofin       MF,
75fa99cb64SMircea Trofin       [&](const MachineBasicBlock &MBB) {
76fa99cb64SMircea Trofin         return MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
77fa99cb64SMircea Trofin       },
78fa99cb64SMircea Trofin       [&](const MachineInstr &MI) {
79fa99cb64SMircea Trofin         return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
80*8d0383ebSMatt Arsenault             MI);
81fa99cb64SMircea Trofin       });
82fa99cb64SMircea Trofin }
83fa99cb64SMircea Trofin 
84fa99cb64SMircea Trofin RegAllocScore llvm::calculateRegAllocScore(
85fa99cb64SMircea Trofin     const MachineFunction &MF,
86fa99cb64SMircea Trofin     llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
87fa99cb64SMircea Trofin     llvm::function_ref<bool(const MachineInstr &)>
88fa99cb64SMircea Trofin         IsTriviallyRematerializable) {
89fa99cb64SMircea Trofin   RegAllocScore Total;
90fa99cb64SMircea Trofin 
91fa99cb64SMircea Trofin   for (const MachineBasicBlock &MBB : MF) {
92fa99cb64SMircea Trofin     double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB);
93fa99cb64SMircea Trofin     RegAllocScore MBBScore;
94fa99cb64SMircea Trofin 
95fa99cb64SMircea Trofin     for (const MachineInstr &MI : MBB) {
96fa99cb64SMircea Trofin       if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) {
97fa99cb64SMircea Trofin         continue;
98fa99cb64SMircea Trofin       }
99fa99cb64SMircea Trofin       if (MI.isCopy()) {
100fa99cb64SMircea Trofin         MBBScore.onCopy(BlockFreqRelativeToEntrypoint);
101fa99cb64SMircea Trofin       } else if (IsTriviallyRematerializable(MI)) {
102fa99cb64SMircea Trofin         if (MI.getDesc().isAsCheapAsAMove()) {
103fa99cb64SMircea Trofin           MBBScore.onCheapRemat(BlockFreqRelativeToEntrypoint);
104fa99cb64SMircea Trofin         } else {
105fa99cb64SMircea Trofin           MBBScore.onExpensiveRemat(BlockFreqRelativeToEntrypoint);
106fa99cb64SMircea Trofin         }
107fa99cb64SMircea Trofin       } else if (MI.mayLoad() && MI.mayStore()) {
108fa99cb64SMircea Trofin         MBBScore.onLoadStore(BlockFreqRelativeToEntrypoint);
109fa99cb64SMircea Trofin       } else if (MI.mayLoad()) {
110fa99cb64SMircea Trofin         MBBScore.onLoad(BlockFreqRelativeToEntrypoint);
111fa99cb64SMircea Trofin       } else if (MI.mayStore()) {
112fa99cb64SMircea Trofin         MBBScore.onStore(BlockFreqRelativeToEntrypoint);
113fa99cb64SMircea Trofin       }
114fa99cb64SMircea Trofin     }
115fa99cb64SMircea Trofin     Total += MBBScore;
116fa99cb64SMircea Trofin   }
117fa99cb64SMircea Trofin   return Total;
118fa99cb64SMircea Trofin }
119