1 //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements an allocation order for virtual registers.
11 // The preferred allocation order for a virtual register depends on allocation
12 // hints and target hooks. The AllocationOrder class encapsulates all of that.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
17 #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/CodeGen/Register.h"
26 class RegisterClassInfo
;
30 class 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 is
34 // constructed with HardHints = true, Order.size() otherwise. While
35 // technically a size_t, it will participate in comparisons with the
36 // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
37 // avoid warnings and under the assumption that the size of Order is
39 // IterationLimit defines an invalid iterator position.
40 const int IterationLimit
;
43 /// Forward iterator for an AllocationOrder.
44 class Iterator final
{
45 const AllocationOrder
&AO
;
49 Iterator(const AllocationOrder
&AO
, int Pos
) : AO(AO
), Pos(Pos
) {}
51 /// Return true if the curent position is that of a preferred register.
52 bool isHint() const { return Pos
< 0; }
54 /// Return the next physical register in the allocation order.
55 MCRegister
operator*() const {
57 return AO
.Hints
.end()[Pos
];
58 assert(Pos
< AO
.IterationLimit
);
62 /// Advance the iterator to the next position. If that's past the Hints
63 /// list, advance to the first value that's not also in the Hints list.
64 Iterator
&operator++() {
65 if (Pos
< AO
.IterationLimit
)
67 while (Pos
>= 0 && Pos
< AO
.IterationLimit
&& AO
.isHint(AO
.Order
[Pos
]))
72 bool operator==(const Iterator
&Other
) const {
73 assert(&AO
== &Other
.AO
);
74 return Pos
== Other
.Pos
;
77 bool operator!=(const Iterator
&Other
) const { return !(*this == Other
); }
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(unsigned VirtReg
, const VirtRegMap
&VRM
,
85 const RegisterClassInfo
&RegClassInfo
,
86 const LiveRegMatrix
*Matrix
);
88 /// Create an AllocationOrder given the Hits, Order, and HardHits values.
89 /// Use the create method above - the ctor is for unittests.
90 AllocationOrder(SmallVector
<MCPhysReg
, 16> &&Hints
, ArrayRef
<MCPhysReg
> Order
,
92 : Hints(std::move(Hints
)), Order(Order
),
93 IterationLimit(HardHints
? 0 : static_cast<int>(Order
.size())) {}
95 Iterator
begin() const {
96 return Iterator(*this, -(static_cast<int>(Hints
.size())));
99 Iterator
end() const { return Iterator(*this, IterationLimit
); }
101 Iterator
getOrderLimitEnd(unsigned OrderLimit
) const {
102 assert(OrderLimit
<= Order
.size());
106 std::min(static_cast<int>(OrderLimit
) - 1, IterationLimit
));
110 /// Get the allocation order without reordered hints.
111 ArrayRef
<MCPhysReg
> getOrder() const { return Order
; }
113 /// Return true if Reg is a preferred physical register.
114 bool isHint(Register Reg
) const {
115 assert(!Reg
.isPhysical() ||
117 static_cast<uint32_t>(std::numeric_limits
<MCPhysReg
>::max()));
118 return Reg
.isPhysical() && is_contained(Hints
, Reg
.id());
122 } // end namespace llvm