• 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 "cgfunc.h"
17 #include "cg_ssu_pre.h"
18 
19 namespace maplebe {
20 
21 // ================ Step 6: Code Motion ================
CodeMotion()22 void SSUPre::CodeMotion()
23 {
24     // pass 1 only donig insertion
25     for (SOcc *occ : allOccs) {
26         if (occ->occTy != kSOccLambdaRes) {
27             continue;
28         }
29         SLambdaResOcc *lambdaResOcc = static_cast<SLambdaResOcc *>(occ);
30         if (lambdaResOcc->insertHere) {
31             workCand->restoreAtEntryBBs.insert(lambdaResOcc->cgbb->GetId());
32         }
33     }
34     // pass 2 only doing deletion
35     for (SOcc *occ : realOccs) {
36         if (occ->occTy != kSOccReal) {
37             continue;
38         }
39         SRealOcc *realOcc = static_cast<SRealOcc *>(occ);
40         if (!realOcc->redundant) {
41             if (realOcc->cgbb->IsWontExit()) {
42                 workCand->restoreAtEpilog = true;
43                 break;
44             }
45             workCand->restoreAtExitBBs.insert(realOcc->cgbb->GetId());
46         }
47     }
48     if (enabledDebug) {
49         if (workCand->restoreAtEpilog) {
50             LogInfo::MapleLogger() << "Giving up because of restore inside infinite loop" << '\n';
51             return;
52         }
53         LogInfo::MapleLogger() << " _______ output _______" << '\n';
54         LogInfo::MapleLogger() << " restoreAtEntryBBs: [";
55         for (uint32 id : workCand->restoreAtEntryBBs) {
56             LogInfo::MapleLogger() << id << " ";
57         }
58         LogInfo::MapleLogger() << "]\n restoreAtExitBBs: [";
59         for (uint32 id : workCand->restoreAtExitBBs) {
60             LogInfo::MapleLogger() << id << " ";
61         }
62         LogInfo::MapleLogger() << "]\n\n";
63     }
64 }
65 
66 // ================ Step 5: Finalize ================
67 // for setting SRealOcc's redundant flag and SLambdaResOcc's insertHere flag
Finalize()68 void SSUPre::Finalize()
69 {
70     std::vector<SOcc *> anticipatedDefVec(classCount + 1, nullptr);
71     // preorder traversal of post-dominator tree
72     for (SOcc *occ : allOccs) {
73         size_t classId = static_cast<size_t>(occ->classId);
74         switch (occ->occTy) {
75             case kSOccLambda: {
76                 auto *lambdaOcc = static_cast<SLambdaOcc *>(occ);
77                 if (lambdaOcc->WillBeAnt()) {
78                     anticipatedDefVec[classId] = lambdaOcc;
79                 }
80                 break;
81             }
82             case kSOccReal: {
83                 auto *realOcc = static_cast<SRealOcc *>(occ);
84                 if (anticipatedDefVec[classId] == nullptr || !anticipatedDefVec[classId]->IsPostDominate(pdom, occ)) {
85                     realOcc->redundant = false;
86                     anticipatedDefVec[classId] = realOcc;
87                 } else {
88                     realOcc->redundant = true;
89                 }
90                 break;
91             }
92             case kSOccLambdaRes: {
93                 auto *lambdaResOcc = static_cast<SLambdaResOcc *>(occ);
94                 const SLambdaOcc *lambdaOcc = lambdaResOcc->useLambdaOcc;
95                 if (lambdaOcc->WillBeAnt()) {
96                     if (lambdaResOcc->use == nullptr ||
97                         (!lambdaResOcc->hasRealUse && lambdaResOcc->use->occTy == kSOccLambda &&
98                          !static_cast<SLambdaOcc *>(lambdaResOcc->use)->WillBeAnt())) {
99                         // insert a store
100                         if (lambdaResOcc->cgbb->GetPreds().size() != 1) {  // critical edge
101                             workCand->restoreAtEpilog = true;
102                             break;
103                         }
104                         lambdaResOcc->insertHere = true;
105                     } else {
106                         lambdaResOcc->use = anticipatedDefVec[classId];
107                     }
108                 }
109                 break;
110             }
111             case kSOccEntry:
112             case kSOccKill:
113                 break;
114             default:
115                 DEBUG_ASSERT(false, "Finalize: unexpected occ type");
116                 break;
117         }
118         if (workCand->restoreAtEpilog) {
119             break;
120         }
121     }
122     if (enabledDebug) {
123         LogInfo::MapleLogger() << " _______ after finalize _______" << '\n';
124         if (workCand->restoreAtEpilog) {
125             LogInfo::MapleLogger() << "Giving up because of insertion at critical edge" << '\n';
126             return;
127         }
128         for (SOcc *occ : allOccs) {
129             if (occ->occTy == kSOccReal) {
130                 SRealOcc *realOcc = static_cast<SRealOcc *>(occ);
131                 if (!realOcc->redundant) {
132                     occ->Dump();
133                     LogInfo::MapleLogger() << " non-redundant" << '\n';
134                 }
135             } else if (occ->occTy == kSOccLambdaRes) {
136                 SLambdaResOcc *lambdaResOcc = static_cast<SLambdaResOcc *>(occ);
137                 if (lambdaResOcc->insertHere) {
138                     occ->Dump();
139                     LogInfo::MapleLogger() << " insertHere" << '\n';
140                 }
141             }
142         }
143     }
144 }
145 
146 // ================ Step 4: WillBeAnt Computation ================
147 
ResetCanBeAnt(SLambdaOcc * lambda) const148 void SSUPre::ResetCanBeAnt(SLambdaOcc *lambda) const
149 {
150     lambda->isCanBeAnt = false;
151     // the following loop finds lambda's defs and reset them
152     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
153         for (SLambdaResOcc *lambdaResOcc : lambdaOcc->lambdaRes) {
154             if (lambdaResOcc->use != nullptr && lambdaResOcc->use == lambda) {
155                 if (!lambdaResOcc->hasRealUse && !lambdaOcc->isUpsafe && lambdaOcc->isCanBeAnt) {
156                     ResetCanBeAnt(lambdaOcc);
157                 }
158             }
159         }
160     }
161 }
162 
ComputeCanBeAnt() const163 void SSUPre::ComputeCanBeAnt() const
164 {
165     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
166         if (!lambdaOcc->isUpsafe && lambdaOcc->isCanBeAnt) {
167             bool existNullUse = false;
168             for (SLambdaResOcc *lambdaResOcc : lambdaOcc->lambdaRes) {
169                 if (lambdaResOcc->use == nullptr) {
170                     existNullUse = true;
171                     break;
172                 }
173             }
174             if (existNullUse) {
175                 ResetCanBeAnt(lambdaOcc);
176             }
177         }
178     }
179 }
180 
ResetEarlier(SLambdaOcc * lambda) const181 void SSUPre::ResetEarlier(SLambdaOcc *lambda) const
182 {
183     lambda->isEarlier = false;
184     // the following loop finds lambda's defs and reset them
185     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
186         for (SLambdaResOcc *lambdaResOcc : lambdaOcc->lambdaRes) {
187             if (lambdaResOcc->use != nullptr && lambdaResOcc->use == lambda) {
188                 if (lambdaOcc->isEarlier) {
189                     ResetEarlier(lambdaOcc);
190                 }
191             }
192         }
193     }
194 }
195 
ComputeEarlier() const196 void SSUPre::ComputeEarlier() const
197 {
198     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
199         lambdaOcc->isEarlier = lambdaOcc->isCanBeAnt;
200     }
201     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
202         if (lambdaOcc->isEarlier) {
203             bool existNonNullUse = false;
204             for (SLambdaResOcc *lambdaResOcc : lambdaOcc->lambdaRes) {
205                 if (lambdaResOcc->use != nullptr && lambdaResOcc->hasRealUse) {
206                     existNonNullUse = true;
207                     break;
208                 }
209             }
210             if (existNonNullUse) {
211                 ResetEarlier(lambdaOcc);
212             }
213         }
214     }
215     if (enabledDebug) {
216         LogInfo::MapleLogger() << " _______ after earlier computation _______" << '\n';
217         for (SLambdaOcc *lambdaOcc : lambdaOccs) {
218             lambdaOcc->Dump();
219             if (lambdaOcc->isCanBeAnt) {
220                 LogInfo::MapleLogger() << " canbeant";
221             }
222             if (lambdaOcc->isEarlier) {
223                 LogInfo::MapleLogger() << " earlier";
224             }
225             if (lambdaOcc->isCanBeAnt && !lambdaOcc->isEarlier) {
226                 LogInfo::MapleLogger() << " will be ant";
227             }
228             LogInfo::MapleLogger() << '\n';
229         }
230     }
231 }
232 
233 // ================ Step 3: Upsafe Computation ================
ResetUpsafe(const SLambdaResOcc * lambdaRes) const234 void SSUPre::ResetUpsafe(const SLambdaResOcc *lambdaRes) const
235 {
236     if (lambdaRes->hasRealUse) {
237         return;
238     }
239     SOcc *useOcc = lambdaRes->use;
240     if (useOcc == nullptr || useOcc->occTy != kSOccLambda) {
241         return;
242     }
243     auto *useLambdaOcc = static_cast<SLambdaOcc *>(useOcc);
244     if (!useLambdaOcc->isUpsafe) {
245         return;
246     }
247     useLambdaOcc->isUpsafe = false;
248     for (SLambdaResOcc *lambdaResOcc : useLambdaOcc->lambdaRes) {
249         ResetUpsafe(lambdaResOcc);
250     }
251 }
252 
ComputeUpsafe() const253 void SSUPre::ComputeUpsafe() const
254 {
255     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
256         if (!lambdaOcc->isUpsafe) {
257             // propagate not-upsafe forward along def-use edges
258             for (SLambdaResOcc *lambdaResOcc : lambdaOcc->lambdaRes) {
259                 ResetUpsafe(lambdaResOcc);
260             }
261         }
262     }
263     if (enabledDebug) {
264         LogInfo::MapleLogger() << " _______ after upsafe computation _______" << '\n';
265         for (SLambdaOcc *lambdaOcc : lambdaOccs) {
266             lambdaOcc->Dump();
267             if (lambdaOcc->isUpsafe) {
268                 LogInfo::MapleLogger() << " upsafe";
269             }
270             LogInfo::MapleLogger() << '\n';
271         }
272     }
273 }
274 
275 // ================ Step 2: rename ================
Rename()276 void SSUPre::Rename()
277 {
278     std::stack<SOcc *> occStack;
279     classCount = 0;
280     // iterate thru the occurrences in order of preorder traversal of
281     // post-dominator tree
282     for (SOcc *occ : allOccs) {
283         while (!occStack.empty() && !occStack.top()->IsPostDominate(pdom, occ)) {
284             occStack.pop();
285         }
286         switch (occ->occTy) {
287             case kSOccKill:
288                 if (!occStack.empty()) {
289                     SOcc *topOcc = occStack.top();
290                     if (topOcc->occTy == kSOccLambda) {
291                         static_cast<SLambdaOcc *>(topOcc)->isUpsafe = false;
292                     }
293                 }
294                 occStack.push(occ);
295                 break;
296             case kSOccEntry:
297                 if (!occStack.empty()) {
298                     SOcc *topOcc = occStack.top();
299                     if (topOcc->occTy == kSOccLambda) {
300                         static_cast<SLambdaOcc *>(topOcc)->isUpsafe = false;
301                     }
302                 }
303                 break;
304             case kSOccLambda:
305                 // assign new class
306                 occ->classId = ++classCount;
307                 occStack.push(occ);
308                 break;
309             case kSOccReal: {
310                 if (occStack.empty()) {
311                     // assign new class
312                     occ->classId = ++classCount;
313                     occStack.push(occ);
314                     break;
315                 }
316                 SOcc *topOcc = occStack.top();
317                 if (topOcc->occTy == kSOccKill) {
318                     // assign new class
319                     occ->classId = ++classCount;
320                     occStack.push(occ);
321                     break;
322                 }
323                 DEBUG_ASSERT(topOcc->occTy == kSOccLambda || topOcc->occTy == kSOccReal,
324                              "Rename: unexpected top-of-stack occ");
325                 occ->classId = topOcc->classId;
326                 if (topOcc->occTy == kSOccLambda) {
327                     occStack.push(occ);
328                 }
329                 break;
330             }
331             case kSOccLambdaRes: {
332                 if (occStack.empty()) {
333                     // leave classId as 0
334                     break;
335                 }
336                 SOcc *topOcc = occStack.top();
337                 if (topOcc->occTy == kSOccKill) {
338                     // leave classId as 0
339                     break;
340                 }
341                 DEBUG_ASSERT(topOcc->occTy == kSOccLambda || topOcc->occTy == kSOccReal,
342                              "Rename: unexpected top-of-stack occ");
343                 occ->use = topOcc;
344                 occ->classId = topOcc->classId;
345                 if (topOcc->occTy == kSOccReal) {
346                     static_cast<SLambdaResOcc *>(occ)->hasRealUse = true;
347                 }
348                 break;
349             }
350             default:
351                 DEBUG_ASSERT(false, "Rename: unexpected type of occurrence");
352                 break;
353         }
354     }
355     if (enabledDebug) {
356         LogInfo::MapleLogger() << " _______ after rename _______" << '\n';
357         for (SOcc *occ : allOccs) {
358             occ->Dump();
359             LogInfo::MapleLogger() << '\n';
360         }
361     }
362 }
363 
364 // ================ Step 1: insert lambdas ================
365 
366 // form lambda occ based on the real occ in workCand->realOccs; result is
367 // stored in lambdaDfns
FormLambdas()368 void SSUPre::FormLambdas()
369 {
370     for (SOcc *occ : realOccs) {
371         if (occ->occTy == kSOccKill) {
372             continue;
373         }
374         GetIterPdomFrontier(occ->cgbb, &lambdaDfns);
375     }
376 }
377 
378 // form allOccs inclusive of real, kill, lambda, lambdaRes, entry occurrences;
379 // form lambdaOccs containing only the lambdas
CreateSortedOccs()380 void SSUPre::CreateSortedOccs()
381 {
382     // form lambdaRes occs based on the succs of the lambda occs; result is
383     // stored in lambdaResDfns
384     std::multiset<uint32> lambdaResDfns;
385     for (uint32 dfn : lambdaDfns) {
386         const BBId bbId = pdom->GetPdtPreOrderItem(dfn);
387         BB *cgbb = cgFunc->GetAllBBs()[bbId];
388         for (BB *succ : cgbb->GetSuccs()) {
389             (void)lambdaResDfns.insert(pdom->GetPdtDfnItem(succ->GetId()));
390         }
391     }
392     std::unordered_map<BBId, std::forward_list<SLambdaResOcc *>> bb2LambdaResMap;
393     MapleVector<SOcc *>::iterator realOccIt = realOccs.begin();
394     MapleVector<SEntryOcc *>::iterator entryOccIt = entryOccs.begin();
395     MapleSet<uint32>::iterator lambdaDfnIt = lambdaDfns.begin();
396     MapleSet<uint32>::iterator lambdaResDfnIt = lambdaResDfns.begin();
397     SOcc *nextRealOcc = nullptr;
398     if (realOccIt != realOccs.end()) {
399         nextRealOcc = *realOccIt;
400     }
401     SEntryOcc *nextEntryOcc = nullptr;
402     if (entryOccIt != entryOccs.end()) {
403         nextEntryOcc = *entryOccIt;
404     }
405     SLambdaOcc *nextLambdaOcc = nullptr;
406     if (lambdaDfnIt != lambdaDfns.end()) {
407         nextLambdaOcc =
408             spreMp->New<SLambdaOcc>(cgFunc->GetAllBBs().at(pdom->GetPdtPreOrderItem(*lambdaDfnIt)), spreAllocator);
409     }
410     SLambdaResOcc *nextLambdaResOcc = nullptr;
411     if (lambdaResDfnIt != lambdaResDfns.end()) {
412         nextLambdaResOcc =
413             spreMp->New<SLambdaResOcc>(cgFunc->GetAllBBs().at(pdom->GetPdtPreOrderItem(*lambdaResDfnIt)));
414         auto it = bb2LambdaResMap.find(pdom->GetPdtPreOrderItem(*lambdaResDfnIt));
415         if (it == bb2LambdaResMap.end()) {
416             std::forward_list<SLambdaResOcc *> newlist = {nextLambdaResOcc};
417             bb2LambdaResMap[pdom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist;
418         } else {
419             it->second.push_front(nextLambdaResOcc);
420         }
421     }
422     SOcc *pickedOcc = nullptr;  // the next picked occ in order of preorder traversal of post-dominator tree
423     do {
424         pickedOcc = nullptr;
425         if (nextLambdaOcc != nullptr) {
426             pickedOcc = nextLambdaOcc;
427         }
428         if (nextRealOcc != nullptr && (pickedOcc == nullptr || pdom->GetPdtDfnItem(nextRealOcc->cgbb->GetId()) <
429                                                                    pdom->GetPdtDfnItem(pickedOcc->cgbb->GetId()))) {
430             pickedOcc = nextRealOcc;
431         }
432         if (nextLambdaResOcc != nullptr &&
433             (pickedOcc == nullptr || *lambdaResDfnIt < pdom->GetPdtDfnItem(pickedOcc->cgbb->GetId()))) {
434             pickedOcc = nextLambdaResOcc;
435         }
436         if (nextEntryOcc != nullptr && (pickedOcc == nullptr || pdom->GetPdtDfnItem(nextEntryOcc->cgbb->GetId()) <
437                                                                     pdom->GetPdtDfnItem(pickedOcc->cgbb->GetId()))) {
438             pickedOcc = nextEntryOcc;
439         }
440         if (pickedOcc != nullptr) {
441             allOccs.push_back(pickedOcc);
442             switch (pickedOcc->occTy) {
443                 case kSOccReal:
444                 case kSOccKill: {
445                     // get the next real/kill occ
446                     CHECK_FATAL(realOccIt != realOccs.end(), "iterator check");
447                     ++realOccIt;
448                     if (realOccIt != realOccs.end()) {
449                         nextRealOcc = *realOccIt;
450                     } else {
451                         nextRealOcc = nullptr;
452                     }
453                     break;
454                 }
455                 case kSOccEntry: {
456                     CHECK_FATAL(entryOccIt != entryOccs.end(), "iterator check");
457                     ++entryOccIt;
458                     if (entryOccIt != entryOccs.end()) {
459                         nextEntryOcc = *entryOccIt;
460                     } else {
461                         nextEntryOcc = nullptr;
462                     }
463                     break;
464                 }
465                 case kSOccLambda: {
466                     lambdaOccs.push_back(static_cast<SLambdaOcc *>(pickedOcc));
467                     CHECK_FATAL(lambdaDfnIt != lambdaDfns.end(), "iterator check");
468                     ++lambdaDfnIt;
469                     if (lambdaDfnIt != lambdaDfns.end()) {
470                         nextLambdaOcc = spreMp->New<SLambdaOcc>(
471                             cgFunc->GetAllBBs().at(pdom->GetPdtPreOrderItem(*lambdaDfnIt)), spreAllocator);
472                     } else {
473                         nextLambdaOcc = nullptr;
474                     }
475                     break;
476                 }
477                 case kSOccLambdaRes: {
478                     CHECK_FATAL(lambdaResDfnIt != lambdaResDfns.end(), "iterator check");
479                     ++lambdaResDfnIt;
480                     if (lambdaResDfnIt != lambdaResDfns.end()) {
481                         nextLambdaResOcc = spreMp->New<SLambdaResOcc>(
482                             cgFunc->GetAllBBs().at(pdom->GetPdtPreOrderItem(*lambdaResDfnIt)));
483                         auto it = bb2LambdaResMap.find(pdom->GetPdtPreOrderItem(*lambdaResDfnIt));
484                         if (it == bb2LambdaResMap.end()) {
485                             std::forward_list<SLambdaResOcc *> newlist = {nextLambdaResOcc};
486                             bb2LambdaResMap[pdom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist;
487                         } else {
488                             it->second.push_front(nextLambdaResOcc);
489                         }
490                     } else {
491                         nextLambdaResOcc = nullptr;
492                     }
493                     break;
494                 }
495                 default:
496                     DEBUG_ASSERT(false, "CreateSortedOccs: unexpected occTy");
497                     break;
498             }
499         }
500     } while (pickedOcc != nullptr);
501     // initialize lambdaRes vector in each SLambdaOcc node and useLambdaOcc in each SLambdaResOcc
502     for (SLambdaOcc *lambdaOcc : lambdaOccs) {
503         for (BB *succ : lambdaOcc->cgbb->GetSuccs()) {
504             SLambdaResOcc *lambdaResOcc = bb2LambdaResMap[succ->GetId()].front();
505             lambdaOcc->lambdaRes.push_back(lambdaResOcc);
506             lambdaResOcc->useLambdaOcc = lambdaOcc;
507             bb2LambdaResMap[succ->GetId()].pop_front();
508         }
509     }
510     if (enabledDebug) {
511         LogInfo::MapleLogger() << " _______ after lambda insertion _______" << '\n';
512         for (SOcc *occ : allOccs) {
513             occ->Dump();
514             LogInfo::MapleLogger() << '\n';
515         }
516     }
517 }
518 
519 // ================ Step 0: Preparations ================
520 
PropagateNotAvail(BB * bb,std::set<BB *,BBIdCmp> * visitedBBs)521 void SSUPre::PropagateNotAvail(BB *bb, std::set<BB *, BBIdCmp> *visitedBBs)
522 {
523     if (visitedBBs->count(bb) != 0) {
524         return;
525     }
526     visitedBBs->insert(bb);
527     if (workCand->occBBs.count(bb->GetId()) != 0 || workCand->saveBBs.count(bb->GetId()) != 0) {
528         return;
529     }
530     fullyAvailBBs[bb->GetId()] = false;
531     for (BB *succbb : bb->GetSuccs()) {
532         PropagateNotAvail(succbb, visitedBBs);
533     }
534 }
535 
FormReals()536 void SSUPre::FormReals()
537 {
538     if (!asLateAsPossible) {
539         for (uint32 i = 0; i < pdom->GetPdtPreOrderSize(); i++) {
540             BBId bbid = pdom->GetPdtPreOrderItem(i);
541             BB *cgbb = cgFunc->GetAllBBs()[bbid];
542             if (workCand->saveBBs.count(cgbb->GetId()) != 0) {
543                 SRealOcc *realOcc = spreMp->New<SRealOcc>(cgbb);
544                 realOccs.push_back(realOcc);
545                 SKillOcc *killOcc = spreMp->New<SKillOcc>(cgbb);
546                 realOccs.push_back(killOcc);
547             } else if (workCand->occBBs.count(cgbb->GetId()) != 0) {
548                 SRealOcc *realOcc = spreMp->New<SRealOcc>(cgbb);
549                 realOccs.push_back(realOcc);
550             }
551         }
552     } else {
553         std::set<BB *, BBIdCmp> visitedBBs;
554         fullyAvailBBs[cgFunc->GetCommonExitBB()->GetId()] = false;
555         PropagateNotAvail(cgFunc->GetFirstBB(), &visitedBBs);
556         for (uint32 i = 0; i < pdom->GetPdtPreOrderSize(); i++) {
557             BBId bbid = pdom->GetPdtPreOrderItem(i);
558             BB *cgbb = cgFunc->GetAllBBs()[bbid];
559             if (fullyAvailBBs[cgbb->GetId()]) {
560                 SRealOcc *realOcc = spreMp->New<SRealOcc>(cgbb);
561                 realOccs.push_back(realOcc);
562                 if (workCand->saveBBs.count(cgbb->GetId()) != 0) {
563                     SKillOcc *killOcc = spreMp->New<SKillOcc>(cgbb);
564                     realOccs.push_back(killOcc);
565                 }
566             }
567         }
568     }
569 
570     if (enabledDebug) {
571         LogInfo::MapleLogger() << "Placement Optimization for callee-save restores" << '\n';
572         LogInfo::MapleLogger() << "-----------------------------------------------" << '\n';
573         LogInfo::MapleLogger() << " _______ input _______" << '\n';
574         LogInfo::MapleLogger() << " occBBs: [";
575         for (uint32 id : workCand->occBBs) {
576             LogInfo::MapleLogger() << id << " ";
577         }
578         LogInfo::MapleLogger() << "]\n saveBBs: [";
579         for (uint32 id : workCand->saveBBs) {
580             LogInfo::MapleLogger() << id << " ";
581         }
582         LogInfo::MapleLogger() << "]\n";
583     }
584 }
585 
ApplySSUPre()586 void SSUPre::ApplySSUPre()
587 {
588     FormReals();
589     // #1 insert lambdas; results in allOccs and lambdaOccs
590     FormLambdas();  // result put in the set lambda_bbs
591     CreateSortedOccs();
592     // #2 rename
593     Rename();
594     if (!lambdaOccs.empty()) {
595         // #3 UpSafety
596         ComputeUpsafe();
597         // #4 CanBeAnt
598         ComputeCanBeAnt();
599         ComputeEarlier();
600     }
601     // #5 Finalize
602     Finalize();
603     if (!workCand->restoreAtEpilog) {
604         // #6 Code Motion
605         CodeMotion();
606     }
607 }
608 
DoRestorePlacementOpt(CGFunc * f,PostDomAnalysis * pdom,SPreWorkCand * workCand)609 void DoRestorePlacementOpt(CGFunc *f, PostDomAnalysis *pdom, SPreWorkCand *workCand)
610 {
611     MemPool *tempMP = memPoolCtrler.NewMemPool("cg_ssu_pre", true);
612     SSUPre cgssupre(f, pdom, tempMP, workCand, true /*asLateAsPossible*/, false /*enabledDebug*/);
613 
614     cgssupre.ApplySSUPre();
615 
616     memPoolCtrler.DeleteMemPool(tempMP);
617 }
618 
619 }  // namespace maplebe
620