• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2023 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "pipeline/jit/pi/graph_capture/loop.h"
17 #include <fstream>
18 #include <string>
19 #include "pipeline/jit/pi/graph_capture/cfg.h"
20 #include "pipeline/jit/pi/graph_capture/graph.h"
21 
22 namespace mindspore {
23 namespace pijit {
Dump() const24 std::string LoopInfo::Dump() const {
25   std::stringstream os;
26   os << "header: " << header_->id();
27   os << " backedge: ";
28   for (auto *bb : backedges_) {
29     os << bb->id() << " ";
30   }
31   os << "\n members: ";
32   for (auto *bb : loop_members_) {
33     os << bb->id() << " ";
34   }
35   os << "\n exits: ";
36   for (auto *bb : exits_) {
37     os << bb->id() << " ";
38   }
39   os << "\n";
40   return os.str();
41 }
42 
LoopFinder(Graph * graph)43 LoopFinder::LoopFinder(Graph *graph) : graph_(*graph), alloc_(graph->allocator()) {}
44 
UpdateLoop2Graph()45 void LoopFinder::UpdateLoop2Graph() {
46   for (LoopInfo *loop = loops_; loop != nullptr; loop = loop->next()) {
47     graph_.AddLoop(loop);
48   }
49 }
50 
FormSimpleLoopInfo()51 void LoopFinder::FormSimpleLoopInfo() {
52   const std::unique_ptr<CFG> &cfg = graph_.GetCFG();
53   if (cfg == nullptr) {
54     return;
55   }
56   LoopInfo *tail_loop = nullptr;
57   for (Block *bb : *cfg) {
58     if (!bb->is_loop_head() || bb->GetJumpBB() == nullptr || bb->GetJumpBB()->id() == bb->id()) {
59       continue;
60     }
61     LoopInfo *loop = alloc_.NewLoopInfo<LoopInfo>();
62     loop->set_header(bb);
63     for (Block *pred : bb->pred_bbs()) {
64       if (pred->instrs().front().bci() > bb->instrs().front().bci()) {
65         loop->InsertBackedge(pred);
66       }
67     }
68     Block *exitBB = bb->GetJumpBB();
69     // find head's jump BB or find the BB after the max backend edge
70     for (Block *pred : loop->backedges()) {
71       if (pred->id() + 1 < cfg->bb_pool().size()) {
72         if (cfg->bb_pool()[pred->id() + 1].get()->instrs().front().bci() > exitBB->instrs().front().bci()) {
73           exitBB = cfg->bb_pool()[pred->id() + 1].get();
74         }
75       }
76     }
77     loop->InsertExit(exitBB);
78     if (loops_ == nullptr) {
79       loops_ = loop;
80     } else {
81       tail_loop->set_next(loop);
82       loop->set_prev(tail_loop);
83     }
84     for (uint32_t i = bb->id(); i < exitBB->id(); ++i) {
85       loop->InsertLoopMembers(cfg->bb_pool()[i].get());
86     }
87     tail_loop = loop;
88   }
89   UpdateLoop2Graph();
90 }
91 }  // namespace pijit
92 }  // namespace mindspore
93