1fa99cb64SMircea Trofin //===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===// 2fa99cb64SMircea Trofin // 3fa99cb64SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa99cb64SMircea Trofin // See https://llvm.org/LICENSE.txt for license information. 5fa99cb64SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa99cb64SMircea Trofin // 7fa99cb64SMircea Trofin //===----------------------------------------------------------------------===// 8fa99cb64SMircea Trofin /// Calculate a measure of the register allocation policy quality. This is used 9fa99cb64SMircea Trofin /// to construct a reward for the training of the ML-driven allocation policy. 10fa99cb64SMircea Trofin /// Currently, the score is the sum of the machine basic block frequency-weighed 11fa99cb64SMircea Trofin /// number of loads, stores, copies, and remat instructions, each factored with 12fa99cb64SMircea Trofin /// a relative weight. 13fa99cb64SMircea Trofin //===----------------------------------------------------------------------===// 14fa99cb64SMircea Trofin 15fa99cb64SMircea Trofin #include "RegAllocScore.h" 16ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineBasicBlock.h" 17ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 18ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineFunction.h" 19ed98c1b3Sserge-sans-paille #include "llvm/CodeGen/MachineInstr.h" 20fa99cb64SMircea Trofin #include "llvm/CodeGen/TargetInstrInfo.h" 21989f1c72Sserge-sans-paille #include "llvm/CodeGen/TargetSubtargetInfo.h" 22989f1c72Sserge-sans-paille #include "llvm/MC/MCInstrDesc.h" 23989f1c72Sserge-sans-paille #include "llvm/Support/CommandLine.h" 24fa99cb64SMircea Trofin 25fa99cb64SMircea Trofin using namespace llvm; 26fa99cb64SMircea Trofin cl::opt<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden); 27fa99cb64SMircea Trofin cl::opt<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden); 28fa99cb64SMircea Trofin cl::opt<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden); 29fa99cb64SMircea Trofin cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2), 30fa99cb64SMircea Trofin cl::Hidden); 31fa99cb64SMircea Trofin cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight", 32fa99cb64SMircea Trofin cl::init(1.0), cl::Hidden); 33fa99cb64SMircea Trofin #define DEBUG_TYPE "regalloc-score" 34fa99cb64SMircea Trofin 35fa99cb64SMircea Trofin RegAllocScore &RegAllocScore::operator+=(const RegAllocScore &Other) { 36fa99cb64SMircea Trofin CopyCounts += Other.copyCounts(); 37fa99cb64SMircea Trofin LoadCounts += Other.loadCounts(); 38fa99cb64SMircea Trofin StoreCounts += Other.storeCounts(); 39fa99cb64SMircea Trofin LoadStoreCounts += Other.loadStoreCounts(); 40fa99cb64SMircea Trofin CheapRematCounts += Other.cheapRematCounts(); 41fa99cb64SMircea Trofin ExpensiveRematCounts += Other.expensiveRematCounts(); 42fa99cb64SMircea Trofin return *this; 43fa99cb64SMircea Trofin } 44fa99cb64SMircea Trofin 45fa99cb64SMircea Trofin bool RegAllocScore::operator==(const RegAllocScore &Other) const { 46fa99cb64SMircea Trofin return copyCounts() == Other.copyCounts() && 47fa99cb64SMircea Trofin loadCounts() == Other.loadCounts() && 48fa99cb64SMircea Trofin storeCounts() == Other.storeCounts() && 49fa99cb64SMircea Trofin loadStoreCounts() == Other.loadStoreCounts() && 50fa99cb64SMircea Trofin cheapRematCounts() == Other.cheapRematCounts() && 51fa99cb64SMircea Trofin expensiveRematCounts() == Other.expensiveRematCounts(); 52fa99cb64SMircea Trofin } 53fa99cb64SMircea Trofin 54fa99cb64SMircea Trofin bool RegAllocScore::operator!=(const RegAllocScore &Other) const { 55fa99cb64SMircea Trofin return !(*this == Other); 56fa99cb64SMircea Trofin } 57fa99cb64SMircea Trofin 58fa99cb64SMircea Trofin double RegAllocScore::getScore() const { 59fa99cb64SMircea Trofin double Ret = 0.0; 60fa99cb64SMircea Trofin Ret += CopyWeight * copyCounts(); 61fa99cb64SMircea Trofin Ret += LoadWeight * loadCounts(); 62fa99cb64SMircea Trofin Ret += StoreWeight * storeCounts(); 63fa99cb64SMircea Trofin Ret += (LoadWeight + StoreWeight) * loadStoreCounts(); 64fa99cb64SMircea Trofin Ret += CheapRematWeight * cheapRematCounts(); 65fa99cb64SMircea Trofin Ret += ExpensiveRematWeight * expensiveRematCounts(); 66fa99cb64SMircea Trofin 67fa99cb64SMircea Trofin return Ret; 68fa99cb64SMircea Trofin } 69fa99cb64SMircea Trofin 70fa99cb64SMircea Trofin RegAllocScore 71fa99cb64SMircea Trofin llvm::calculateRegAllocScore(const MachineFunction &MF, 72*8d0383ebSMatt Arsenault const MachineBlockFrequencyInfo &MBFI) { 73fa99cb64SMircea Trofin return calculateRegAllocScore( 74fa99cb64SMircea Trofin MF, 75fa99cb64SMircea Trofin [&](const MachineBasicBlock &MBB) { 76fa99cb64SMircea Trofin return MBFI.getBlockFreqRelativeToEntryBlock(&MBB); 77fa99cb64SMircea Trofin }, 78fa99cb64SMircea Trofin [&](const MachineInstr &MI) { 79fa99cb64SMircea Trofin return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable( 80*8d0383ebSMatt Arsenault MI); 81fa99cb64SMircea Trofin }); 82fa99cb64SMircea Trofin } 83fa99cb64SMircea Trofin 84fa99cb64SMircea Trofin RegAllocScore llvm::calculateRegAllocScore( 85fa99cb64SMircea Trofin const MachineFunction &MF, 86fa99cb64SMircea Trofin llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq, 87fa99cb64SMircea Trofin llvm::function_ref<bool(const MachineInstr &)> 88fa99cb64SMircea Trofin IsTriviallyRematerializable) { 89fa99cb64SMircea Trofin RegAllocScore Total; 90fa99cb64SMircea Trofin 91fa99cb64SMircea Trofin for (const MachineBasicBlock &MBB : MF) { 92fa99cb64SMircea Trofin double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB); 93fa99cb64SMircea Trofin RegAllocScore MBBScore; 94fa99cb64SMircea Trofin 95fa99cb64SMircea Trofin for (const MachineInstr &MI : MBB) { 96fa99cb64SMircea Trofin if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) { 97fa99cb64SMircea Trofin continue; 98fa99cb64SMircea Trofin } 99fa99cb64SMircea Trofin if (MI.isCopy()) { 100fa99cb64SMircea Trofin MBBScore.onCopy(BlockFreqRelativeToEntrypoint); 101fa99cb64SMircea Trofin } else if (IsTriviallyRematerializable(MI)) { 102fa99cb64SMircea Trofin if (MI.getDesc().isAsCheapAsAMove()) { 103fa99cb64SMircea Trofin MBBScore.onCheapRemat(BlockFreqRelativeToEntrypoint); 104fa99cb64SMircea Trofin } else { 105fa99cb64SMircea Trofin MBBScore.onExpensiveRemat(BlockFreqRelativeToEntrypoint); 106fa99cb64SMircea Trofin } 107fa99cb64SMircea Trofin } else if (MI.mayLoad() && MI.mayStore()) { 108fa99cb64SMircea Trofin MBBScore.onLoadStore(BlockFreqRelativeToEntrypoint); 109fa99cb64SMircea Trofin } else if (MI.mayLoad()) { 110fa99cb64SMircea Trofin MBBScore.onLoad(BlockFreqRelativeToEntrypoint); 111fa99cb64SMircea Trofin } else if (MI.mayStore()) { 112fa99cb64SMircea Trofin MBBScore.onStore(BlockFreqRelativeToEntrypoint); 113fa99cb64SMircea Trofin } 114fa99cb64SMircea Trofin } 115fa99cb64SMircea Trofin Total += MBBScore; 116fa99cb64SMircea Trofin } 117fa99cb64SMircea Trofin return Total; 118fa99cb64SMircea Trofin } 119