• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &region) 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 &region) 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