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