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 #include "base_schedule.h"
17 #ifdef TARGAARCH64
18 #include "aarch64_cg.h"
19 #endif
20
21 namespace maplebe {
22 // Set insnId to guarantee default priority,
23 // Set locInsn to maintain debug info
InitInsnIdAndLocInsn()24 void BaseSchedule::InitInsnIdAndLocInsn()
25 {
26 uint32 id = 0;
27 FOR_ALL_BB(bb, &cgFunc)
28 {
29 bb->SetLastLoc(bb->GetPrev() ? bb->GetPrev()->GetLastLoc() : nullptr);
30 FOR_BB_INSNS(insn, bb)
31 {
32 if (insn->IsMachineInstruction()) {
33 insn->SetId(id++);
34 }
35 #if defined(DEBUG) && DEBUG
36 insn->AppendComment(" Insn id: " + std::to_string(insn->GetId()));
37 #endif
38 if (insn->IsImmaterialInsn() && !insn->IsComment()) {
39 bb->SetLastLoc(insn);
40 } else if (!bb->GetFirstLoc() && insn->IsMachineInstruction()) {
41 bb->SetFirstLoc(*bb->GetLastLoc());
42 }
43 }
44 }
45 }
46
InitMachineInsnNum(CDGNode & cdgNode) const47 void BaseSchedule::InitMachineInsnNum(CDGNode &cdgNode) const
48 {
49 uint32 insnNum = 0;
50 BB *curBB = cdgNode.GetBB();
51 CHECK_FATAL(curBB != nullptr, "get bb from cdgNode failed");
52 FOR_BB_INSNS_CONST(insn, curBB)
53 {
54 if (insn->IsMachineInstruction()) {
55 insnNum++;
56 }
57 }
58 cdgNode.SetInsnNum(insnNum);
59 }
60
InitInRegion(CDGRegion & region) const61 void BaseSchedule::InitInRegion(CDGRegion ®ion) const
62 {
63 // Init valid dependency size for scheduling
64 for (auto *cdgNode : region.GetRegionNodes()) {
65 for (auto *depNode : cdgNode->GetAllDataNodes()) {
66 depNode->SetState(kNormal);
67 depNode->SetValidPredsSize(static_cast<uint32>(depNode->GetPreds().size()));
68 depNode->SetValidSuccsSize(static_cast<uint32>(depNode->GetSuccs().size()));
69 }
70 }
71 }
72
CaculateOriginalCyclesOfBB(CDGNode & cdgNode) const73 uint32 BaseSchedule::CaculateOriginalCyclesOfBB(CDGNode &cdgNode) const
74 {
75 BB *bb = cdgNode.GetBB();
76 DEBUG_ASSERT(bb != nullptr, "get bb from cdgNode failed");
77
78 FOR_BB_INSNS(insn, bb)
79 {
80 if (!insn->IsMachineInstruction()) {
81 continue;
82 }
83 DepNode *depNode = insn->GetDepNode();
84 DEBUG_ASSERT(depNode != nullptr, "get depNode from insn failed");
85 // init
86 depNode->SetSimulateState(kStateUndef);
87 depNode->SetSimulateIssueCycle(0);
88 }
89
90 MAD *mad = Globals::GetInstance()->GetMAD();
91 std::vector<DepNode *> runningList;
92 uint32 curCycle = 0;
93 FOR_BB_INSNS(insn, bb)
94 {
95 if (!insn->IsMachineInstruction()) {
96 continue;
97 }
98 DepNode *depNode = insn->GetDepNode();
99 ASSERT_NOT_NULL(depNode);
100 // Currently, do not consider the conflicts of resource
101 if (depNode->GetPreds().empty()) {
102 depNode->SetSimulateState(kRunning);
103 depNode->SetSimulateIssueCycle(curCycle);
104 (void)runningList.emplace_back(depNode);
105 continue;
106 }
107 // Update depNode info on curCycle
108 for (auto *runningNode : runningList) {
109 if (runningNode->GetSimulateState() == kRunning &&
110 (static_cast<int>(curCycle) - static_cast<int>(runningNode->GetSimulateIssueCycle()) >=
111 runningNode->GetReservation()->GetLatency())) {
112 runningNode->SetSimulateState(kRetired);
113 }
114 }
115 // Update curCycle by curDepNode
116 uint32 maxWaitTime = 0;
117 for (auto *predLink : depNode->GetPreds()) {
118 ASSERT_NOT_NULL(predLink);
119 DepNode &predNode = predLink->GetFrom();
120 Insn *predInsn = predNode.GetInsn();
121 ASSERT_NOT_NULL(predInsn);
122 // Only calculate latency of true dependency in local BB
123 if (predLink->GetDepType() == kDependenceTypeTrue && predInsn->GetBB() == bb &&
124 predNode.GetSimulateState() == kRunning) {
125 DEBUG_ASSERT(curCycle >= predNode.GetSimulateIssueCycle(), "the state of dependency node is wrong");
126 if ((static_cast<int>(curCycle) - static_cast<int>(predNode.GetSimulateIssueCycle())) <
127 mad->GetLatency(*predInsn, *insn)) {
128 int actualLatency =
129 mad->GetLatency(*predInsn, *insn) -
130 (static_cast<int>(curCycle) - static_cast<int>(predNode.GetSimulateIssueCycle()));
131 maxWaitTime = std::max(maxWaitTime, static_cast<uint32>(actualLatency));
132 }
133 }
134 }
135 curCycle += maxWaitTime;
136 depNode->SetSimulateState(kRunning);
137 depNode->SetSimulateIssueCycle(curCycle);
138 }
139 return curCycle;
140 }
141
DumpRegionInfoBeforeSchedule(CDGRegion & region) const142 void BaseSchedule::DumpRegionInfoBeforeSchedule(CDGRegion ®ion) const
143 {
144 LogInfo::MapleLogger() << "---------------- Schedule Region_" << region.GetRegionId() << " ----------------\n\n";
145 LogInfo::MapleLogger() << "## total number of blocks: " << region.GetRegionNodeSize() << "\n\n";
146 LogInfo::MapleLogger() << "## topological order of blocks in region: {";
147 for (uint32 i = 0; i < region.GetRegionNodeSize(); ++i) {
148 BB *bb = region.GetRegionNodes()[i]->GetBB();
149 DEBUG_ASSERT(bb != nullptr, "get bb from cdgNode failed");
150 LogInfo::MapleLogger() << "bb_" << bb->GetId();
151 CHECK_FATAL(region.GetRegionNodeSize() >= 1, "value overflow");
152 if (i != region.GetRegionNodeSize() - 1) {
153 LogInfo::MapleLogger() << ", ";
154 } else {
155 LogInfo::MapleLogger() << "}\n\n";
156 }
157 }
158 }
159
DumpCDGNodeInfoBeforeSchedule(CDGNode & cdgNode) const160 void BaseSchedule::DumpCDGNodeInfoBeforeSchedule(CDGNode &cdgNode) const
161 {
162 BB *curBB = cdgNode.GetBB();
163 DEBUG_ASSERT(curBB != nullptr, "get bb from cdgNode failed");
164 LogInfo::MapleLogger() << "= = = = = = = = = = = = = = = = = = = = = = = = = = = =\n\n";
165 LogInfo::MapleLogger() << "## -- bb_" << curBB->GetId() << " before schedule --\n\n";
166 LogInfo::MapleLogger() << " >> candidates info of bb_" << curBB->GetId() << " <<\n\n";
167 curBB->Dump();
168 LogInfo::MapleLogger() << "\n";
169 DumpInsnInfoByScheduledOrder(cdgNode);
170 }
171
DumpCDGNodeInfoAfterSchedule(CDGNode & cdgNode) const172 void BaseSchedule::DumpCDGNodeInfoAfterSchedule(CDGNode &cdgNode) const
173 {
174 BB *curBB = cdgNode.GetBB();
175 DEBUG_ASSERT(curBB != nullptr, "get bb from cdgNode failed");
176 LogInfo::MapleLogger() << "\n";
177 LogInfo::MapleLogger() << "## -- bb_" << curBB->GetId() << " after schedule --\n";
178 LogInfo::MapleLogger() << " ideal total cycles: "
179 << (doDelayHeu ? listScheduler->GetMaxDelay() : listScheduler->GetMaxLStart()) << "\n";
180 LogInfo::MapleLogger() << " sched total cycles: " << listScheduler->GetCurrCycle() << "\n\n";
181 curBB->Dump();
182 LogInfo::MapleLogger() << " = = = = = = = = = = = = = = = = = = = = = = = = = = =\n\n\n";
183 }
184
DumpInsnInfoByScheduledOrder(CDGNode & cdgNode) const185 void BaseSchedule::DumpInsnInfoByScheduledOrder(CDGNode &cdgNode) const
186 {
187 // For print table log with unequal widths
188 int printWidth1 = 6;
189 int printWidth2 = 8;
190 int printWidth3 = 14;
191 LogInfo::MapleLogger() << " ------------------------------------------------\n";
192 (void)LogInfo::MapleLogger().fill(' ');
193 LogInfo::MapleLogger() << " " << std::setiosflags(std::ios::left) << std::setw(printWidth1) << "insn"
194 << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right)
195 << std::setw(printWidth2) << "mop" << std::resetiosflags(std::ios::right)
196 << std::setiosflags(std::ios::right) << std::setw(printWidth2) << "bb"
197 << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
198 << std::setw(printWidth3) << "succs(latency)" << std::resetiosflags(std::ios::right) << "\n";
199 LogInfo::MapleLogger() << " ------------------------------------------------\n";
200 BB *curBB = cdgNode.GetBB();
201 DEBUG_ASSERT(curBB != nullptr, "get bb from cdgNode failed");
202 FOR_BB_INSNS_CONST(insn, curBB)
203 {
204 if (!insn->IsMachineInstruction()) {
205 continue;
206 }
207 LogInfo::MapleLogger() << " " << std::setiosflags(std::ios::left) << std::setw(printWidth1)
208 << insn->GetId() << std::resetiosflags(std::ios::left)
209 << std::setiosflags(std::ios::right) << std::setw(printWidth2);
210 const InsnDesc *md = nullptr;
211 if (Globals::GetInstance()->GetTarget()->GetTargetMachine()->isAArch64()) {
212 md = &AArch64CG::kMd[insn->GetMachineOpcode()];
213 }
214 CHECK_NULL_FATAL(md);
215 LogInfo::MapleLogger() << md->name << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
216 << std::setw(printWidth2) << curBB->GetId() << std::resetiosflags(std::ios::right)
217 << std::setiosflags(std::ios::right) << std::setw(printWidth3);
218 const DepNode *depNode = insn->GetDepNode();
219 DEBUG_ASSERT(depNode != nullptr, "get depNode from insn failed");
220 for (auto succLink : depNode->GetSuccs()) {
221 DepNode &succNode = succLink->GetTo();
222 LogInfo::MapleLogger() << succNode.GetInsn()->GetId() << "(" << succLink->GetLatency() << "), ";
223 }
224 LogInfo::MapleLogger() << std::resetiosflags(std::ios::right) << "\n";
225 }
226 LogInfo::MapleLogger() << " ------------------------------------------------\n";
227 LogInfo::MapleLogger() << "\n";
228 }
229 } // namespace maplebe
230