1218885Sdim//===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===// 2218885Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6218885Sdim// 7218885Sdim//===----------------------------------------------------------------------===// 8218885Sdim// 9218885Sdim// This file implements an allocation order for virtual registers. 10218885Sdim// 11218885Sdim// The preferred allocation order for a virtual register depends on allocation 12218885Sdim// hints and target hooks. The AllocationOrder class encapsulates all of that. 13218885Sdim// 14218885Sdim//===----------------------------------------------------------------------===// 15218885Sdim 16280031Sdim#ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H 17280031Sdim#define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H 18218885Sdim 19249423Sdim#include "llvm/ADT/ArrayRef.h" 20314564Sdim#include "llvm/ADT/STLExtras.h" 21249423Sdim#include "llvm/MC/MCRegisterInfo.h" 22249423Sdim 23218885Sdimnamespace llvm { 24218885Sdim 25223017Sdimclass RegisterClassInfo; 26218885Sdimclass VirtRegMap; 27296417Sdimclass LiveRegMatrix; 28218885Sdim 29288943Sdimclass LLVM_LIBRARY_VISIBILITY AllocationOrder { 30249423Sdim SmallVector<MCPhysReg, 16> Hints; 31249423Sdim ArrayRef<MCPhysReg> Order; 32249423Sdim int Pos; 33249423Sdim 34327952Sdim // If HardHints is true, *only* Hints will be returned. 35327952Sdim bool HardHints; 36327952Sdim 37218885Sdimpublic: 38327952Sdim 39249423Sdim /// Create a new AllocationOrder for VirtReg. 40218885Sdim /// @param VirtReg Virtual register to allocate for. 41218885Sdim /// @param VRM Virtual register map for function. 42234353Sdim /// @param RegClassInfo Information about reserved and allocatable registers. 43218885Sdim AllocationOrder(unsigned VirtReg, 44218885Sdim const VirtRegMap &VRM, 45296417Sdim const RegisterClassInfo &RegClassInfo, 46296417Sdim const LiveRegMatrix *Matrix); 47218885Sdim 48249423Sdim /// Get the allocation order without reordered hints. 49249423Sdim ArrayRef<MCPhysReg> getOrder() const { return Order; } 50223017Sdim 51249423Sdim /// Return the next physical register in the allocation order, or 0. 52249423Sdim /// It is safe to call next() again after it returned 0, it will keep 53249423Sdim /// returning 0 until rewind() is called. 54276479Sdim unsigned next(unsigned Limit = 0) { 55249423Sdim if (Pos < 0) 56249423Sdim return Hints.end()[Pos++]; 57327952Sdim if (HardHints) 58327952Sdim return 0; 59276479Sdim if (!Limit) 60276479Sdim Limit = Order.size(); 61276479Sdim while (Pos < int(Limit)) { 62249423Sdim unsigned Reg = Order[Pos++]; 63249423Sdim if (!isHint(Reg)) 64223017Sdim return Reg; 65223017Sdim } 66223017Sdim return 0; 67223017Sdim } 68218885Sdim 69249423Sdim /// As next(), but allow duplicates to be returned, and stop before the 70249423Sdim /// Limit'th register in the RegisterClassInfo allocation order. 71249423Sdim /// 72249423Sdim /// This can produce more than Limit registers if there are hints. 73249423Sdim unsigned nextWithDups(unsigned Limit) { 74249423Sdim if (Pos < 0) 75249423Sdim return Hints.end()[Pos++]; 76327952Sdim if (HardHints) 77327952Sdim return 0; 78249423Sdim if (Pos < int(Limit)) 79249423Sdim return Order[Pos++]; 80249423Sdim return 0; 81249423Sdim } 82218885Sdim 83249423Sdim /// Start over from the beginning. 84249423Sdim void rewind() { Pos = -int(Hints.size()); } 85249423Sdim 86249423Sdim /// Return true if the last register returned from next() was a preferred register. 87249423Sdim bool isHint() const { return Pos <= 0; } 88249423Sdim 89249423Sdim /// Return true if PhysReg is a preferred register. 90314564Sdim bool isHint(unsigned PhysReg) const { return is_contained(Hints, PhysReg); } 91218885Sdim}; 92218885Sdim 93218885Sdim} // end namespace llvm 94218885Sdim 95218885Sdim#endif 96