• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 MAPLEBE_INCLUDE_AD_MAD_H
17 #define MAPLEBE_INCLUDE_AD_MAD_H
18 #include <vector>
19 #include <bitset>
20 #include "types_def.h"
21 #include "mpl_logging.h"
22 #include "insn.h"
23 
24 namespace maplebe {
25 constexpr int kOccupyWidth = 32;
26 enum UnitId : maple::uint32 {
27 #include "mplad_unit_id.def"
28     kUnitIdLast
29 };
30 
31 enum UnitType : maple::uint8 { kUnitTypePrimart, kUnitTypeOr, kUnitTypeAnd, KUnitTypeNone };
32 
33 enum RealUnitKind : maple::uint32 {
34     kUnitKindUndef,
35 #include "mplad_unit_kind.def"
36     kUnitKindLast = 13
37 };
38 
39 enum SlotType : maple::uint8 {
40     kSlotNone,
41     kSlot0,
42     kSlot1,
43     kSlotAny,
44     kSlots,
45 };
46 
47 /* machine model */
48 enum LatencyType : maple::uint32 {
49 /* LT: latency */
50 #include "mplad_latency_type.def"
51     kLtLast,
52 };
53 
54 class Unit {
55 public:
56     explicit Unit(enum UnitId theUnitId);
57     Unit(enum UnitType theUnitType, enum UnitId theUnitId, int numOfUnits, ...);
58     ~Unit() = default;
59 
GetUnitType()60     enum UnitType GetUnitType() const
61     {
62         return unitType;
63     }
64 
GetUnitId()65     enum UnitId GetUnitId() const
66     {
67         return unitId;
68     };
69 
70     const std::vector<Unit *> &GetCompositeUnits() const;
71 
72     std::string GetName() const;
73     bool IsIdle(uint32 cycle) const;
74     void Occupy(uint32 cycle);
75     void Release();
76     void AdvanceOneCycle();
77     void Dump(int indent = 0) const;
78     std::bitset<kOccupyWidth> GetOccupancyTable() const;
79 
SetOccupancyTable(const std::bitset<kOccupyWidth> value)80     void SetOccupancyTable(const std::bitset<kOccupyWidth> value)
81     {
82         occupancyTable = value;
83     }
84 
85 private:
86     void PrintIndent(int indent) const;
87 
88     enum UnitId unitId;
89     enum UnitType unitType;
90     // using 32-bit vector simulating resource occupation, the LSB always indicates the current cycle by AdvanceOneCycle
91     std::bitset<kOccupyWidth> occupancyTable;
92     std::vector<Unit *> compositeUnits;
93 };
94 
95 class Reservation {
96 public:
97     Reservation(LatencyType t, int l, int n, ...);
98     ~Reservation() = default;
99 
IsEqual(maple::uint32 typ)100     bool IsEqual(maple::uint32 typ) const
101     {
102         return typ == type;
103     }
104 
GetLatency()105     int GetLatency() const
106     {
107         return latency;
108     }
109 
GetUnitNum()110     uint32 GetUnitNum() const
111     {
112         return unitNum;
113     }
114 
GetSlot()115     enum SlotType GetSlot() const
116     {
117         return slot;
118     }
119 
120     const std::string &GetSlotName() const;
121 
GetUnit()122     Unit *const *GetUnit() const
123     {
124         return units;
125     }
126 
127 private:
128     static const int kMaxUnit = 13;
129     LatencyType type;
130     int latency;
131     uint32 unitNum;
132     Unit *units[kMaxUnit];
133     enum SlotType slot = kSlotNone;
134 
135     SlotType GetSlotType(UnitId unitID) const;
136 };
137 
138 class Bypass {
139 public:
Bypass(LatencyType d,LatencyType u,int l)140     Bypass(LatencyType d, LatencyType u, int l) : def(d), use(u), latency(l) {}
141     virtual ~Bypass() = default;
142 
143     virtual bool CanBypass(const Insn &defInsn, const Insn &useInsn) const;
144 
GetLatency()145     int GetLatency() const
146     {
147         return latency;
148     }
149 
GetDefType()150     LatencyType GetDefType() const
151     {
152         return def;
153     }
154 
GetUseType()155     LatencyType GetUseType() const
156     {
157         return use;
158     }
159 
160 private:
161     LatencyType def;
162     LatencyType use;
163     int latency;
164 };
165 
166 class MAD {
167 public:
MAD()168     MAD()
169     {
170         InitParallelism();
171         InitBypass();
172     }
173 
174     ~MAD();
175 
176     using BypassVector = std::vector<Bypass *>;
177 
178     void InitParallelism() const;
179     void InitBypass() const;
180     bool IsFullIssued() const;
181     int GetLatency(const Insn &def, const Insn &use) const;
182     int DefaultLatency(const Insn &insn) const;
183     Reservation *FindReservation(const Insn &insn) const;
184     void AdvanceOneCycleForAll() const;
185     void ReleaseAllUnits() const;
186     void SaveStates(std::vector<std::bitset<kOccupyWidth>> &occupyTable, int size) const;
187     void RestoreStates(std::vector<std::bitset<kOccupyWidth>> &occupyTable, int size) const;
188 
GetMaxParallelism()189     int GetMaxParallelism() const
190     {
191         return parallelism;
192     }
193 
GetUnitByUnitId(enum UnitId uId)194     const Unit *GetUnitByUnitId(enum UnitId uId) const
195     {
196         CHECK_FATAL(!allUnits.empty(), "CHECK_CONTAINER_EMPTY");
197         return allUnits[uId];
198     }
199 
AddUnit(Unit & u)200     static void AddUnit(Unit &u)
201     {
202         allUnits.emplace_back(&u);
203     }
204 
GetAllUnitsSize()205     static maple::uint32 GetAllUnitsSize()
206     {
207         return allUnits.size();
208     }
209 
AddReservation(Reservation & rev)210     static void AddReservation(Reservation &rev)
211     {
212         allReservations.emplace_back(&rev);
213     }
214 
AddBypass(Bypass & bp)215     static void AddBypass(Bypass &bp)
216     {
217         DEBUG_ASSERT(bp.GetDefType() < kLtLast, "out of range");
218         DEBUG_ASSERT(bp.GetUseType() < kLtLast, "out of range");
219         (bypassArrays[bp.GetDefType()][bp.GetUseType()]).push_back(&bp);
220     }
221 
222 protected:
SetMaxParallelism(int num)223     static void SetMaxParallelism(int num)
224     {
225         parallelism = num;
226     }
227 
228     int BypassLatency(const Insn &def, const Insn &use) const;
229 
230 private:
231     static int parallelism;
232     static std::vector<Unit *> allUnits;
233     static std::vector<Reservation *> allReservations;
234     static std::array<std::array<BypassVector, kLtLast>, kLtLast> bypassArrays;
235 };
236 
237 class AluShiftBypass : public Bypass {
238 public:
AluShiftBypass(LatencyType d,LatencyType u,int l)239     AluShiftBypass(LatencyType d, LatencyType u, int l) : Bypass(d, u, l) {}
240     ~AluShiftBypass() override = default;
241 
242     bool CanBypass(const Insn &defInsn, const Insn &useInsn) const override;
243 };
244 
245 class AccumulatorBypass : public Bypass {
246 public:
AccumulatorBypass(LatencyType d,LatencyType u,int l)247     AccumulatorBypass(LatencyType d, LatencyType u, int l) : Bypass(d, u, l) {}
248     ~AccumulatorBypass() override = default;
249 
250     bool CanBypass(const Insn &defInsn, const Insn &useInsn) const override;
251 };
252 
253 class StoreAddrBypass : public Bypass {
254 public:
StoreAddrBypass(LatencyType d,LatencyType u,int l)255     StoreAddrBypass(LatencyType d, LatencyType u, int l) : Bypass(d, u, l) {}
256     ~StoreAddrBypass() override = default;
257 
258     bool CanBypass(const Insn &defInsn, const Insn &useInsn) const override;
259 };
260 } /* namespace maplebe */
261 
262 #endif /* MAPLEBE_INCLUDE_AD_MAD_H */
263