OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |