brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 3dd02c3 Raw
125 lines · c
1//===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements an allocation order for virtual registers.10//11// The preferred allocation order for a virtual register depends on allocation12// hints and target hooks. The AllocationOrder class encapsulates all of that.13//14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H17#define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H18 19#include "llvm/ADT/ArrayRef.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/SmallVector.h"22#include "llvm/CodeGen/Register.h"23 24namespace llvm {25 26class RegisterClassInfo;27class VirtRegMap;28class LiveRegMatrix;29 30class LLVM_LIBRARY_VISIBILITY AllocationOrder {31  const SmallVector<MCPhysReg, 16> Hints;32  ArrayRef<MCPhysReg> Order;33  // How far into the Order we can iterate. This is 0 if the AllocationOrder is34  // constructed with HardHints = true, Order.size() otherwise. While35  // technically a size_t, it will participate in comparisons with the36  // Iterator's Pos, which must be signed, so it's typed here as signed, too, to37  // avoid warnings and under the assumption that the size of Order is38  // relatively small.39  // IterationLimit defines an invalid iterator position.40  const int IterationLimit;41 42public:43  /// Forward iterator for an AllocationOrder.44  class Iterator final {45    const AllocationOrder &AO;46    int Pos = 0;47 48  public:49    Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}50 51    /// Return true if the current position is that of a preferred register.52    bool isHint() const { return Pos < 0; }53 54    /// Return the next physical register in the allocation order.55    MCRegister operator*() const {56      if (Pos < 0)57        return AO.Hints.end()[Pos];58      assert(Pos < AO.IterationLimit);59      return AO.Order[Pos];60    }61 62    /// Advance the iterator to the next position. If that's past the Hints63    /// list, advance to the first value that's not also in the Hints list.64    Iterator &operator++() {65      if (Pos < AO.IterationLimit)66        ++Pos;67      while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))68        ++Pos;69      return *this;70    }71 72    bool operator==(const Iterator &Other) const {73      assert(&AO == &Other.AO);74      return Pos == Other.Pos;75    }76 77    bool operator!=(const Iterator &Other) const { return !(*this == Other); }78  };79 80  /// Create a new AllocationOrder for VirtReg.81  /// @param VirtReg      Virtual register to allocate for.82  /// @param VRM          Virtual register map for function.83  /// @param RegClassInfo Information about reserved and allocatable registers.84  static AllocationOrder create(Register VirtReg, const VirtRegMap &VRM,85                                const RegisterClassInfo &RegClassInfo,86                                const LiveRegMatrix *Matrix);87 88  /// Create an AllocationOrder given the Hints, Order, and HardHints values.89  /// Use the create method above - the ctor is for unittests.90  AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,91                  bool HardHints)92      : Hints(std::move(Hints)), Order(Order),93        IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}94 95  Iterator begin() const {96    return Iterator(*this, -(static_cast<int>(Hints.size())));97  }98 99  Iterator end() const { return Iterator(*this, IterationLimit); }100 101  Iterator getOrderLimitEnd(unsigned OrderLimit) const {102    assert(OrderLimit <= Order.size());103    if (OrderLimit == 0)104      return end();105    Iterator Ret(*this,106                 std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));107    return ++Ret;108  }109 110  /// Get the allocation order without reordered hints.111  ArrayRef<MCPhysReg> getOrder() const { return Order; }112 113  /// Return true if Reg is a preferred physical register.114  bool isHint(Register Reg) const {115    assert(!Reg.isPhysical() ||116           Reg.id() <117               static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));118    return Reg.isPhysical() && is_contained(Hints, Reg.id());119  }120};121 122} // end namespace llvm123 124#endif125