124 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- RegAllocScore.cpp - evaluate regalloc policy quality ---------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
/// Calculate a measure of the register allocation policy quality. This is used
 | 
						|
/// to construct a reward for the training of the ML-driven allocation policy.
 | 
						|
/// Currently, the score is the sum of the machine basic block frequency-weighed
 | 
						|
/// number of loads, stores, copies, and remat instructions, each factored with
 | 
						|
/// a relative weight.
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "RegAllocScore.h"
 | 
						|
#include "llvm/ADT/DenseMapInfo.h"
 | 
						|
#include "llvm/ADT/STLForwardCompat.h"
 | 
						|
#include "llvm/ADT/SetVector.h"
 | 
						|
#include "llvm/ADT/ilist_iterator.h"
 | 
						|
#include "llvm/CodeGen/MachineBasicBlock.h"
 | 
						|
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
 | 
						|
#include "llvm/CodeGen/MachineFunction.h"
 | 
						|
#include "llvm/CodeGen/MachineInstr.h"
 | 
						|
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
 | 
						|
#include "llvm/CodeGen/TargetInstrInfo.h"
 | 
						|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
 | 
						|
#include "llvm/MC/MCInstrDesc.h"
 | 
						|
#include "llvm/Support/CommandLine.h"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
cl::opt<double> CopyWeight("regalloc-copy-weight", cl::init(0.2), cl::Hidden);
 | 
						|
cl::opt<double> LoadWeight("regalloc-load-weight", cl::init(4.0), cl::Hidden);
 | 
						|
cl::opt<double> StoreWeight("regalloc-store-weight", cl::init(1.0), cl::Hidden);
 | 
						|
cl::opt<double> CheapRematWeight("regalloc-cheap-remat-weight", cl::init(0.2),
 | 
						|
                                 cl::Hidden);
 | 
						|
cl::opt<double> ExpensiveRematWeight("regalloc-expensive-remat-weight",
 | 
						|
                                     cl::init(1.0), cl::Hidden);
 | 
						|
#define DEBUG_TYPE "regalloc-score"
 | 
						|
 | 
						|
RegAllocScore &RegAllocScore::operator+=(const RegAllocScore &Other) {
 | 
						|
  CopyCounts += Other.copyCounts();
 | 
						|
  LoadCounts += Other.loadCounts();
 | 
						|
  StoreCounts += Other.storeCounts();
 | 
						|
  LoadStoreCounts += Other.loadStoreCounts();
 | 
						|
  CheapRematCounts += Other.cheapRematCounts();
 | 
						|
  ExpensiveRematCounts += Other.expensiveRematCounts();
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
bool RegAllocScore::operator==(const RegAllocScore &Other) const {
 | 
						|
  return copyCounts() == Other.copyCounts() &&
 | 
						|
         loadCounts() == Other.loadCounts() &&
 | 
						|
         storeCounts() == Other.storeCounts() &&
 | 
						|
         loadStoreCounts() == Other.loadStoreCounts() &&
 | 
						|
         cheapRematCounts() == Other.cheapRematCounts() &&
 | 
						|
         expensiveRematCounts() == Other.expensiveRematCounts();
 | 
						|
}
 | 
						|
 | 
						|
bool RegAllocScore::operator!=(const RegAllocScore &Other) const {
 | 
						|
  return !(*this == Other);
 | 
						|
}
 | 
						|
 | 
						|
double RegAllocScore::getScore() const {
 | 
						|
  double Ret = 0.0;
 | 
						|
  Ret += CopyWeight * copyCounts();
 | 
						|
  Ret += LoadWeight * loadCounts();
 | 
						|
  Ret += StoreWeight * storeCounts();
 | 
						|
  Ret += (LoadWeight + StoreWeight) * loadStoreCounts();
 | 
						|
  Ret += CheapRematWeight * cheapRematCounts();
 | 
						|
  Ret += ExpensiveRematWeight * expensiveRematCounts();
 | 
						|
 | 
						|
  return Ret;
 | 
						|
}
 | 
						|
 | 
						|
RegAllocScore
 | 
						|
llvm::calculateRegAllocScore(const MachineFunction &MF,
 | 
						|
                             const MachineBlockFrequencyInfo &MBFI) {
 | 
						|
  return calculateRegAllocScore(
 | 
						|
      MF,
 | 
						|
      [&](const MachineBasicBlock &MBB) {
 | 
						|
        return MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
 | 
						|
      },
 | 
						|
      [&](const MachineInstr &MI) {
 | 
						|
        return MF.getSubtarget().getInstrInfo()->isTriviallyReMaterializable(
 | 
						|
            MI);
 | 
						|
      });
 | 
						|
}
 | 
						|
 | 
						|
RegAllocScore llvm::calculateRegAllocScore(
 | 
						|
    const MachineFunction &MF,
 | 
						|
    llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
 | 
						|
    llvm::function_ref<bool(const MachineInstr &)>
 | 
						|
        IsTriviallyRematerializable) {
 | 
						|
  RegAllocScore Total;
 | 
						|
 | 
						|
  for (const MachineBasicBlock &MBB : MF) {
 | 
						|
    double BlockFreqRelativeToEntrypoint = GetBBFreq(MBB);
 | 
						|
    RegAllocScore MBBScore;
 | 
						|
 | 
						|
    for (const MachineInstr &MI : MBB) {
 | 
						|
      if (MI.isDebugInstr() || MI.isKill() || MI.isInlineAsm()) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      if (MI.isCopy()) {
 | 
						|
        MBBScore.onCopy(BlockFreqRelativeToEntrypoint);
 | 
						|
      } else if (IsTriviallyRematerializable(MI)) {
 | 
						|
        if (MI.getDesc().isAsCheapAsAMove()) {
 | 
						|
          MBBScore.onCheapRemat(BlockFreqRelativeToEntrypoint);
 | 
						|
        } else {
 | 
						|
          MBBScore.onExpensiveRemat(BlockFreqRelativeToEntrypoint);
 | 
						|
        }
 | 
						|
      } else if (MI.mayLoad() && MI.mayStore()) {
 | 
						|
        MBBScore.onLoadStore(BlockFreqRelativeToEntrypoint);
 | 
						|
      } else if (MI.mayLoad()) {
 | 
						|
        MBBScore.onLoad(BlockFreqRelativeToEntrypoint);
 | 
						|
      } else if (MI.mayStore()) {
 | 
						|
        MBBScore.onStore(BlockFreqRelativeToEntrypoint);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    Total += MBBScore;
 | 
						|
  }
 | 
						|
  return Total;
 | 
						|
}
 |