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