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