1 //===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 /// Calculate a measure of the register allocation policy quality. This is used
9 /// to construct a reward for the training of the ML-driven allocation policy.
10 /// Currently, the score is the sum of the machine basic block frequency-weighed
11 /// number of loads, stores, copies, and remat instructions, each factored with
12 /// a relative weight.
13 //===----------------------------------------------------------------------===//
15 #include "RegAllocScore.h"
16 #include "llvm/ADT/ilist_iterator.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstr.h"
21 #include "llvm/CodeGen/MachineInstrBundleIterator.h"
22 #include "llvm/CodeGen/TargetInstrInfo.h"
23 #include "llvm/CodeGen/TargetSubtargetInfo.h"
24 #include "llvm/MC/MCInstrDesc.h"
25 #include "llvm/Support/CommandLine.h"
28 cl::opt
<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden
);
29 cl::opt
<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden
);
30 cl::opt
<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden
);
31 cl::opt
<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2),
33 cl::opt
<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
34 cl::init(1.0), cl::Hidden
);
35 #define DEBUG_TYPE "regalloc-score"
37 RegAllocScore
&RegAllocScore::operator+=(const RegAllocScore
&Other
) {
38 CopyCounts
+= Other
.copyCounts();
39 LoadCounts
+= Other
.loadCounts();
40 StoreCounts
+= Other
.storeCounts();
41 LoadStoreCounts
+= Other
.loadStoreCounts();
42 CheapRematCounts
+= Other
.cheapRematCounts();
43 ExpensiveRematCounts
+= Other
.expensiveRematCounts();
47 bool RegAllocScore::operator==(const RegAllocScore
&Other
) const {
48 return copyCounts() == Other
.copyCounts() &&
49 loadCounts() == Other
.loadCounts() &&
50 storeCounts() == Other
.storeCounts() &&
51 loadStoreCounts() == Other
.loadStoreCounts() &&
52 cheapRematCounts() == Other
.cheapRematCounts() &&
53 expensiveRematCounts() == Other
.expensiveRematCounts();
56 bool RegAllocScore::operator!=(const RegAllocScore
&Other
) const {
57 return !(*this == Other
);
60 double RegAllocScore::getScore() const {
62 Ret
+= CopyWeight
* copyCounts();
63 Ret
+= LoadWeight
* loadCounts();
64 Ret
+= StoreWeight
* storeCounts();
65 Ret
+= (LoadWeight
+ StoreWeight
) * loadStoreCounts();
66 Ret
+= CheapRematWeight
* cheapRematCounts();
67 Ret
+= ExpensiveRematWeight
* expensiveRematCounts();
73 llvm::calculateRegAllocScore(const MachineFunction
&MF
,
74 const MachineBlockFrequencyInfo
&MBFI
) {
75 return calculateRegAllocScore(
77 [&](const MachineBasicBlock
&MBB
) {
78 return MBFI
.getBlockFreqRelativeToEntryBlock(&MBB
);
80 [&](const MachineInstr
&MI
) {
81 return MF
.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
86 RegAllocScore
llvm::calculateRegAllocScore(
87 const MachineFunction
&MF
,
88 llvm::function_ref
<double(const MachineBasicBlock
&)> GetBBFreq
,
89 llvm::function_ref
<bool(const MachineInstr
&)>
90 IsTriviallyRematerializable
) {
93 for (const MachineBasicBlock
&MBB
: MF
) {
94 double BlockFreqRelativeToEntrypoint
= GetBBFreq(MBB
);
95 RegAllocScore MBBScore
;
97 for (const MachineInstr
&MI
: MBB
) {
98 if (MI
.isDebugInstr() || MI
.isKill() || MI
.isInlineAsm()) {
102 MBBScore
.onCopy(BlockFreqRelativeToEntrypoint
);
103 } else if (IsTriviallyRematerializable(MI
)) {
104 if (MI
.getDesc().isAsCheapAsAMove()) {
105 MBBScore
.onCheapRemat(BlockFreqRelativeToEntrypoint
);
107 MBBScore
.onExpensiveRemat(BlockFreqRelativeToEntrypoint
);
109 } else if (MI
.mayLoad() && MI
.mayStore()) {
110 MBBScore
.onLoadStore(BlockFreqRelativeToEntrypoint
);
111 } else if (MI
.mayLoad()) {
112 MBBScore
.onLoad(BlockFreqRelativeToEntrypoint
);
113 } else if (MI
.mayStore()) {
114 MBBScore
.onStore(BlockFreqRelativeToEntrypoint
);