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_SCHEDULE_H 17 #define MAPLEBE_INCLUDE_CG_SCHEDULE_H 18 19 #include "insn.h" 20 #include "mad.h" 21 #include "dependence.h" 22 #include "live.h" 23 24 namespace maplebe { 25 #define LIST_SCHED_DUMP_NEWPM CG_DEBUG_FUNC(f) 26 #define LIST_SCHED_DUMP_REF CG_DEBUG_FUNC(cgFunc) 27 28 class RegPressureSchedule { 29 public: RegPressureSchedule(CGFunc & func,MapleAllocator & alloc)30 RegPressureSchedule(CGFunc &func, MapleAllocator &alloc) 31 : cgFunc(func), 32 liveReg(alloc.Adapter()), 33 scheduledNode(alloc.Adapter()), 34 originalNodeSeries(alloc.Adapter()), 35 readyList(alloc.Adapter()), 36 partialList(alloc.Adapter()), 37 partialSet(alloc.Adapter()), 38 partialScheduledNode(alloc.Adapter()), 39 optimisticScheduledNodes(alloc.Adapter()), 40 splitterIndexes(alloc.Adapter()), 41 liveInRegNO(alloc.Adapter()), 42 liveOutRegNO(alloc.Adapter()) 43 { 44 } 45 virtual ~RegPressureSchedule() = default; 46 47 void InitBBInfo(BB &b, MemPool &memPool, const MapleVector<DepNode *> &nodes); 48 void BuildPhyRegInfo(const std::vector<int32> ®NumVec); 49 void initPartialSplitters(const MapleVector<DepNode *> &nodes); 50 void Init(const MapleVector<DepNode *> &nodes); 51 void UpdateBBPressure(const DepNode &node); 52 void CalculatePressure(DepNode &node, regno_t reg, bool def); 53 void SortReadyList(); 54 static bool IsLastUse(const DepNode &node, regno_t regNO); 55 void ReCalculateDepNodePressure(DepNode &node); 56 void UpdateLiveReg(const DepNode &node, regno_t reg, bool def); 57 bool CanSchedule(const DepNode &node) const; 58 void UpdateReadyList(const DepNode &node); 59 void BruteUpdateReadyList(const DepNode &node, std::vector<bool> &changedToReady); 60 void RestoreReadyList(DepNode &node, std::vector<bool> &changedToReady); 61 void UpdatePriority(DepNode &node); 62 void CalculateMaxDepth(const MapleVector<DepNode *> &nodes); 63 void CalculateNear(const DepNode &node); 64 static bool DepNodePriorityCmp(const DepNode *node1, const DepNode *node2); 65 DepNode *ChooseNode(); 66 void DoScheduling(MapleVector<DepNode *> &nodes); 67 void HeuristicScheduling(MapleVector<DepNode *> &nodes); 68 int CalculateRegisterPressure(MapleVector<DepNode *> &nodes); 69 void PartialScheduling(MapleVector<DepNode *> &nodes); 70 void BruteForceScheduling(); 71 void CalculatePredSize(DepNode &node); 72 void InitBruteForceScheduling(MapleVector<DepNode *> &nodes); 73 void EmitSchedulingSeries(MapleVector<DepNode *> &nodes); 74 75 private: 76 void DumpBBPressureInfo() const; 77 void DumpBBLiveInfo() const; 78 void DumpReadyList() const; 79 void DumpSelectInfo(const DepNode &node) const; 80 static void DumpDependencyInfo(const MapleVector<DepNode *> &nodes); 81 void ReportScheduleError() const; 82 void ReportScheduleOutput() const; 83 RegType GetRegisterType(regno_t reg) const; 84 85 CGFunc &cgFunc; 86 BB *bb = nullptr; 87 int32 *maxPressure = nullptr; 88 int32 *curPressure = nullptr; 89 MapleUnorderedSet<regno_t> liveReg; 90 /* save node that has been scheduled. */ 91 MapleVector<DepNode *> scheduledNode; 92 MapleVector<DepNode *> originalNodeSeries; 93 MapleVector<DepNode *> readyList; 94 /* save partial nodes to be scheduled */ 95 MapleVector<DepNode *> partialList; 96 MapleSet<DepNode *> partialSet; 97 /* save partial nodes which have been scheduled. */ 98 MapleVector<DepNode *> partialScheduledNode; 99 /* optimistic schedule series with minimum register pressure */ 100 MapleVector<DepNode *> optimisticScheduledNodes; 101 /* save split points */ 102 MapleVector<int> splitterIndexes; 103 /* save integer register pressure */ 104 std::vector<int> integerRegisterPressureList; 105 /* save the amount of every type register. */ 106 int32 *physicalRegNum = nullptr; 107 int32 maxPriority = 0; 108 int32 scheduleSeriesCount = 0; 109 /* live in register set */ 110 MapleSet<regno_t> liveInRegNO; 111 /* live out register set */ 112 MapleSet<regno_t> liveOutRegNO; 113 /* register pressure without pre-scheduling */ 114 int originalPressure = 0; 115 /* register pressure after pre-scheduling */ 116 int scheduledPressure = 0; 117 /* minimum pressure ever met */ 118 int minPressure = -1; 119 }; 120 121 enum SimulateType : uint8 { kListSchedule, kBruteForce, kSimulateOnly }; 122 123 class Schedule { 124 public: Schedule(CGFunc & func,MemPool & memPool,LiveAnalysis & liveAnalysis,const std::string & phase)125 Schedule(CGFunc &func, MemPool &memPool, LiveAnalysis &liveAnalysis, const std::string &phase) 126 : phaseName(phase), 127 cgFunc(func), 128 memPool(memPool), 129 alloc(&memPool), 130 live(liveAnalysis), 131 considerRegPressure(false), 132 nodes(alloc.Adapter()), 133 readyList(alloc.Adapter()), 134 liveInRegNo(alloc.Adapter()), 135 liveOutRegNo(alloc.Adapter()) 136 { 137 } 138 139 virtual ~Schedule() = default; 140 virtual void MemoryAccessPairOpt() = 0; 141 virtual void ClinitPairOpt() = 0; 142 virtual uint32 DoSchedule() = 0; 143 virtual uint32 DoBruteForceSchedule() = 0; 144 virtual uint32 SimulateOnly() = 0; 145 virtual void UpdateBruteForceSchedCycle() = 0; 146 virtual void IterateBruteForce(DepNode &targetNode, MapleVector<DepNode *> &readyList, uint32 currCycle, 147 MapleVector<DepNode *> &scheduledNodes, uint32 &maxCycleCount, 148 MapleVector<DepNode *> &optimizedScheduledNodes) = 0; 149 virtual void UpdateReadyList(DepNode &targetNode, MapleVector<DepNode *> &readyList, bool updateEStart) = 0; 150 virtual void ListScheduling(bool beforeRA) = 0; 151 virtual void FinalizeScheduling(BB &bb, const DepAnalysis &depAnalysis) = 0; 152 153 protected: 154 virtual void Init() = 0; 155 virtual uint32 ComputeEstart(uint32 cycle) = 0; 156 virtual void ComputeLstart(uint32 maxEstart) = 0; 157 virtual void UpdateELStartsOnCycle(uint32 cycle) = 0; 158 virtual void RandomTest() = 0; 159 virtual void EraseNodeFromReadyList(const DepNode &target) = 0; 160 virtual void EraseNodeFromNodeList(const DepNode &target, MapleVector<DepNode *> &nodeList) = 0; 161 virtual uint32 GetNextSepIndex() const = 0; 162 virtual void CountUnitKind(const DepNode &depNode, uint32 array[], const uint32 arraySize) const = 0; 163 virtual void FindAndCombineMemoryAccessPair(const std::vector<DepNode *> &memList) = 0; 164 virtual void RegPressureScheduling(BB &bb, MapleVector<DepNode *> &nodes) = 0; 165 virtual bool CanCombine(const Insn &insn) const = 0; SetConsiderRegPressure()166 void SetConsiderRegPressure() 167 { 168 considerRegPressure = true; 169 } GetConsiderRegPressure()170 bool GetConsiderRegPressure() const 171 { 172 return considerRegPressure; 173 } 174 void InitIDAndLoc(); 175 void RestoreFirstLoc(); PhaseName()176 std::string PhaseName() const 177 { 178 return phaseName; 179 } 180 181 const std::string phaseName; 182 CGFunc &cgFunc; 183 MemPool &memPool; 184 MapleAllocator alloc; 185 LiveAnalysis &live; 186 DepAnalysis *depAnalysis = nullptr; 187 MAD *mad = nullptr; 188 uint32 lastSeparatorIndex = 0; 189 uint32 nodeSize = 0; 190 bool considerRegPressure = false; 191 MapleVector<DepNode *> nodes; /* Dependence graph */ 192 MapleVector<DepNode *> readyList; /* Ready list. */ 193 MapleSet<regno_t> liveInRegNo; 194 MapleSet<regno_t> liveOutRegNo; 195 }; 196 197 MAPLE_FUNC_PHASE_DECLARE(CgPreScheduling, maplebe::CGFunc) 198 MAPLE_FUNC_PHASE_DECLARE(CgScheduling, maplebe::CGFunc) 199 } /* namespace maplebe */ 200 201 #endif /* MAPLEBE_INCLUDE_CG_SCHEDULE_H */ 202