• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMPILER_OPTIMIZER_OPTIMIZATIONS_REG_ALLOC_BASE_H
17 #define COMPILER_OPTIMIZER_OPTIMIZATIONS_REG_ALLOC_BASE_H
18 
19 #include "compiler/optimizer/ir/graph.h"
20 #include "optimizer/analysis/liveness_analyzer.h"
21 #include "utils/arena_containers.h"
22 #include "location_mask.h"
23 
24 namespace ark::compiler {
25 
26 void ConnectIntervals(SpillFillInst *spillFill, const LifeIntervals *src, const LifeIntervals *dst);
27 bool TryToSpillConstant(LifeIntervals *interval, Graph *graph);
28 
29 class PANDA_PUBLIC_API RegAllocBase : public Optimization {
30 public:
31     explicit RegAllocBase(Graph *graph);
32     RegAllocBase(Graph *graph, size_t regsCount);
33     RegAllocBase(Graph *graph, const RegMask &regMask, const VRegMask &vregMask, size_t slotsCount);
34     RegAllocBase(Graph *graph, LocationMask mask);
35 
36     NO_MOVE_SEMANTIC(RegAllocBase);
37     NO_COPY_SEMANTIC(RegAllocBase);
38 
39     ~RegAllocBase() override = default;
40 
41     bool RunImpl() override;
42     const char *GetPassName() const override;
43     bool AbortIfFailed() const override;
44 
45     template <typename T>
SetRegMask(const T & regMask)46     void SetRegMask(const T &regMask)
47     {
48         regsMask_.Init(regMask);
49     }
50 
GetRegMask()51     LocationMask &GetRegMask()
52     {
53         return regsMask_;
54     }
55 
GetRegMask()56     const LocationMask &GetRegMask() const
57     {
58         return regsMask_;
59     }
60 
61     template <typename T>
SetVRegMask(const T & vregMask)62     void SetVRegMask(const T &vregMask)
63     {
64         vregsMask_.Init(vregMask);
65     }
66 
GetVRegMask()67     LocationMask &GetVRegMask()
68     {
69         return vregsMask_;
70     }
71 
GetVRegMask()72     const LocationMask &GetVRegMask() const
73     {
74         return vregsMask_;
75     }
76 
SetSlotsCount(size_t slotsCount)77     void SetSlotsCount(size_t slotsCount)
78     {
79         stackMask_.Resize(slotsCount);
80         stackUseLastPositions_.resize(slotsCount);
81     }
82 
GetStackMask()83     LocationMask &GetStackMask()
84     {
85         return stackMask_;
86     }
87 
88     void ReserveTempRegisters();
89 
90     // resolve graph
91     virtual bool Resolve();
92 
93 protected:
GetNextStackSlot(LifeIntervals * interval)94     StackSlot GetNextStackSlot(LifeIntervals *interval)
95     {
96         return !GetStackMask().AllSet() ? GetNextStackSlotImpl(interval) : GetInvalidStackSlot();
97     }
98 
GetNextStackSlotImpl(LifeIntervals * interval)99     StackSlot GetNextStackSlotImpl(LifeIntervals *interval)
100     {
101         auto size = GetStackMask().GetSize();
102         for (size_t slot = 0; slot < size; slot++) {
103             if (GetStackMask().IsSet(slot)) {
104                 continue;
105             }
106 
107             ASSERT(slot < stackUseLastPositions_.size());
108             if (stackUseLastPositions_[slot] > interval->GetBegin()) {
109                 continue;
110             }
111 
112             GetStackMask().Set(slot);
113             stackUseLastPositions_[slot] = interval->GetEnd();
114             return slot;
115         }
116         return GetInvalidStackSlot();
117     }
118 
119     void PrepareIntervals();
120 
InitIntervals()121     virtual void InitIntervals() {}
122 
PrepareInterval(LifeIntervals * interval)123     virtual void PrepareInterval([[maybe_unused]] LifeIntervals *interval) {}
124 
125     // Prepare allocations and run passes such as LivenessAnalyzer
126     virtual bool Prepare();
127 
128     // Arrange intervals/ranges and RA
129     virtual bool Allocate() = 0;
130 
131     // Post resolve actions
132     virtual bool Finish();
133 
134 private:
135     void SetType(LifeIntervals *interval);
136     void SetPreassignedRegisters(LifeIntervals *interval);
137     size_t GetTotalSlotsCount();
138 
139 private:
140     LocationMask regsMask_;
141     LocationMask vregsMask_;
142     LocationMask stackMask_;
143     ArenaVector<LifeNumber> stackUseLastPositions_;
144 };
145 
146 }  // namespace ark::compiler
147 
148 #endif  // COMPILER_OPTIMIZER_OPTIMIZATIONS_REG_ALLOC_BASE_H
149