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