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/DenseMapInfo.h"
17 #include "llvm/ADT/ilist_iterator.h"
18 #include "llvm/CodeGen/MachineBasicBlock.h"
19 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/CodeGen/MachineInstrBundleIterator.h"
23 #include "llvm/CodeGen/TargetInstrInfo.h"
24 #include "llvm/CodeGen/TargetSubtargetInfo.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/Support/CommandLine.h"
29 cl::opt
<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden
);
30 cl::opt
<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden
);
31 cl::opt
<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden
);
32 cl::opt
<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2),
34 cl::opt
<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
35 cl::init(1.0), cl::Hidden
);
36 #define DEBUG_TYPE "regalloc-score"
38 RegAllocScore
&RegAllocScore::operator+=(const RegAllocScore
&Other
) {
39 CopyCounts
+= Other
.copyCounts();
40 LoadCounts
+= Other
.loadCounts();
41 StoreCounts
+= Other
.storeCounts();
42 LoadStoreCounts
+= Other
.loadStoreCounts();
43 CheapRematCounts
+= Other
.cheapRematCounts();
44 ExpensiveRematCounts
+= Other
.expensiveRematCounts();
48 bool RegAllocScore::operator==(const RegAllocScore
&Other
) const {
49 return copyCounts() == Other
.copyCounts() &&
50 loadCounts() == Other
.loadCounts() &&
51 storeCounts() == Other
.storeCounts() &&
52 loadStoreCounts() == Other
.loadStoreCounts() &&
53 cheapRematCounts() == Other
.cheapRematCounts() &&
54 expensiveRematCounts() == Other
.expensiveRematCounts();
57 bool RegAllocScore::operator!=(const RegAllocScore
&Other
) const {
58 return !(*this == Other
);
61 double RegAllocScore::getScore() const {
63 Ret
+= CopyWeight
* copyCounts();
64 Ret
+= LoadWeight
* loadCounts();
65 Ret
+= StoreWeight
* storeCounts();
66 Ret
+= (LoadWeight
+ StoreWeight
) * loadStoreCounts();
67 Ret
+= CheapRematWeight
* cheapRematCounts();
68 Ret
+= ExpensiveRematWeight
* expensiveRematCounts();
74 llvm::calculateRegAllocScore(const MachineFunction
&MF
,
75 const MachineBlockFrequencyInfo
&MBFI
) {
76 return calculateRegAllocScore(
78 [&](const MachineBasicBlock
&MBB
) {
79 return MBFI
.getBlockFreqRelativeToEntryBlock(&MBB
);
81 [&](const MachineInstr
&MI
) {
82 return MF
.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
87 RegAllocScore
llvm::calculateRegAllocScore(
88 const MachineFunction
&MF
,
89 llvm::function_ref
<double(const MachineBasicBlock
&)> GetBBFreq
,
90 llvm::function_ref
<bool(const MachineInstr
&)>
91 IsTriviallyRematerializable
) {
94 for (const MachineBasicBlock
&MBB
: MF
) {
95 double BlockFreqRelativeToEntrypoint
= GetBBFreq(MBB
);
96 RegAllocScore MBBScore
;
98 for (const MachineInstr
&MI
: MBB
) {
99 if (MI
.isDebugInstr() || MI
.isKill() || MI
.isInlineAsm()) {
103 MBBScore
.onCopy(BlockFreqRelativeToEntrypoint
);
104 } else if (IsTriviallyRematerializable(MI
)) {
105 if (MI
.getDesc().isAsCheapAsAMove()) {
106 MBBScore
.onCheapRemat(BlockFreqRelativeToEntrypoint
);
108 MBBScore
.onExpensiveRemat(BlockFreqRelativeToEntrypoint
);
110 } else if (MI
.mayLoad() && MI
.mayStore()) {
111 MBBScore
.onLoadStore(BlockFreqRelativeToEntrypoint
);
112 } else if (MI
.mayLoad()) {
113 MBBScore
.onLoad(BlockFreqRelativeToEntrypoint
);
114 } else if (MI
.mayStore()) {
115 MBBScore
.onStore(BlockFreqRelativeToEntrypoint
);