10eae32dcSDimitry Andric //==- RegAllocScore.h - evaluate regalloc policy quality ----------*-C++-*-==// 20eae32dcSDimitry Andric // 30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60eae32dcSDimitry Andric // 70eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 80eae32dcSDimitry Andric /// Calculate a measure of the register allocation policy quality. This is used 90eae32dcSDimitry Andric /// to construct a reward for the training of the ML-driven allocation policy. 100eae32dcSDimitry Andric /// Currently, the score is the sum of the machine basic block frequency-weighed 110eae32dcSDimitry Andric /// number of loads, stores, copies, and remat instructions, each factored with 120eae32dcSDimitry Andric /// a relative weight. 130eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 140eae32dcSDimitry Andric 150eae32dcSDimitry Andric #ifndef LLVM_CODEGEN_REGALLOCSCORE_H_ 160eae32dcSDimitry Andric #define LLVM_CODEGEN_REGALLOCSCORE_H_ 170eae32dcSDimitry Andric 1881ad6265SDimitry Andric #include "llvm/ADT/STLFunctionalExtras.h" 190eae32dcSDimitry Andric 200eae32dcSDimitry Andric namespace llvm { 210eae32dcSDimitry Andric 2281ad6265SDimitry Andric class MachineBasicBlock; 2381ad6265SDimitry Andric class MachineBlockFrequencyInfo; 2481ad6265SDimitry Andric class MachineFunction; 2581ad6265SDimitry Andric class MachineInstr; 2681ad6265SDimitry Andric 270eae32dcSDimitry Andric /// Regalloc score. 280eae32dcSDimitry Andric class RegAllocScore final { 290eae32dcSDimitry Andric double CopyCounts = 0.0; 300eae32dcSDimitry Andric double LoadCounts = 0.0; 310eae32dcSDimitry Andric double StoreCounts = 0.0; 320eae32dcSDimitry Andric double CheapRematCounts = 0.0; 330eae32dcSDimitry Andric double LoadStoreCounts = 0.0; 340eae32dcSDimitry Andric double ExpensiveRematCounts = 0.0; 350eae32dcSDimitry Andric 360eae32dcSDimitry Andric public: 370eae32dcSDimitry Andric RegAllocScore() = default; 380eae32dcSDimitry Andric RegAllocScore(const RegAllocScore &) = default; 390eae32dcSDimitry Andric copyCounts()400eae32dcSDimitry Andric double copyCounts() const { return CopyCounts; } loadCounts()410eae32dcSDimitry Andric double loadCounts() const { return LoadCounts; } storeCounts()420eae32dcSDimitry Andric double storeCounts() const { return StoreCounts; } loadStoreCounts()430eae32dcSDimitry Andric double loadStoreCounts() const { return LoadStoreCounts; } expensiveRematCounts()440eae32dcSDimitry Andric double expensiveRematCounts() const { return ExpensiveRematCounts; } cheapRematCounts()450eae32dcSDimitry Andric double cheapRematCounts() const { return CheapRematCounts; } 460eae32dcSDimitry Andric onCopy(double Freq)470eae32dcSDimitry Andric void onCopy(double Freq) { CopyCounts += Freq; } onLoad(double Freq)480eae32dcSDimitry Andric void onLoad(double Freq) { LoadCounts += Freq; } onStore(double Freq)490eae32dcSDimitry Andric void onStore(double Freq) { StoreCounts += Freq; } onLoadStore(double Freq)500eae32dcSDimitry Andric void onLoadStore(double Freq) { LoadStoreCounts += Freq; } onExpensiveRemat(double Freq)510eae32dcSDimitry Andric void onExpensiveRemat(double Freq) { ExpensiveRematCounts += Freq; } onCheapRemat(double Freq)520eae32dcSDimitry Andric void onCheapRemat(double Freq) { CheapRematCounts += Freq; } 530eae32dcSDimitry Andric 540eae32dcSDimitry Andric RegAllocScore &operator+=(const RegAllocScore &Other); 550eae32dcSDimitry Andric bool operator==(const RegAllocScore &Other) const; 560eae32dcSDimitry Andric bool operator!=(const RegAllocScore &Other) const; 570eae32dcSDimitry Andric double getScore() const; 580eae32dcSDimitry Andric }; 590eae32dcSDimitry Andric 600eae32dcSDimitry Andric /// Calculate a score. When comparing 2 scores for the same function but 610eae32dcSDimitry Andric /// different policies, the better policy would have a smaller score. 620eae32dcSDimitry Andric /// The implementation is the overload below (which is also easily unittestable) 630eae32dcSDimitry Andric RegAllocScore calculateRegAllocScore(const MachineFunction &MF, 64*fcaf7f86SDimitry Andric const MachineBlockFrequencyInfo &MBFI); 650eae32dcSDimitry Andric 660eae32dcSDimitry Andric /// Implementation of the above, which is also more easily unittestable. 670eae32dcSDimitry Andric RegAllocScore calculateRegAllocScore( 680eae32dcSDimitry Andric const MachineFunction &MF, 690eae32dcSDimitry Andric llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq, 700eae32dcSDimitry Andric llvm::function_ref<bool(const MachineInstr &)> IsTriviallyRematerializable); 710eae32dcSDimitry Andric } // end namespace llvm 720eae32dcSDimitry Andric 730eae32dcSDimitry Andric #endif // LLVM_CODEGEN_REGALLOCSCORE_H_ 74