Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AllocationOrder.h
35233 views
//===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements an allocation order for virtual registers.9//10// The preferred allocation order for a virtual register depends on allocation11// hints and target hooks. The AllocationOrder class encapsulates all of that.12//13//===----------------------------------------------------------------------===//1415#ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H16#define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H1718#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/ADT/SmallVector.h"21#include "llvm/CodeGen/Register.h"2223namespace llvm {2425class RegisterClassInfo;26class VirtRegMap;27class LiveRegMatrix;2829class LLVM_LIBRARY_VISIBILITY AllocationOrder {30const SmallVector<MCPhysReg, 16> Hints;31ArrayRef<MCPhysReg> Order;32// How far into the Order we can iterate. This is 0 if the AllocationOrder is33// constructed with HardHints = true, Order.size() otherwise. While34// technically a size_t, it will participate in comparisons with the35// Iterator's Pos, which must be signed, so it's typed here as signed, too, to36// avoid warnings and under the assumption that the size of Order is37// relatively small.38// IterationLimit defines an invalid iterator position.39const int IterationLimit;4041public:42/// Forward iterator for an AllocationOrder.43class Iterator final {44const AllocationOrder &AO;45int Pos = 0;4647public:48Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}4950/// Return true if the curent position is that of a preferred register.51bool isHint() const { return Pos < 0; }5253/// Return the next physical register in the allocation order.54MCRegister operator*() const {55if (Pos < 0)56return AO.Hints.end()[Pos];57assert(Pos < AO.IterationLimit);58return AO.Order[Pos];59}6061/// Advance the iterator to the next position. If that's past the Hints62/// list, advance to the first value that's not also in the Hints list.63Iterator &operator++() {64if (Pos < AO.IterationLimit)65++Pos;66while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))67++Pos;68return *this;69}7071bool operator==(const Iterator &Other) const {72assert(&AO == &Other.AO);73return Pos == Other.Pos;74}7576bool operator!=(const Iterator &Other) const { return !(*this == Other); }77};7879/// Create a new AllocationOrder for VirtReg.80/// @param VirtReg Virtual register to allocate for.81/// @param VRM Virtual register map for function.82/// @param RegClassInfo Information about reserved and allocatable registers.83static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM,84const RegisterClassInfo &RegClassInfo,85const LiveRegMatrix *Matrix);8687/// Create an AllocationOrder given the Hits, Order, and HardHits values.88/// Use the create method above - the ctor is for unittests.89AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,90bool HardHints)91: Hints(std::move(Hints)), Order(Order),92IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}9394Iterator begin() const {95return Iterator(*this, -(static_cast<int>(Hints.size())));96}9798Iterator end() const { return Iterator(*this, IterationLimit); }99100Iterator getOrderLimitEnd(unsigned OrderLimit) const {101assert(OrderLimit <= Order.size());102if (OrderLimit == 0)103return end();104Iterator Ret(*this,105std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));106return ++Ret;107}108109/// Get the allocation order without reordered hints.110ArrayRef<MCPhysReg> getOrder() const { return Order; }111112/// Return true if Reg is a preferred physical register.113bool isHint(Register Reg) const {114assert(!Reg.isPhysical() ||115Reg.id() <116static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));117return Reg.isPhysical() && is_contained(Hints, Reg.id());118}119};120121} // end namespace llvm122123#endif124125126