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/CodeGen/MachineBasicBlock.h" |
17 | #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" |
18 | #include "llvm/CodeGen/MachineFunction.h" |
19 | #include "llvm/CodeGen/MachineInstr.h" |
20 | #include "llvm/CodeGen/TargetInstrInfo.h" |
21 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
22 | #include "llvm/MC/MCInstrDesc.h" |
23 | #include "llvm/Support/CommandLine.h" |
24 | |
25 | using namespace llvm; |
26 | LLVM_ABI cl::opt<double> CopyWeight("regalloc-copy-weight" , cl::init(Val: 0.2), |
27 | cl::Hidden); |
28 | LLVM_ABI cl::opt<double> LoadWeight("regalloc-load-weight" , cl::init(Val: 4.0), |
29 | cl::Hidden); |
30 | LLVM_ABI cl::opt<double> StoreWeight("regalloc-store-weight" , cl::init(Val: 1.0), |
31 | cl::Hidden); |
32 | LLVM_ABI cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight" , |
33 | cl::init(Val: 0.2), cl::Hidden); |
34 | LLVM_ABI cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight" , |
35 | cl::init(Val: 1.0), cl::Hidden); |
36 | #define DEBUG_TYPE "regalloc-score" |
37 | |
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(); |
45 | return *this; |
46 | } |
47 | |
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(); |
55 | } |
56 | |
57 | bool RegAllocScore::operator!=(const RegAllocScore &Other) const { |
58 | return !(*this == Other); |
59 | } |
60 | |
61 | double RegAllocScore::getScore() const { |
62 | double Ret = 0.0; |
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(); |
69 | |
70 | return Ret; |
71 | } |
72 | |
73 | RegAllocScore |
74 | llvm::calculateRegAllocScore(const MachineFunction &MF, |
75 | const MachineBlockFrequencyInfo &MBFI) { |
76 | return calculateRegAllocScore( |
77 | MF, |
78 | GetBBFreq: [&](const MachineBasicBlock &MBB) { |
79 | return MBFI.getBlockFreqRelativeToEntryBlock(MBB: &MBB); |
80 | }, |
81 | IsTriviallyRematerializable: [&](const MachineInstr &MI) { |
82 | return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable( |
83 | MI); |
84 | }); |
85 | } |
86 | |
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) { |
92 | RegAllocScore Total; |
93 | |
94 | for (const MachineBasicBlock &MBB : MF) { |
95 | double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB); |
96 | RegAllocScore MBBScore; |
97 | |
98 | for (const MachineInstr &MI : MBB) { |
99 | if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) { |
100 | continue; |
101 | } |
102 | if (MI.isCopy()) { |
103 | MBBScore.onCopy(Freq: BlockFreqRelativeToEntrypoint); |
104 | } else if (IsTriviallyRematerializable(MI)) { |
105 | if (MI.getDesc().isAsCheapAsAMove()) { |
106 | MBBScore.onCheapRemat(Freq: BlockFreqRelativeToEntrypoint); |
107 | } else { |
108 | MBBScore.onExpensiveRemat(Freq: BlockFreqRelativeToEntrypoint); |
109 | } |
110 | } else if (MI.mayLoad() && MI.mayStore()) { |
111 | MBBScore.onLoadStore(Freq: BlockFreqRelativeToEntrypoint); |
112 | } else if (MI.mayLoad()) { |
113 | MBBScore.onLoad(Freq: BlockFreqRelativeToEntrypoint); |
114 | } else if (MI.mayStore()) { |
115 | MBBScore.onStore(Freq: BlockFreqRelativeToEntrypoint); |
116 | } |
117 | } |
118 | Total += MBBScore; |
119 | } |
120 | return Total; |
121 | } |
122 | |