1 //===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===//
2 //
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
6 //
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 //===----------------------------------------------------------------------===//
14
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"
26
27 using namespace llvm;
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),
32 cl::Hidden);
33 cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
34 cl::init(1.0), cl::Hidden);
35 #define DEBUG_TYPE "regalloc-score"
36
operator +=(const RegAllocScore & Other)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();
44 return *this;
45 }
46
operator ==(const RegAllocScore & Other) const47 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();
54 }
55
operator !=(const RegAllocScore & Other) const56 bool RegAllocScore::operator!=(const RegAllocScore &Other) const {
57 return !(*this == Other);
58 }
59
getScore() const60 double RegAllocScore::getScore() const {
61 double Ret = 0.0;
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();
68
69 return Ret;
70 }
71
72 RegAllocScore
calculateRegAllocScore(const MachineFunction & MF,const MachineBlockFrequencyInfo & MBFI)73 llvm::calculateRegAllocScore(const MachineFunction &MF,
74 const MachineBlockFrequencyInfo &MBFI) {
75 return calculateRegAllocScore(
76 MF,
77 [&](const MachineBasicBlock &MBB) {
78 return MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
79 },
80 [&](const MachineInstr &MI) {
81 return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
82 MI);
83 });
84 }
85
calculateRegAllocScore(const MachineFunction & MF,llvm::function_ref<double (const MachineBasicBlock &)> GetBBFreq,llvm::function_ref<bool (const MachineInstr &)> 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) {
91 RegAllocScore Total;
92
93 for (const MachineBasicBlock &MBB : MF) {
94 double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB);
95 RegAllocScore MBBScore;
96
97 for (const MachineInstr &MI : MBB) {
98 if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) {
99 continue;
100 }
101 if (MI.isCopy()) {
102 MBBScore.onCopy(BlockFreqRelativeToEntrypoint);
103 } else if (IsTriviallyRematerializable(MI)) {
104 if (MI.getDesc().isAsCheapAsAMove()) {
105 MBBScore.onCheapRemat(BlockFreqRelativeToEntrypoint);
106 } else {
107 MBBScore.onExpensiveRemat(BlockFreqRelativeToEntrypoint);
108 }
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);
115 }
116 }
117 Total += MBBScore;
118 }
119 return Total;
120 }
121