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 "local_schedule.h"
17 #include "data_dep_base.h"
18 #include "aarch64_data_dep_base.h"
19 #include "cg.h"
20 #include "optimize_common.h"
21
22 namespace maplebe {
Run()23 void LocalSchedule::Run()
24 {
25 FCDG *fcdg = cda.GetFCDG();
26 CHECK_FATAL(fcdg != nullptr, "control dependence analysis failed");
27 if (LOCAL_SCHEDULE_DUMP) {
28 DotGenerator::GenerateDot("localsched", cgFunc, cgFunc.GetMirModule(), cgFunc.GetName());
29 }
30 InitInsnIdAndLocInsn();
31 for (auto region : fcdg->GetAllRegions()) {
32 if (region == nullptr || !CheckCondition(*region)) {
33 continue;
34 }
35 DoLocalScheduleForRegion(*region);
36 }
37 }
38
CheckCondition(CDGRegion & region) const39 bool LocalSchedule::CheckCondition(CDGRegion ®ion) const
40 {
41 CHECK_FATAL(region.GetRegionNodeSize() == 1 && region.GetRegionRoot() != nullptr,
42 "invalid region in local scheduling");
43 uint32 insnSum = 0;
44 for (auto cdgNode : region.GetRegionNodes()) {
45 BB *bb = cdgNode->GetBB();
46 CHECK_FATAL(bb != nullptr, "get bb from cdgNode failed");
47 FOR_BB_INSNS_CONST(insn, bb)
48 {
49 if (!insn->IsMachineInstruction()) {
50 continue;
51 }
52 insnSum++;
53 }
54 }
55 if (insnSum > kMaxInsnNum) {
56 return false;
57 }
58 return true;
59 }
60
DoLocalScheduleForRegion(CDGRegion & region)61 void LocalSchedule::DoLocalScheduleForRegion(CDGRegion ®ion)
62 {
63 CDGNode *cdgNode = region.GetRegionRoot();
64 BB *bb = cdgNode->GetBB();
65 DEBUG_ASSERT(bb != nullptr, "get bb from cdgNode failed");
66 if (bb->IsAtomicBuiltInBB()) {
67 return;
68 }
69 intraDDA.Run(region);
70 if (LOCAL_SCHEDULE_DUMP) {
71 intraDDA.GenerateDataDepGraphDotOfRegion(region);
72 }
73 InitInRegion(region);
74 if (LOCAL_SCHEDULE_DUMP || isUnitTest) {
75 DumpRegionInfoBeforeSchedule(region);
76 }
77 DoLocalSchedule(*cdgNode);
78 }
79
DoLocalSchedule(CDGNode & cdgNode)80 void LocalSchedule::DoLocalSchedule(CDGNode &cdgNode)
81 {
82 listScheduler = schedMP.New<ListScheduler>(schedMP, cgFunc, true, "localschedule");
83 InitInCDGNode(cdgNode);
84 listScheduler->SetCDGRegion(*cdgNode.GetRegion());
85 listScheduler->SetCDGNode(cdgNode);
86 listScheduler->SetUnitTest(isUnitTest);
87 listScheduler->DoListScheduling();
88 FinishScheduling(cdgNode);
89 if (LOCAL_SCHEDULE_DUMP || isUnitTest) {
90 DumpCDGNodeInfoAfterSchedule(cdgNode);
91 }
92 }
93
InitInCDGNode(CDGNode & cdgNode)94 void LocalSchedule::InitInCDGNode(CDGNode &cdgNode)
95 {
96 commonSchedInfo = schedMP.New<CommonScheduleInfo>(schedMP);
97 for (auto *depNode : cdgNode.GetAllDataNodes()) {
98 commonSchedInfo->AddCandidates(depNode);
99 depNode->SetState(kCandidate);
100 }
101 listScheduler->SetCommonSchedInfo(*commonSchedInfo);
102
103 InitMachineInsnNum(cdgNode);
104
105 if (LOCAL_SCHEDULE_DUMP || isUnitTest) {
106 DumpCDGNodeInfoBeforeSchedule(cdgNode);
107 }
108 }
109
PhaseRun(maplebe::CGFunc & f)110 bool CgLocalSchedule::PhaseRun(maplebe::CGFunc &f)
111 {
112 MemPool *memPool = GetPhaseMemPool();
113 auto *cda = memPool->New<ControlDepAnalysis>(f, *memPool, "localschedule", true);
114 cda->Run();
115 MAD *mad = Globals::GetInstance()->GetMAD();
116 auto *ddb = memPool->New<AArch64DataDepBase>(*memPool, f, *mad, true);
117 auto *dda = memPool->New<DataDepAnalysis>(f, *memPool, *ddb);
118 auto *localScheduler = f.GetCG()->CreateLocalSchedule(*memPool, f, *cda, *dda);
119 DEBUG_ASSERT(localScheduler != nullptr, "nullptr check");
120 localScheduler->Run();
121 return true;
122 }
123 MAPLE_TRANSFORM_PHASE_REGISTER_CANSKIP(CgLocalSchedule, localschedule)
124 } // namespace maplebe
125