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(Val: 0.2), cl::Hidden); |
29 | cl::opt<double> LoadWeight("regalloc-load-weight" , cl::init(Val: 4.0), cl::Hidden); |
30 | cl::opt<double> StoreWeight("regalloc-store-weight" , cl::init(Val: 1.0), cl::Hidden); |
31 | cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight" , cl::init(Val: 0.2), |
32 | cl::Hidden); |
33 | cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight" , |
34 | cl::init(Val: 1.0), cl::Hidden); |
35 | #define DEBUG_TYPE "regalloc-score" |
36 | |
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 | |
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(); |
54 | } |
55 | |
56 | bool RegAllocScore::operator!=(const RegAllocScore &Other) const { |
57 | return !(*this == Other); |
58 | } |
59 | |
60 | 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 |
73 | llvm::calculateRegAllocScore(const MachineFunction &MF, |
74 | const MachineBlockFrequencyInfo &MBFI) { |
75 | return calculateRegAllocScore( |
76 | MF, |
77 | GetBBFreq: [&](const MachineBasicBlock &MBB) { |
78 | return MBFI.getBlockFreqRelativeToEntryBlock(MBB: &MBB); |
79 | }, |
80 | IsTriviallyRematerializable: [&](const MachineInstr &MI) { |
81 | return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable( |
82 | MI); |
83 | }); |
84 | } |
85 | |
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(Freq: BlockFreqRelativeToEntrypoint); |
103 | } else if (IsTriviallyRematerializable(MI)) { |
104 | if (MI.getDesc().isAsCheapAsAMove()) { |
105 | MBBScore.onCheapRemat(Freq: BlockFreqRelativeToEntrypoint); |
106 | } else { |
107 | MBBScore.onExpensiveRemat(Freq: BlockFreqRelativeToEntrypoint); |
108 | } |
109 | } else if (MI.mayLoad() && MI.mayStore()) { |
110 | MBBScore.onLoadStore(Freq: BlockFreqRelativeToEntrypoint); |
111 | } else if (MI.mayLoad()) { |
112 | MBBScore.onLoad(Freq: BlockFreqRelativeToEntrypoint); |
113 | } else if (MI.mayStore()) { |
114 | MBBScore.onStore(Freq: BlockFreqRelativeToEntrypoint); |
115 | } |
116 | } |
117 | Total += MBBScore; |
118 | } |
119 | return Total; |
120 | } |
121 | |