123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements an allocation order for virtual registers.
- //
- // The preferred allocation order for a virtual register depends on allocation
- // hints and target hooks. The AllocationOrder class encapsulates all of that.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
- #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/CodeGen/Register.h"
- namespace llvm {
- class RegisterClassInfo;
- class VirtRegMap;
- class LiveRegMatrix;
- class LLVM_LIBRARY_VISIBILITY AllocationOrder {
- const SmallVector<MCPhysReg, 16> Hints;
- ArrayRef<MCPhysReg> Order;
- // How far into the Order we can iterate. This is 0 if the AllocationOrder is
- // constructed with HardHints = true, Order.size() otherwise. While
- // technically a size_t, it will participate in comparisons with the
- // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
- // avoid warnings and under the assumption that the size of Order is
- // relatively small.
- // IterationLimit defines an invalid iterator position.
- const int IterationLimit;
- public:
- /// Forward iterator for an AllocationOrder.
- class Iterator final {
- const AllocationOrder &AO;
- int Pos = 0;
- public:
- Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}
- /// Return true if the curent position is that of a preferred register.
- bool isHint() const { return Pos < 0; }
- /// Return the next physical register in the allocation order.
- MCRegister operator*() const {
- if (Pos < 0)
- return AO.Hints.end()[Pos];
- assert(Pos < AO.IterationLimit);
- return AO.Order[Pos];
- }
- /// Advance the iterator to the next position. If that's past the Hints
- /// list, advance to the first value that's not also in the Hints list.
- Iterator &operator++() {
- if (Pos < AO.IterationLimit)
- ++Pos;
- while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))
- ++Pos;
- return *this;
- }
- bool operator==(const Iterator &Other) const {
- assert(&AO == &Other.AO);
- return Pos == Other.Pos;
- }
- bool operator!=(const Iterator &Other) const { return !(*this == Other); }
- };
- /// Create a new AllocationOrder for VirtReg.
- /// @param VirtReg Virtual register to allocate for.
- /// @param VRM Virtual register map for function.
- /// @param RegClassInfo Information about reserved and allocatable registers.
- static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM,
- const RegisterClassInfo &RegClassInfo,
- const LiveRegMatrix *Matrix);
- /// Create an AllocationOrder given the Hits, Order, and HardHits values.
- /// Use the create method above - the ctor is for unittests.
- AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,
- bool HardHints)
- : Hints(std::move(Hints)), Order(Order),
- IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}
- Iterator begin() const {
- return Iterator(*this, -(static_cast<int>(Hints.size())));
- }
- Iterator end() const { return Iterator(*this, IterationLimit); }
- Iterator getOrderLimitEnd(unsigned OrderLimit) const {
- assert(OrderLimit <= Order.size());
- if (OrderLimit == 0)
- return end();
- Iterator Ret(*this,
- std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));
- return ++Ret;
- }
- /// Get the allocation order without reordered hints.
- ArrayRef<MCPhysReg> getOrder() const { return Order; }
- /// Return true if Reg is a preferred physical register.
- bool isHint(Register Reg) const {
- assert(!Reg.isPhysical() ||
- Reg.id() <
- static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));
- return Reg.isPhysical() && is_contained(Hints, Reg.id());
- }
- };
- } // end namespace llvm
- #endif
|