• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 panda::compiler {
25 
26 void ConnectIntervals(SpillFillInst *spillFill, const LifeIntervals *src, const LifeIntervals *dst);
27 bool TryToSpillConstant(LifeIntervals *interval, Graph *graph);
28 
29 class 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 
35     NO_MOVE_SEMANTIC(RegAllocBase);
36     NO_COPY_SEMANTIC(RegAllocBase);
37 
38     ~RegAllocBase() override = default;
39 
40     bool RunImpl() override;
41     const char *GetPassName() const override;
42     bool AbortIfFailed() const override;
43 
44     template <typename T>
SetRegMask(const T & regMask)45     void SetRegMask(const T &regMask)
46     {
47         regsMask_.Init(regMask);
48     }
49 
GetRegMask()50     LocationMask &GetRegMask()
51     {
52         return regsMask_;
53     }
54 
GetRegMask()55     const LocationMask &GetRegMask() const
56     {
57         return regsMask_;
58     }
59 
60     template <typename T>
SetVRegMask(const T & vregMask)61     void SetVRegMask(const T &vregMask)
62     {
63         vregsMask_.Init(vregMask);
64     }
65 
GetVRegMask()66     LocationMask &GetVRegMask()
67     {
68         return vregsMask_;
69     }
70 
GetVRegMask()71     const LocationMask &GetVRegMask() const
72     {
73         return vregsMask_;
74     }
75 
SetSlotsCount(size_t slotsCount)76     void SetSlotsCount(size_t slotsCount)
77     {
78         stackMask_.Resize(slotsCount);
79         stackUseLastPositions_.resize(slotsCount);
80     }
81 
GetStackMask()82     LocationMask &GetStackMask()
83     {
84         return stackMask_;
85     }
86 
87     void ReserveTempRegisters();
88 
89     // resolve graph
90     virtual bool Resolve();
91 
92 protected:
GetNextStackSlot(LifeIntervals * interval)93     StackSlot GetNextStackSlot(LifeIntervals *interval)
94     {
95         return !GetStackMask().AllSet() ? GetNextStackSlotImpl(interval) : INVALID_STACK_SLOT;
96     }
97 
GetNextStackSlotImpl(LifeIntervals * interval)98     StackSlot GetNextStackSlotImpl(LifeIntervals *interval)
99     {
100         for (size_t slot = 0; slot < GetStackMask().GetSize(); slot++) {
101             if (GetStackMask().IsSet(slot)) {
102                 continue;
103             }
104 
105             ASSERT(slot < stackUseLastPositions_.size());
106             if (stackUseLastPositions_[slot] > interval->GetBegin()) {
107                 continue;
108             }
109 
110             GetStackMask().Set(slot);
111             stackUseLastPositions_[slot] = interval->GetEnd();
112             return slot;
113         }
114         return INVALID_STACK_SLOT;
115     }
116 
117     void PrepareIntervals();
118 
InitIntervals()119     virtual void InitIntervals() {}
120 
PrepareInterval(LifeIntervals * interval)121     virtual void PrepareInterval([[maybe_unused]] LifeIntervals *interval) {}
122 
123     // Prepare allocations and run passes such as LivenessAnalyzer
124     virtual bool Prepare();
125 
126     // Arrange intervals/ranges and RA
127     virtual bool Allocate() = 0;
128 
129     // Post resolve actions
130     virtual bool Finish();
131 
132 private:
133     void SetType(LifeIntervals *interval);
134     void SetPreassignedRegisters(LifeIntervals *interval);
135     size_t GetTotalSlotsCount();
136 
137 private:
138     LocationMask regsMask_;
139     LocationMask vregsMask_;
140     LocationMask stackMask_;
141     ArenaVector<LifeNumber> stackUseLastPositions_;
142 };
143 
144 }  // namespace panda::compiler
145 
146 #endif  // COMPILER_OPTIMIZER_OPTIMIZATIONS_REG_ALLOC_BASE_H
147