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