Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/IceCfgNode.cpp

Issue 652633002: Subzero: Improve performance of liveness analysis and live range construction. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Remove TODO Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceCfgNode.h ('k') | src/IceDefs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the CfgNode class, including the complexities 10 // This file implements the CfgNode class, including the complexities
11 // of instruction insertion and in-edge calculation. 11 // of instruction insertion and in-edge calculation.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "IceCfg.h" 15 #include "IceCfg.h"
16 #include "IceCfgNode.h" 16 #include "IceCfgNode.h"
17 #include "IceInst.h" 17 #include "IceInst.h"
18 #include "IceLiveness.h" 18 #include "IceLiveness.h"
19 #include "IceOperand.h" 19 #include "IceOperand.h"
20 #include "IceTargetLowering.h" 20 #include "IceTargetLowering.h"
21 21
22 namespace Ice { 22 namespace Ice {
23 23
24 CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber, IceString Name) 24 CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber, IceString Name)
25 : Func(Func), Number(LabelNumber), Name(Name), HasReturn(false) {} 25 : Func(Func), Number(LabelNumber), Name(Name), HasReturn(false),
26 InstCountEstimate(0) {}
26 27
27 // Returns the name the node was created with. If no name was given, 28 // Returns the name the node was created with. If no name was given,
28 // it synthesizes a (hopefully) unique name. 29 // it synthesizes a (hopefully) unique name.
29 IceString CfgNode::getName() const { 30 IceString CfgNode::getName() const {
30 if (!Name.empty()) 31 if (!Name.empty())
31 return Name; 32 return Name;
32 char buf[30]; 33 char buf[30];
33 snprintf(buf, llvm::array_lengthof(buf), "__%u", getIndex()); 34 snprintf(buf, llvm::array_lengthof(buf), "__%u", getIndex());
34 return buf; 35 return buf;
35 } 36 }
36 37
37 // Adds an instruction to either the Phi list or the regular 38 // Adds an instruction to either the Phi list or the regular
38 // instruction list. Validates that all Phis are added before all 39 // instruction list. Validates that all Phis are added before all
39 // regular instructions. 40 // regular instructions.
40 void CfgNode::appendInst(Inst *Inst) { 41 void CfgNode::appendInst(Inst *Inst) {
42 ++InstCountEstimate;
41 if (InstPhi *Phi = llvm::dyn_cast<InstPhi>(Inst)) { 43 if (InstPhi *Phi = llvm::dyn_cast<InstPhi>(Inst)) {
42 if (!Insts.empty()) { 44 if (!Insts.empty()) {
43 Func->setError("Phi instruction added to the middle of a block"); 45 Func->setError("Phi instruction added to the middle of a block");
44 return; 46 return;
45 } 47 }
46 Phis.push_back(Phi); 48 Phis.push_back(Phi);
47 } else { 49 } else {
48 Insts.push_back(Inst); 50 Insts.push_back(Inst);
49 } 51 }
50 } 52 }
51 53
52 // Renumbers the non-deleted instructions in the node. This needs to 54 // Renumbers the non-deleted instructions in the node. This needs to
53 // be done in preparation for live range analysis. The instruction 55 // be done in preparation for live range analysis. The instruction
54 // numbers in a block must be monotonically increasing. The range of 56 // numbers in a block must be monotonically increasing. The range of
55 // instruction numbers in a block, from lowest to highest, must not 57 // instruction numbers in a block, from lowest to highest, must not
56 // overlap with the range of any other block. 58 // overlap with the range of any other block.
57 void CfgNode::renumberInstructions() { 59 void CfgNode::renumberInstructions() {
60 InstNumberT FirstNumber = Func->getNextInstNumber();
58 for (InstPhi *I : Phis) 61 for (InstPhi *I : Phis)
59 I->renumber(Func); 62 I->renumber(Func);
60 for (Inst *I : Insts) 63 for (Inst *I : Insts)
61 I->renumber(Func); 64 I->renumber(Func);
65 InstCountEstimate = Func->getNextInstNumber() - FirstNumber;
62 } 66 }
63 67
64 // When a node is created, the OutEdges are immediately knows, but the 68 // When a node is created, the OutEdges are immediately knows, but the
65 // InEdges have to be built up incrementally. After the CFG has been 69 // InEdges have to be built up incrementally. After the CFG has been
66 // constructed, the computePredecessors() pass finalizes it by 70 // constructed, the computePredecessors() pass finalizes it by
67 // creating the InEdges list. 71 // creating the InEdges list.
68 void CfgNode::computePredecessors() { 72 void CfgNode::computePredecessors() {
69 OutEdges = (*Insts.rbegin())->getTerminatorEdges(); 73 OutEdges = (*Insts.rbegin())->getTerminatorEdges();
70 for (CfgNode *Succ : OutEdges) 74 for (CfgNode *Succ : OutEdges)
71 Succ->InEdges.push_back(this); 75 Succ->InEdges.push_back(this);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 if (llvm::isa<InstRet>(*Orig)) 248 if (llvm::isa<InstRet>(*Orig))
245 setHasReturn(); 249 setHasReturn();
246 Target->lower(); 250 Target->lower();
247 // Ensure target lowering actually moved the cursor. 251 // Ensure target lowering actually moved the cursor.
248 assert(Context.getCur() != Orig); 252 assert(Context.getCur() != Orig);
249 } 253 }
250 } 254 }
251 255
252 void CfgNode::livenessLightweight() { 256 void CfgNode::livenessLightweight() {
253 SizeT NumVars = Func->getNumVariables(); 257 SizeT NumVars = Func->getNumVariables();
254 llvm::BitVector Live(NumVars); 258 LivenessBV Live(NumVars);
255 // Process regular instructions in reverse order. 259 // Process regular instructions in reverse order.
256 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. 260 // TODO(stichnot): Use llvm::make_range with LLVM 3.5.
257 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { 261 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) {
258 if ((*I)->isDeleted()) 262 if ((*I)->isDeleted())
259 continue; 263 continue;
260 (*I)->livenessLightweight(Func, Live); 264 (*I)->livenessLightweight(Func, Live);
261 } 265 }
262 for (InstPhi *I : Phis) { 266 for (InstPhi *I : Phis) {
263 if (I->isDeleted()) 267 if (I->isDeleted())
264 continue; 268 continue;
265 I->livenessLightweight(Func, Live); 269 I->livenessLightweight(Func, Live);
266 } 270 }
267 } 271 }
268 272
269 // Performs liveness analysis on the block. Returns true if the 273 // Performs liveness analysis on the block. Returns true if the
270 // incoming liveness changed from before, false if it stayed the same. 274 // incoming liveness changed from before, false if it stayed the same.
271 // (If it changes, the node's predecessors need to be processed 275 // (If it changes, the node's predecessors need to be processed
272 // again.) 276 // again.)
273 bool CfgNode::liveness(Liveness *Liveness) { 277 bool CfgNode::liveness(Liveness *Liveness) {
274 SizeT NumVars = Liveness->getNumVarsInNode(this); 278 SizeT NumVars = Liveness->getNumVarsInNode(this);
275 llvm::BitVector Live(NumVars); 279 LivenessBV Live(NumVars);
280 LiveBeginEndMap *LiveBegin = NULL;
281 LiveBeginEndMap *LiveEnd = NULL;
276 // Mark the beginning and ending of each variable's live range 282 // Mark the beginning and ending of each variable's live range
277 // with the sentinel instruction number 0. 283 // with the sentinel instruction number 0.
278 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); 284 if (Liveness->getMode() == Liveness_Intervals) {
279 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); 285 LiveBegin = Liveness->getLiveBegin(this);
280 InstNumberT Sentinel = Inst::NumberSentinel; 286 LiveEnd = Liveness->getLiveEnd(this);
281 LiveBegin.assign(NumVars, Sentinel); 287 LiveBegin->clear();
282 LiveEnd.assign(NumVars, Sentinel); 288 LiveEnd->clear();
289 // Guess that the number of live ranges beginning is roughly the
290 // number of instructions, and same for live ranges ending.
291 LiveBegin->reserve(getInstCountEstimate());
292 LiveEnd->reserve(getInstCountEstimate());
293 }
283 // Initialize Live to be the union of all successors' LiveIn. 294 // Initialize Live to be the union of all successors' LiveIn.
284 for (CfgNode *Succ : OutEdges) { 295 for (CfgNode *Succ : OutEdges) {
285 Live |= Liveness->getLiveIn(Succ); 296 Live |= Liveness->getLiveIn(Succ);
286 // Mark corresponding argument of phis in successor as live. 297 // Mark corresponding argument of phis in successor as live.
287 for (InstPhi *I : Succ->Phis) 298 for (InstPhi *I : Succ->Phis)
288 I->livenessPhiOperand(Live, this, Liveness); 299 I->livenessPhiOperand(Live, this, Liveness);
289 } 300 }
290 Liveness->getLiveOut(this) = Live; 301 Liveness->getLiveOut(this) = Live;
291 302
292 // Process regular instructions in reverse order. 303 // Process regular instructions in reverse order.
293 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. 304 // TODO(stichnot): Use llvm::make_range with LLVM 3.5.
294 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { 305 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) {
295 if ((*I)->isDeleted()) 306 if ((*I)->isDeleted())
296 continue; 307 continue;
297 (*I)->liveness((*I)->getNumber(), Live, Liveness, this); 308 (*I)->liveness((*I)->getNumber(), Live, Liveness, LiveBegin, LiveEnd);
298 } 309 }
299 // Process phis in forward order so that we can override the 310 // Process phis in forward order so that we can override the
300 // instruction number to be that of the earliest phi instruction in 311 // instruction number to be that of the earliest phi instruction in
301 // the block. 312 // the block.
302 InstNumberT FirstPhiNumber = Inst::NumberSentinel; 313 InstNumberT FirstPhiNumber = Inst::NumberSentinel;
303 for (InstPhi *I : Phis) { 314 for (InstPhi *I : Phis) {
304 if (I->isDeleted()) 315 if (I->isDeleted())
305 continue; 316 continue;
306 if (FirstPhiNumber == Inst::NumberSentinel) 317 if (FirstPhiNumber == Inst::NumberSentinel)
307 FirstPhiNumber = I->getNumber(); 318 FirstPhiNumber = I->getNumber();
308 I->liveness(FirstPhiNumber, Live, Liveness, this); 319 I->liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd);
309 } 320 }
310 321
311 // When using the sparse representation, after traversing the 322 // When using the sparse representation, after traversing the
312 // instructions in the block, the Live bitvector should only contain 323 // instructions in the block, the Live bitvector should only contain
313 // set bits for global variables upon block entry. We validate this 324 // set bits for global variables upon block entry. We validate this
314 // by shrinking the Live vector and then testing it against the 325 // by shrinking the Live vector and then testing it against the
315 // pre-shrunk version. (The shrinking is required, but the 326 // pre-shrunk version. (The shrinking is required, but the
316 // validation is not.) 327 // validation is not.)
317 llvm::BitVector LiveOrig = Live; 328 LivenessBV LiveOrig = Live;
318 Live.resize(Liveness->getNumGlobalVars()); 329 Live.resize(Liveness->getNumGlobalVars());
319 // Non-global arguments in the entry node are allowed to be live on 330 // Non-global arguments in the entry node are allowed to be live on
320 // entry. 331 // entry.
321 bool IsEntry = (Func->getEntryNode() == this); 332 bool IsEntry = (Func->getEntryNode() == this);
322 if (!(IsEntry || Live == LiveOrig)) { 333 if (!(IsEntry || Live == LiveOrig)) {
323 // This is a fatal liveness consistency error. Print some 334 // This is a fatal liveness consistency error. Print some
324 // diagnostics and abort. 335 // diagnostics and abort.
325 Ostream &Str = Func->getContext()->getStrDump(); 336 Ostream &Str = Func->getContext()->getStrDump();
326 Func->resetCurrentNode(); 337 Func->resetCurrentNode();
327 Str << "LiveOrig-Live ="; 338 Str << "LiveOrig-Live =";
328 for (SizeT i = Live.size(); i < LiveOrig.size(); ++i) { 339 for (SizeT i = Live.size(); i < LiveOrig.size(); ++i) {
329 if (LiveOrig.test(i)) { 340 if (LiveOrig.test(i)) {
330 Str << " "; 341 Str << " ";
331 Liveness->getVariable(i, this)->dump(Func); 342 Liveness->getVariable(i, this)->dump(Func);
332 } 343 }
333 } 344 }
334 Str << "\n"; 345 Str << "\n";
335 llvm_unreachable("Fatal inconsistency in liveness analysis"); 346 llvm_unreachable("Fatal inconsistency in liveness analysis");
336 } 347 }
337 348
338 bool Changed = false; 349 bool Changed = false;
339 llvm::BitVector &LiveIn = Liveness->getLiveIn(this); 350 LivenessBV &LiveIn = Liveness->getLiveIn(this);
340 // Add in current LiveIn 351 // Add in current LiveIn
341 Live |= LiveIn; 352 Live |= LiveIn;
342 // Check result, set LiveIn=Live 353 // Check result, set LiveIn=Live
343 Changed = (Live != LiveIn); 354 Changed = (Live != LiveIn);
344 if (Changed) 355 if (Changed)
345 LiveIn = Live; 356 LiveIn = Live;
346 return Changed; 357 return Changed;
347 } 358 }
348 359
360 #ifndef NDEBUG
361 namespace {
362
363 bool comparePair(const LiveBeginEndMapEntry &A, const LiveBeginEndMapEntry &B) {
364 return A.first == B.first;
365 }
366
367 } // end of anonymous namespace
368 #endif // NDEBUG
369
349 // Now that basic liveness is complete, remove dead instructions that 370 // Now that basic liveness is complete, remove dead instructions that
350 // were tentatively marked as dead, and compute actual live ranges. 371 // were tentatively marked as dead, and compute actual live ranges.
351 // It is assumed that within a single basic block, a live range begins 372 // It is assumed that within a single basic block, a live range begins
352 // at most once and ends at most once. This is certainly true for 373 // at most once and ends at most once. This is certainly true for
353 // pure SSA form. It is also true once phis are lowered, since each 374 // pure SSA form. It is also true once phis are lowered, since each
354 // assignment to the phi-based temporary is in a different basic 375 // assignment to the phi-based temporary is in a different basic
355 // block, and there is a single read that ends the live in the basic 376 // block, and there is a single read that ends the live in the basic
356 // block that contained the actual phi instruction. 377 // block that contained the actual phi instruction.
357 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { 378 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) {
358 InstNumberT FirstInstNum = Inst::NumberSentinel; 379 InstNumberT FirstInstNum = Inst::NumberSentinel;
(...skipping 30 matching lines...) Expand all
389 } 410 }
390 } 411 }
391 } 412 }
392 } 413 }
393 } 414 }
394 if (Mode != Liveness_Intervals) 415 if (Mode != Liveness_Intervals)
395 return; 416 return;
396 TimerMarker T1(TimerStack::TT_liveRangeCtor, Func); 417 TimerMarker T1(TimerStack::TT_liveRangeCtor, Func);
397 418
398 SizeT NumVars = Liveness->getNumVarsInNode(this); 419 SizeT NumVars = Liveness->getNumVarsInNode(this);
399 SizeT NumGlobals = Liveness->getNumGlobalVars(); 420 LivenessBV &LiveIn = Liveness->getLiveIn(this);
400 llvm::BitVector &LiveIn = Liveness->getLiveIn(this); 421 LivenessBV &LiveOut = Liveness->getLiveOut(this);
401 llvm::BitVector &LiveOut = Liveness->getLiveOut(this); 422 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this);
402 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); 423 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this);
403 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); 424 std::sort(MapBegin.begin(), MapBegin.end());
404 for (SizeT i = 0; i < NumVars; ++i) { 425 std::sort(MapEnd.begin(), MapEnd.end());
405 // Deal with the case where the variable is both live-in and 426 // Verify there are no duplicates.
406 // live-out, but LiveEnd comes before LiveBegin. In this case, we 427 assert(std::adjacent_find(MapBegin.begin(), MapBegin.end(), comparePair) ==
407 // need to add two segments to the live range because there is a 428 MapBegin.end());
408 // hole in the middle. This would typically happen as a result of 429 assert(std::adjacent_find(MapEnd.begin(), MapEnd.end(), comparePair) ==
409 // phi lowering in the presence of loopback edges. 430 MapEnd.end());
410 bool IsGlobal = (i < NumGlobals); 431
411 if (IsGlobal && LiveIn[i] && LiveOut[i] && LiveBegin[i] > LiveEnd[i]) { 432 LivenessBV LiveInAndOut = LiveIn;
412 Variable *Var = Liveness->getVariable(i, this); 433 LiveInAndOut &= LiveOut;
413 Liveness->addLiveRange(Var, FirstInstNum, LiveEnd[i], 1); 434
414 Liveness->addLiveRange(Var, LiveBegin[i], LastInstNum + 1, 1); 435 // Iterate in parallel across the sorted MapBegin[] and MapEnd[].
415 continue; 436 auto IBB = MapBegin.begin(), IEB = MapEnd.begin();
437 auto IBE = MapBegin.end(), IEE = MapEnd.end();
438 while (IBB != IBE || IEB != IEE) {
439 SizeT i1 = IBB == IBE ? NumVars : IBB->first;
440 SizeT i2 = IEB == IEE ? NumVars : IEB->first;
441 SizeT i = std::min(i1, i2);
442 // i1 is the Variable number of the next MapBegin entry, and i2 is
443 // the Variable number of the next MapEnd entry. If i1==i2, then
444 // the Variable's live range begins and ends in this block. If
445 // i1<i2, then i1's live range begins at instruction IBB->second
446 // and extends through the end of the block. If i1>i2, then i2's
447 // live range begins at the first instruction of the block and
448 // ends at IEB->second. In any case, we choose the lesser of i1
449 // and i2 and proceed accordingly.
450 InstNumberT LB = i == i1 ? IBB->second : FirstInstNum;
451 InstNumberT LE = i == i2 ? IEB->second : LastInstNum + 1;
452
453 Variable *Var = Liveness->getVariable(i, this);
454 if (!Var->getIgnoreLiveness()) {
455 if (LB > LE) {
456 Liveness->addLiveRange(Var, FirstInstNum, LE, 1);
457 Liveness->addLiveRange(Var, LB, LastInstNum + 1, 1);
458 // Assert that Var is a global variable by checking that its
459 // liveness index is less than the number of globals. This
460 // ensures that the LiveInAndOut[] access is valid.
461 assert(i < Liveness->getNumGlobalVars());
462 LiveInAndOut[i] = false;
463 } else {
464 Liveness->addLiveRange(Var, LB, LE, 1);
465 }
416 } 466 }
417 InstNumberT Begin = (IsGlobal && LiveIn[i]) ? FirstInstNum : LiveBegin[i]; 467 if (i == i1)
418 InstNumberT End = (IsGlobal && LiveOut[i]) ? LastInstNum + 1 : LiveEnd[i]; 468 ++IBB;
419 if (Begin == Inst::NumberSentinel && End == Inst::NumberSentinel) 469 if (i == i2)
420 continue; 470 ++IEB;
421 if (Begin <= FirstInstNum) 471 }
422 Begin = FirstInstNum; 472 // Process the variables that are live across the entire block.
423 if (End == Inst::NumberSentinel) 473 for (int i = LiveInAndOut.find_first(); i != -1;
424 End = LastInstNum + 1; 474 i = LiveInAndOut.find_next(i)) {
425 Variable *Var = Liveness->getVariable(i, this); 475 Variable *Var = Liveness->getVariable(i, this);
426 Liveness->addLiveRange(Var, Begin, End, 1); 476 Liveness->addLiveRange(Var, FirstInstNum, LastInstNum + 1, 1);
427 } 477 }
428 } 478 }
429 479
430 void CfgNode::doBranchOpt(const CfgNode *NextNode) { 480 void CfgNode::doBranchOpt(const CfgNode *NextNode) {
431 TargetLowering *Target = Func->getTarget(); 481 TargetLowering *Target = Func->getTarget();
432 // Check every instruction for a branch optimization opportunity. 482 // Check every instruction for a branch optimization opportunity.
433 // It may be more efficient to iterate in reverse and stop after the 483 // It may be more efficient to iterate in reverse and stop after the
434 // first opportunity, unless there is some target lowering where we 484 // first opportunity, unless there is some target lowering where we
435 // have the possibility of multiple such optimizations per block 485 // have the possibility of multiple such optimizations per block
436 // (currently not the case for x86 lowering). 486 // (currently not the case for x86 lowering).
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 bool First = true; 547 bool First = true;
498 for (CfgNode *I : InEdges) { 548 for (CfgNode *I : InEdges) {
499 if (!First) 549 if (!First)
500 Str << ", "; 550 Str << ", ";
501 First = false; 551 First = false;
502 Str << "%" << I->getName(); 552 Str << "%" << I->getName();
503 } 553 }
504 Str << "\n"; 554 Str << "\n";
505 } 555 }
506 // Dump the live-in variables. 556 // Dump the live-in variables.
507 llvm::BitVector LiveIn; 557 LivenessBV LiveIn;
508 if (Liveness) 558 if (Liveness)
509 LiveIn = Liveness->getLiveIn(this); 559 LiveIn = Liveness->getLiveIn(this);
510 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) { 560 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) {
511 Str << " // LiveIn:"; 561 Str << " // LiveIn:";
512 for (SizeT i = 0; i < LiveIn.size(); ++i) { 562 for (SizeT i = 0; i < LiveIn.size(); ++i) {
513 if (LiveIn[i]) { 563 if (LiveIn[i]) {
514 Str << " %" << Liveness->getVariable(i, this)->getName(); 564 Str << " %" << Liveness->getVariable(i, this)->getName();
515 } 565 }
516 } 566 }
517 Str << "\n"; 567 Str << "\n";
518 } 568 }
519 // Dump each instruction. 569 // Dump each instruction.
520 if (Func->getContext()->isVerbose(IceV_Instructions)) { 570 if (Func->getContext()->isVerbose(IceV_Instructions)) {
521 for (InstPhi *I : Phis) 571 for (InstPhi *I : Phis)
522 I->dumpDecorated(Func); 572 I->dumpDecorated(Func);
523 for (Inst *I : Insts) 573 for (Inst *I : Insts)
524 I->dumpDecorated(Func); 574 I->dumpDecorated(Func);
525 } 575 }
526 // Dump the live-out variables. 576 // Dump the live-out variables.
527 llvm::BitVector LiveOut; 577 LivenessBV LiveOut;
528 if (Liveness) 578 if (Liveness)
529 LiveOut = Liveness->getLiveOut(this); 579 LiveOut = Liveness->getLiveOut(this);
530 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { 580 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) {
531 Str << " // LiveOut:"; 581 Str << " // LiveOut:";
532 for (SizeT i = 0; i < LiveOut.size(); ++i) { 582 for (SizeT i = 0; i < LiveOut.size(); ++i) {
533 if (LiveOut[i]) { 583 if (LiveOut[i]) {
534 Str << " %" << Liveness->getVariable(i, this)->getName(); 584 Str << " %" << Liveness->getVariable(i, this)->getName();
535 } 585 }
536 } 586 }
537 Str << "\n"; 587 Str << "\n";
538 } 588 }
539 // Dump list of successor nodes. 589 // Dump list of successor nodes.
540 if (Func->getContext()->isVerbose(IceV_Succs)) { 590 if (Func->getContext()->isVerbose(IceV_Succs)) {
541 Str << " // succs = "; 591 Str << " // succs = ";
542 bool First = true; 592 bool First = true;
543 for (CfgNode *I : OutEdges) { 593 for (CfgNode *I : OutEdges) {
544 if (!First) 594 if (!First)
545 Str << ", "; 595 Str << ", ";
546 First = false; 596 First = false;
547 Str << "%" << I->getName(); 597 Str << "%" << I->getName();
548 } 598 }
549 Str << "\n"; 599 Str << "\n";
550 } 600 }
551 } 601 }
552 602
553 } // end of namespace Ice 603 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfgNode.h ('k') | src/IceDefs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698