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_CG_AARCH64_AARCH64_SCHEDULE_H 17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_SCHEDULE_H 18 19 #include "schedule.h" 20 #include "aarch64_operand.h" 21 22 namespace maplebe { 23 enum RegisterType : uint8 { 24 kRegisterUndef, 25 kRegisterInt, 26 kRegisterFloat, 27 kRegisterCc, 28 kRegisterLast, 29 }; 30 31 class AArch64ScheduleProcessInfo : public ScheduleProcessInfo { 32 public: AArch64ScheduleProcessInfo(uint32 size)33 explicit AArch64ScheduleProcessInfo(uint32 size) : ScheduleProcessInfo(size) {} 34 ~AArch64ScheduleProcessInfo() override = default; 35 36 /* recover register type which is not recorded in live analysis */ 37 static RegType GetRegisterType(const CGFunc &f, regno_t regNO); 38 void VaryLiveRegSet(const CGFunc &f, regno_t regNO, bool isInc); 39 void VaryFreeRegSet(const CGFunc &f, std::set<regno_t> regNOs, DepNode &node); 40 GetFreeIntRegs(DepNode & node)41 uint32 GetFreeIntRegs(DepNode &node) 42 { 43 return (freeIntRegNodeSet.count(&node)) > 0 ? freeIntRegNodeSet.find(&node)->second : 0; 44 } IncFreeIntRegNode(DepNode & node)45 void IncFreeIntRegNode(DepNode &node) 46 { 47 if (freeIntRegNodeSet.count(&node) == 0) { 48 freeIntRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1)); 49 } else { 50 freeIntRegNodeSet.find(&node)->second++; 51 } 52 } GetFreeIntRegNodeSet()53 const std::map<DepNode *, uint32> &GetFreeIntRegNodeSet() const 54 { 55 return freeIntRegNodeSet; 56 } IncFreeFpRegNode(DepNode & node)57 void IncFreeFpRegNode(DepNode &node) 58 { 59 if (freeFpRegNodeSet.count(&node) == 0) { 60 freeFpRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1)); 61 } else { 62 freeFpRegNodeSet.find(&node)->second++; 63 } 64 } GetFreeFpRegs(DepNode & node)65 uint32 GetFreeFpRegs(DepNode &node) 66 { 67 return (freeFpRegNodeSet.count(&node)) > 0 ? freeFpRegNodeSet.find(&node)->second : 0; 68 } GetFreeFpRegNodeSet()69 const std::map<DepNode *, uint32> &GetFreeFpRegNodeSet() const 70 { 71 return freeFpRegNodeSet; 72 } 73 ClearALLFreeRegNodeSet()74 void ClearALLFreeRegNodeSet() 75 { 76 freeIntRegNodeSet.clear(); 77 freeFpRegNodeSet.clear(); 78 } 79 FindIntLiveReg(regno_t reg)80 size_t FindIntLiveReg(regno_t reg) const 81 { 82 return intLiveRegSet.count(reg); 83 } IncIntLiveRegSet(regno_t reg)84 void IncIntLiveRegSet(regno_t reg) 85 { 86 intLiveRegSet.emplace(reg); 87 } DecIntLiveRegSet(regno_t reg)88 void DecIntLiveRegSet(regno_t reg) 89 { 90 intLiveRegSet.erase(reg); 91 } FindFpLiveReg(regno_t reg)92 size_t FindFpLiveReg(regno_t reg) const 93 { 94 return fpLiveRegSet.count(reg); 95 } IncFpLiveRegSet(regno_t reg)96 void IncFpLiveRegSet(regno_t reg) 97 { 98 fpLiveRegSet.emplace(reg); 99 } DecFpLiveRegSet(regno_t reg)100 void DecFpLiveRegSet(regno_t reg) 101 { 102 fpLiveRegSet.erase(reg); 103 } 104 SizeOfIntLiveRegSet()105 size_t SizeOfIntLiveRegSet() const 106 { 107 return intLiveRegSet.size(); 108 } 109 SizeOfCalleeSaveLiveRegister(bool isInt)110 size_t SizeOfCalleeSaveLiveRegister(bool isInt) 111 { 112 size_t num = 0; 113 if (isInt) { 114 for (auto regNO : intLiveRegSet) { 115 if (regNO > static_cast<regno_t>(R19)) { 116 num++; 117 } 118 } 119 } else { 120 for (auto regNO : fpLiveRegSet) { 121 if (regNO > static_cast<regno_t>(V16)) { 122 num++; 123 } 124 } 125 } 126 return num; 127 } 128 SizeOfFpLiveRegSet()129 size_t SizeOfFpLiveRegSet() const 130 { 131 return fpLiveRegSet.size(); 132 } 133 134 private: 135 std::set<regno_t> intLiveRegSet; 136 std::set<regno_t> fpLiveRegSet; 137 std::map<DepNode *, uint32> freeIntRegNodeSet; 138 std::map<DepNode *, uint32> freeFpRegNodeSet; 139 }; 140 141 class AArch64Schedule : public Schedule { 142 public: AArch64Schedule(CGFunc & func,MemPool & memPool,LiveAnalysis & live,const std::string & phaseName)143 AArch64Schedule(CGFunc &func, MemPool &memPool, LiveAnalysis &live, const std::string &phaseName) 144 : Schedule(func, memPool, live, phaseName) 145 { 146 intCalleeSaveThreshold = func.UseFP() ? intCalleeSaveThresholdBase : intCalleeSaveThresholdEnhance; 147 } 148 ~AArch64Schedule() override = default; 149 150 protected: 151 void DumpDepGraph(const MapleVector<DepNode *> &nodes) const; 152 void DumpScheduleResult(const MapleVector<DepNode *> &nodes, SimulateType type) const; 153 void GenerateDot(const BB &bb, const MapleVector<DepNode *> &nodes) const; 154 void EraseNodeFromNodeList(const DepNode &target, MapleVector<DepNode *> &nodeList) override; 155 void FindAndCombineMemoryAccessPair(const std::vector<DepNode *> &memList) override; 156 void RegPressureScheduling(BB &bb, MapleVector<DepNode *> &nodes) override; 157 158 private: 159 enum CSRResult : uint8 { 160 kNode1, 161 kNode2, 162 kDoCSP /* can do csp further */ 163 }; 164 void Init() override; 165 void MemoryAccessPairOpt() override; 166 void ClinitPairOpt() override; 167 uint32 DoSchedule() override; 168 uint32 DoBruteForceSchedule() override; 169 uint32 SimulateOnly() override; 170 void UpdateBruteForceSchedCycle() override; 171 void IterateBruteForce(DepNode &targetNode, MapleVector<DepNode *> &readyList, uint32 currCycle, 172 MapleVector<DepNode *> &scheduledNodes, uint32 &maxCycleCount, 173 MapleVector<DepNode *> &optimizedScheduledNodes) override; 174 bool CanCombine(const Insn &insn) const override; 175 void ListScheduling(bool beforeRA) override; 176 void BruteForceScheduling(const BB &bb); 177 void SimulateScheduling(const BB &bb); 178 void FinalizeScheduling(BB &bb, const DepAnalysis &depAnalysis) override; 179 uint32 ComputeEstart(uint32 cycle) override; 180 void ComputeLstart(uint32 maxEstart) override; 181 void UpdateELStartsOnCycle(uint32 cycle) override; 182 void RandomTest() override; 183 void EraseNodeFromReadyList(const DepNode &target) override; 184 uint32 GetNextSepIndex() const override; 185 void CountUnitKind(const DepNode &depNode, uint32 array[], const uint32 arraySize) const override; 186 static bool IfUseUnitKind(const DepNode &depNode, uint32 index); 187 void UpdateReadyList(DepNode &targetNode, MapleVector<DepNode *> &readyList, bool updateEStart) override; 188 void UpdateScheduleProcessInfo(AArch64ScheduleProcessInfo &info) const; 189 void UpdateAdvanceCycle(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &targetNode) const; 190 bool CheckSchedulable(AArch64ScheduleProcessInfo &info) const; 191 void SelectNode(AArch64ScheduleProcessInfo &scheduleInfo); 192 static void DumpDebugInfo(const ScheduleProcessInfo &scheduleInfo); 193 bool CompareDepNode(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const; 194 void CalculateMaxUnitKindCount(ScheduleProcessInfo &scheduleInfo) const; 195 void UpdateReleaseRegInfo(AArch64ScheduleProcessInfo &scheduleInfo); 196 std::set<regno_t> CanFreeRegister(const DepNode &node) const; 197 void UpdateLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &node); 198 void InitLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo); 199 int CalSeriesCycles(const MapleVector<DepNode *> &nodes) const; 200 CSRResult DoCSR(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const; 201 AArch64Schedule::CSRResult ScheduleCrossCall(const DepNode &node1, const DepNode &node2) const; 202 int intCalleeSaveThreshold = 0; 203 204 static uint32 maxUnitIndex; 205 static int intRegPressureThreshold; 206 static int fpRegPressureThreshold; 207 static int intCalleeSaveThresholdBase; 208 static int intCalleeSaveThresholdEnhance; 209 static int fpCalleeSaveThreshold; 210 }; 211 } /* namespace maplebe */ 212 213 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_SCHEDULE_H */ 214