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