xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RegAllocScore.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
177fc4c14SDimitry Andric //===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===//
277fc4c14SDimitry Andric //
377fc4c14SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
477fc4c14SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
577fc4c14SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
677fc4c14SDimitry Andric //
777fc4c14SDimitry Andric //===----------------------------------------------------------------------===//
877fc4c14SDimitry Andric /// Calculate a measure of the register allocation policy quality. This is used
977fc4c14SDimitry Andric /// to construct a reward for the training of the ML-driven allocation policy.
1077fc4c14SDimitry Andric /// Currently, the score is the sum of the machine basic block frequency-weighed
1177fc4c14SDimitry Andric /// number of loads, stores, copies, and remat instructions, each factored with
1277fc4c14SDimitry Andric /// a relative weight.
1377fc4c14SDimitry Andric //===----------------------------------------------------------------------===//
1477fc4c14SDimitry Andric 
1577fc4c14SDimitry Andric #include "RegAllocScore.h"
16145449b1SDimitry Andric #include "llvm/ADT/ilist_iterator.h"
17145449b1SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
18145449b1SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
19145449b1SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
20145449b1SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
21145449b1SDimitry Andric #include "llvm/CodeGen/MachineInstrBundleIterator.h"
2277fc4c14SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
23145449b1SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
24145449b1SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
25145449b1SDimitry Andric #include "llvm/Support/CommandLine.h"
2677fc4c14SDimitry Andric 
2777fc4c14SDimitry Andric using namespace llvm;
2877fc4c14SDimitry Andric cl::opt<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden);
2977fc4c14SDimitry Andric cl::opt<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden);
3077fc4c14SDimitry Andric cl::opt<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden);
3177fc4c14SDimitry Andric cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2),
3277fc4c14SDimitry Andric                                  cl::Hidden);
3377fc4c14SDimitry Andric cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
3477fc4c14SDimitry Andric                                      cl::init(1.0), cl::Hidden);
3577fc4c14SDimitry Andric #define DEBUG_TYPE "regalloc-score"
3677fc4c14SDimitry Andric 
operator +=(const RegAllocScore & Other)3777fc4c14SDimitry Andric RegAllocScore &RegAllocScore::operator+=(const RegAllocScore &Other) {
3877fc4c14SDimitry Andric   CopyCounts += Other.copyCounts();
3977fc4c14SDimitry Andric   LoadCounts += Other.loadCounts();
4077fc4c14SDimitry Andric   StoreCounts += Other.storeCounts();
4177fc4c14SDimitry Andric   LoadStoreCounts += Other.loadStoreCounts();
4277fc4c14SDimitry Andric   CheapRematCounts += Other.cheapRematCounts();
4377fc4c14SDimitry Andric   ExpensiveRematCounts += Other.expensiveRematCounts();
4477fc4c14SDimitry Andric   return *this;
4577fc4c14SDimitry Andric }
4677fc4c14SDimitry Andric 
operator ==(const RegAllocScore & Other) const4777fc4c14SDimitry Andric bool RegAllocScore::operator==(const RegAllocScore &Other) const {
4877fc4c14SDimitry Andric   return copyCounts() == Other.copyCounts() &&
4977fc4c14SDimitry Andric          loadCounts() == Other.loadCounts() &&
5077fc4c14SDimitry Andric          storeCounts() == Other.storeCounts() &&
5177fc4c14SDimitry Andric          loadStoreCounts() == Other.loadStoreCounts() &&
5277fc4c14SDimitry Andric          cheapRematCounts() == Other.cheapRematCounts() &&
5377fc4c14SDimitry Andric          expensiveRematCounts() == Other.expensiveRematCounts();
5477fc4c14SDimitry Andric }
5577fc4c14SDimitry Andric 
operator !=(const RegAllocScore & Other) const5677fc4c14SDimitry Andric bool RegAllocScore::operator!=(const RegAllocScore &Other) const {
5777fc4c14SDimitry Andric   return !(*this == Other);
5877fc4c14SDimitry Andric }
5977fc4c14SDimitry Andric 
getScore() const6077fc4c14SDimitry Andric double RegAllocScore::getScore() const {
6177fc4c14SDimitry Andric   double Ret = 0.0;
6277fc4c14SDimitry Andric   Ret += CopyWeight * copyCounts();
6377fc4c14SDimitry Andric   Ret += LoadWeight * loadCounts();
6477fc4c14SDimitry Andric   Ret += StoreWeight * storeCounts();
6577fc4c14SDimitry Andric   Ret += (LoadWeight + StoreWeight) * loadStoreCounts();
6677fc4c14SDimitry Andric   Ret += CheapRematWeight * cheapRematCounts();
6777fc4c14SDimitry Andric   Ret += ExpensiveRematWeight * expensiveRematCounts();
6877fc4c14SDimitry Andric 
6977fc4c14SDimitry Andric   return Ret;
7077fc4c14SDimitry Andric }
7177fc4c14SDimitry Andric 
7277fc4c14SDimitry Andric RegAllocScore
calculateRegAllocScore(const MachineFunction & MF,const MachineBlockFrequencyInfo & MBFI)7377fc4c14SDimitry Andric llvm::calculateRegAllocScore(const MachineFunction &MF,
744b4fe385SDimitry Andric                              const MachineBlockFrequencyInfo &MBFI) {
7577fc4c14SDimitry Andric   return calculateRegAllocScore(
7677fc4c14SDimitry Andric       MF,
7777fc4c14SDimitry Andric       [&](const MachineBasicBlock &MBB) {
7877fc4c14SDimitry Andric         return MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
7977fc4c14SDimitry Andric       },
8077fc4c14SDimitry Andric       [&](const MachineInstr &MI) {
8177fc4c14SDimitry Andric         return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
824b4fe385SDimitry Andric             MI);
8377fc4c14SDimitry Andric       });
8477fc4c14SDimitry Andric }
8577fc4c14SDimitry Andric 
calculateRegAllocScore(const MachineFunction & MF,llvm::function_ref<double (const MachineBasicBlock &)> GetBBFreq,llvm::function_ref<bool (const MachineInstr &)> IsTriviallyRematerializable)8677fc4c14SDimitry Andric RegAllocScore llvm::calculateRegAllocScore(
8777fc4c14SDimitry Andric     const MachineFunction &MF,
8877fc4c14SDimitry Andric     llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
8977fc4c14SDimitry Andric     llvm::function_ref<bool(const MachineInstr &)>
9077fc4c14SDimitry Andric         IsTriviallyRematerializable) {
9177fc4c14SDimitry Andric   RegAllocScore Total;
9277fc4c14SDimitry Andric 
9377fc4c14SDimitry Andric   for (const MachineBasicBlock &MBB : MF) {
9477fc4c14SDimitry Andric     double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB);
9577fc4c14SDimitry Andric     RegAllocScore MBBScore;
9677fc4c14SDimitry Andric 
9777fc4c14SDimitry Andric     for (const MachineInstr &MI : MBB) {
9877fc4c14SDimitry Andric       if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) {
9977fc4c14SDimitry Andric         continue;
10077fc4c14SDimitry Andric       }
10177fc4c14SDimitry Andric       if (MI.isCopy()) {
10277fc4c14SDimitry Andric         MBBScore.onCopy(BlockFreqRelativeToEntrypoint);
10377fc4c14SDimitry Andric       } else if (IsTriviallyRematerializable(MI)) {
10477fc4c14SDimitry Andric         if (MI.getDesc().isAsCheapAsAMove()) {
10577fc4c14SDimitry Andric           MBBScore.onCheapRemat(BlockFreqRelativeToEntrypoint);
10677fc4c14SDimitry Andric         } else {
10777fc4c14SDimitry Andric           MBBScore.onExpensiveRemat(BlockFreqRelativeToEntrypoint);
10877fc4c14SDimitry Andric         }
10977fc4c14SDimitry Andric       } else if (MI.mayLoad() && MI.mayStore()) {
11077fc4c14SDimitry Andric         MBBScore.onLoadStore(BlockFreqRelativeToEntrypoint);
11177fc4c14SDimitry Andric       } else if (MI.mayLoad()) {
11277fc4c14SDimitry Andric         MBBScore.onLoad(BlockFreqRelativeToEntrypoint);
11377fc4c14SDimitry Andric       } else if (MI.mayStore()) {
11477fc4c14SDimitry Andric         MBBScore.onStore(BlockFreqRelativeToEntrypoint);
11577fc4c14SDimitry Andric       }
11677fc4c14SDimitry Andric     }
11777fc4c14SDimitry Andric     Total += MBBScore;
11877fc4c14SDimitry Andric   }
11977fc4c14SDimitry Andric   return Total;
12077fc4c14SDimitry Andric }
121