xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric //===- MLRegAllocEvictAdvisor.cpp - ML eviction advisor -------------------===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric //
95f757f3fSDimitry Andric // Function declarations of utilities related to feature extraction for unit
105f757f3fSDimitry Andric // testing.
115f757f3fSDimitry Andric //
125f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
135f757f3fSDimitry Andric 
145f757f3fSDimitry Andric #ifndef LLVM_CODEGEN_MLREGALLOCEVICTIONADVISOR_H
155f757f3fSDimitry Andric #define LLVM_CODEGEN_MLREGALLOCEVICTIONADVISOR_H
165f757f3fSDimitry Andric 
175f757f3fSDimitry Andric #include "llvm/Analysis/MLModelRunner.h"
185f757f3fSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
195f757f3fSDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
20*0fca6ea1SDimitry Andric #include <map>
215f757f3fSDimitry Andric 
225f757f3fSDimitry Andric using namespace llvm;
235f757f3fSDimitry Andric 
245f757f3fSDimitry Andric // LRStartEndInfo contains the start and end of a specific live range as
255f757f3fSDimitry Andric // slot indices as well as storing the index of the physical register it
265f757f3fSDimitry Andric // is assigned to (or 1 above the phys reg count if its the candidate).
275f757f3fSDimitry Andric // Used when extracting per-instruction features in the context of a
285f757f3fSDimitry Andric // specific eviction problem.
295f757f3fSDimitry Andric struct LRStartEndInfo {
305f757f3fSDimitry Andric   SlotIndex Begin;
315f757f3fSDimitry Andric   SlotIndex End;
325f757f3fSDimitry Andric   size_t Pos = 0;
335f757f3fSDimitry Andric };
345f757f3fSDimitry Andric 
355f757f3fSDimitry Andric void extractInstructionFeatures(
365f757f3fSDimitry Andric     llvm::SmallVectorImpl<LRStartEndInfo> &LRPosInfo,
375f757f3fSDimitry Andric     MLModelRunner *RegallocRunner, function_ref<int(SlotIndex)> GetOpcode,
385f757f3fSDimitry Andric     function_ref<float(SlotIndex)> GetMBBFreq,
395f757f3fSDimitry Andric     function_ref<MachineBasicBlock *(SlotIndex)> GetMBBReference,
405f757f3fSDimitry Andric     const int InstructionsIndex, const int InstructionsMappingIndex,
415f757f3fSDimitry Andric     const int MBBFreqIndex, const int MBBMappingIndex,
425f757f3fSDimitry Andric     const SlotIndex LastIndex);
435f757f3fSDimitry Andric 
445f757f3fSDimitry Andric void extractMBBFrequency(const SlotIndex CurrentIndex,
455f757f3fSDimitry Andric                          const size_t CurrentInstructionIndex,
465f757f3fSDimitry Andric                          std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
475f757f3fSDimitry Andric                          function_ref<float(SlotIndex)> GetMBBFreq,
485f757f3fSDimitry Andric                          MachineBasicBlock *CurrentMBBReference,
495f757f3fSDimitry Andric                          MLModelRunner *RegallocRunner, const int MBBFreqIndex,
505f757f3fSDimitry Andric                          const int MBBMappingIndex);
515f757f3fSDimitry Andric 
525f757f3fSDimitry Andric // This is the maximum number of interfererring ranges. That's the number of
535f757f3fSDimitry Andric // distinct AllocationOrder values, which comes from MCRegisterClass::RegsSize.
545f757f3fSDimitry Andric // For X86, that's 32.
555f757f3fSDimitry Andric // TODO: find a way to get this, statically, in a programmatic way.
565f757f3fSDimitry Andric static const int64_t MaxInterferences = 32;
575f757f3fSDimitry Andric 
585f757f3fSDimitry Andric // Logically, we can think of the feature set given to the evaluator as a 2D
595f757f3fSDimitry Andric // matrix. The rows are the features (see next). The columns correspond to the
605f757f3fSDimitry Andric // interferences. We treat the candidate virt reg as an 'interference', too, as
615f757f3fSDimitry Andric // its feature set is the same as that of the interferring ranges. So we'll have
625f757f3fSDimitry Andric // MaxInterferences + 1 columns and by convention, we will use the last column
635f757f3fSDimitry Andric // for the virt reg seeking allocation.
645f757f3fSDimitry Andric static const int64_t CandidateVirtRegPos = MaxInterferences;
655f757f3fSDimitry Andric static const int64_t NumberOfInterferences = CandidateVirtRegPos + 1;
665f757f3fSDimitry Andric 
675f757f3fSDimitry Andric // The number of instructions that a specific live range might have is variable,
685f757f3fSDimitry Andric // but we're passing in a single matrix of instructions and tensorflow saved
695f757f3fSDimitry Andric // models only support a fixed input size, so we have to cap the number of
705f757f3fSDimitry Andric // instructions that can be passed along. The specific value was derived from
715f757f3fSDimitry Andric // experimentation such that the majority of eviction problems would be
725f757f3fSDimitry Andric // completely covered.
735f757f3fSDimitry Andric static const int ModelMaxSupportedInstructionCount = 300;
745f757f3fSDimitry Andric 
755f757f3fSDimitry Andric // When extracting per-instruction features, the advisor will currently create
765f757f3fSDimitry Andric // a vector of size ModelMaxSupportedInstructionCount to hold the opcodes of the
775f757f3fSDimitry Andric // instructions relevant to the eviction problem, and a NumberOfInterferences *
785f757f3fSDimitry Andric // ModelMaxSupportedInstructionCount matrix that maps LRs to the instructions
795f757f3fSDimitry Andric // that they span.
805f757f3fSDimitry Andric static const std::vector<int64_t> InstructionsShape{
815f757f3fSDimitry Andric     1, ModelMaxSupportedInstructionCount};
825f757f3fSDimitry Andric static const std::vector<int64_t> InstructionsMappingShape{
835f757f3fSDimitry Andric     1, NumberOfInterferences, ModelMaxSupportedInstructionCount};
845f757f3fSDimitry Andric 
855f757f3fSDimitry Andric // When extracting mappings between MBBs and individual instructions, we create
865f757f3fSDimitry Andric // a vector of MBB frequencies, currently of size 100, which was a value
875f757f3fSDimitry Andric // determined through experimentation to encompass the vast majority of eviction
885f757f3fSDimitry Andric // problems. The actual mapping is the same shape as the instruction opcodes
895f757f3fSDimitry Andric // vector.
905f757f3fSDimitry Andric static const int64_t ModelMaxSupportedMBBCount = 100;
915f757f3fSDimitry Andric static const std::vector<int64_t> MBBFrequencyShape{1,
925f757f3fSDimitry Andric                                                     ModelMaxSupportedMBBCount};
935f757f3fSDimitry Andric 
945f757f3fSDimitry Andric #endif // LLVM_CODEGEN_MLREGALLOCEVICTIONADVISOR_H
95