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 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 Insts.push_back(Inst); | 48 Insts.push_back(Inst); |
49 } | 49 } |
50 } | 50 } |
51 | 51 |
52 // Renumbers the non-deleted instructions in the node. This needs to | 52 // Renumbers the non-deleted instructions in the node. This needs to |
53 // be done in preparation for live range analysis. The instruction | 53 // be done in preparation for live range analysis. The instruction |
54 // numbers in a block must be monotonically increasing. The range of | 54 // numbers in a block must be monotonically increasing. The range of |
55 // instruction numbers in a block, from lowest to highest, must not | 55 // instruction numbers in a block, from lowest to highest, must not |
56 // overlap with the range of any other block. | 56 // overlap with the range of any other block. |
57 void CfgNode::renumberInstructions() { | 57 void CfgNode::renumberInstructions() { |
58 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 58 for (InstPhi *I : Phis) |
59 (*I)->renumber(Func); | 59 I->renumber(Func); |
60 } | 60 for (Inst *I : Insts) |
61 InstList::const_iterator I = Insts.begin(), E = Insts.end(); | 61 I->renumber(Func); |
62 while (I != E) { | |
63 Inst *Inst = *I++; | |
64 Inst->renumber(Func); | |
65 } | |
66 } | 62 } |
67 | 63 |
68 // When a node is created, the OutEdges are immediately knows, but the | 64 // When a node is created, the OutEdges are immediately knows, but the |
69 // InEdges have to be built up incrementally. After the CFG has been | 65 // InEdges have to be built up incrementally. After the CFG has been |
70 // constructed, the computePredecessors() pass finalizes it by | 66 // constructed, the computePredecessors() pass finalizes it by |
71 // creating the InEdges list. | 67 // creating the InEdges list. |
72 void CfgNode::computePredecessors() { | 68 void CfgNode::computePredecessors() { |
73 OutEdges = (*Insts.rbegin())->getTerminatorEdges(); | 69 OutEdges = (*Insts.rbegin())->getTerminatorEdges(); |
74 for (NodeList::const_iterator I = OutEdges.begin(), E = OutEdges.end(); | 70 for (CfgNode *Succ : OutEdges) |
75 I != E; ++I) { | 71 Succ->InEdges.push_back(this); |
76 CfgNode *Node = *I; | |
77 Node->InEdges.push_back(this); | |
78 } | |
79 } | 72 } |
80 | 73 |
81 // This does part 1 of Phi lowering, by creating a new dest variable | 74 // This does part 1 of Phi lowering, by creating a new dest variable |
82 // for each Phi instruction, replacing the Phi instruction's dest with | 75 // for each Phi instruction, replacing the Phi instruction's dest with |
83 // that variable, and adding an explicit assignment of the old dest to | 76 // that variable, and adding an explicit assignment of the old dest to |
84 // the new dest. For example, | 77 // the new dest. For example, |
85 // a=phi(...) | 78 // a=phi(...) |
86 // changes to | 79 // changes to |
87 // "a_phi=phi(...); a=a_phi". | 80 // "a_phi=phi(...); a=a_phi". |
88 // | 81 // |
89 // This is in preparation for part 2 which deletes the Phi | 82 // This is in preparation for part 2 which deletes the Phi |
90 // instructions and appends assignment instructions to predecessor | 83 // instructions and appends assignment instructions to predecessor |
91 // blocks. Note that this transformation preserves SSA form. | 84 // blocks. Note that this transformation preserves SSA form. |
92 void CfgNode::placePhiLoads() { | 85 void CfgNode::placePhiLoads() { |
93 for (PhiList::iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 86 for (InstPhi *I : Phis) |
94 Inst *Inst = (*I)->lower(Func); | 87 Insts.insert(Insts.begin(), I->lower(Func)); |
95 Insts.insert(Insts.begin(), Inst); | |
96 } | |
97 } | 88 } |
98 | 89 |
99 // This does part 2 of Phi lowering. For each Phi instruction at each | 90 // This does part 2 of Phi lowering. For each Phi instruction at each |
100 // out-edge, create a corresponding assignment instruction, and add | 91 // out-edge, create a corresponding assignment instruction, and add |
101 // all the assignments near the end of this block. They need to be | 92 // all the assignments near the end of this block. They need to be |
102 // added before any branch instruction, and also if the block ends | 93 // added before any branch instruction, and also if the block ends |
103 // with a compare instruction followed by a branch instruction that we | 94 // with a compare instruction followed by a branch instruction that we |
104 // may want to fuse, it's better to insert the new assignments before | 95 // may want to fuse, it's better to insert the new assignments before |
105 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method | 96 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method |
106 // assumes this ordering of instructions. | 97 // assumes this ordering of instructions. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 llvm::isa<InstFcmp>(*InsertionPoint)) { | 172 llvm::isa<InstFcmp>(*InsertionPoint)) { |
182 CmpInstDest = (*InsertionPoint)->getDest(); | 173 CmpInstDest = (*InsertionPoint)->getDest(); |
183 } else { | 174 } else { |
184 ++InsertionPoint; | 175 ++InsertionPoint; |
185 } | 176 } |
186 } | 177 } |
187 } | 178 } |
188 } | 179 } |
189 | 180 |
190 // Consider every out-edge. | 181 // Consider every out-edge. |
191 for (NodeList::const_iterator I1 = OutEdges.begin(), E1 = OutEdges.end(); | 182 for (CfgNode *Succ : OutEdges) { |
192 I1 != E1; ++I1) { | |
193 CfgNode *Target = *I1; | |
194 // Consider every Phi instruction at the out-edge. | 183 // Consider every Phi instruction at the out-edge. |
195 for (PhiList::const_iterator I2 = Target->Phis.begin(), | 184 for (InstPhi *I : Succ->Phis) { |
196 E2 = Target->Phis.end(); | 185 Operand *Operand = I->getOperandForTarget(this); |
197 I2 != E2; ++I2) { | |
198 Operand *Operand = (*I2)->getOperandForTarget(this); | |
199 assert(Operand); | 186 assert(Operand); |
200 Variable *Dest = (*I2)->getDest(); | 187 Variable *Dest = I->getDest(); |
201 assert(Dest); | 188 assert(Dest); |
202 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand); | 189 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand); |
203 if (CmpInstDest == Operand) | 190 if (CmpInstDest == Operand) |
204 Insts.insert(SafeInsertionPoint, NewInst); | 191 Insts.insert(SafeInsertionPoint, NewInst); |
205 else | 192 else |
206 Insts.insert(InsertionPoint, NewInst); | 193 Insts.insert(InsertionPoint, NewInst); |
207 } | 194 } |
208 } | 195 } |
209 } | 196 } |
210 | 197 |
211 // Deletes the phi instructions after the loads and stores are placed. | 198 // Deletes the phi instructions after the loads and stores are placed. |
212 void CfgNode::deletePhis() { | 199 void CfgNode::deletePhis() { |
213 for (PhiList::iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 200 for (InstPhi *I : Phis) |
214 (*I)->setDeleted(); | 201 I->setDeleted(); |
215 } | |
216 } | 202 } |
217 | 203 |
218 // Does address mode optimization. Pass each instruction to the | 204 // Does address mode optimization. Pass each instruction to the |
219 // TargetLowering object. If it returns a new instruction | 205 // TargetLowering object. If it returns a new instruction |
220 // (representing the optimized address mode), then insert the new | 206 // (representing the optimized address mode), then insert the new |
221 // instruction and delete the old. | 207 // instruction and delete the old. |
222 void CfgNode::doAddressOpt() { | 208 void CfgNode::doAddressOpt() { |
223 TargetLowering *Target = Func->getTarget(); | 209 TargetLowering *Target = Func->getTarget(); |
224 LoweringContext &Context = Target->getContext(); | 210 LoweringContext &Context = Target->getContext(); |
225 Context.init(this); | 211 Context.init(this); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 Target->lower(); | 246 Target->lower(); |
261 // Ensure target lowering actually moved the cursor. | 247 // Ensure target lowering actually moved the cursor. |
262 assert(Context.getCur() != Orig); | 248 assert(Context.getCur() != Orig); |
263 } | 249 } |
264 } | 250 } |
265 | 251 |
266 void CfgNode::livenessLightweight() { | 252 void CfgNode::livenessLightweight() { |
267 SizeT NumVars = Func->getNumVariables(); | 253 SizeT NumVars = Func->getNumVariables(); |
268 llvm::BitVector Live(NumVars); | 254 llvm::BitVector Live(NumVars); |
269 // Process regular instructions in reverse order. | 255 // Process regular instructions in reverse order. |
270 for (InstList::const_reverse_iterator I = Insts.rbegin(), E = Insts.rend(); | 256 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
271 I != E; ++I) { | 257 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
272 if ((*I)->isDeleted()) | 258 if ((*I)->isDeleted()) |
273 continue; | 259 continue; |
274 (*I)->livenessLightweight(Func, Live); | 260 (*I)->livenessLightweight(Func, Live); |
275 } | 261 } |
276 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 262 for (InstPhi *I : Phis) { |
277 if ((*I)->isDeleted()) | 263 if (I->isDeleted()) |
278 continue; | 264 continue; |
279 (*I)->livenessLightweight(Func, Live); | 265 I->livenessLightweight(Func, Live); |
280 } | 266 } |
281 } | 267 } |
282 | 268 |
283 // Performs liveness analysis on the block. Returns true if the | 269 // Performs liveness analysis on the block. Returns true if the |
284 // incoming liveness changed from before, false if it stayed the same. | 270 // incoming liveness changed from before, false if it stayed the same. |
285 // (If it changes, the node's predecessors need to be processed | 271 // (If it changes, the node's predecessors need to be processed |
286 // again.) | 272 // again.) |
287 bool CfgNode::liveness(Liveness *Liveness) { | 273 bool CfgNode::liveness(Liveness *Liveness) { |
288 SizeT NumVars = Liveness->getNumVarsInNode(this); | 274 SizeT NumVars = Liveness->getNumVarsInNode(this); |
289 llvm::BitVector Live(NumVars); | 275 llvm::BitVector Live(NumVars); |
290 // Mark the beginning and ending of each variable's live range | 276 // Mark the beginning and ending of each variable's live range |
291 // with the sentinel instruction number 0. | 277 // with the sentinel instruction number 0. |
292 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); | 278 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); |
293 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); | 279 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); |
294 InstNumberT Sentinel = Inst::NumberSentinel; | 280 InstNumberT Sentinel = Inst::NumberSentinel; |
295 LiveBegin.assign(NumVars, Sentinel); | 281 LiveBegin.assign(NumVars, Sentinel); |
296 LiveEnd.assign(NumVars, Sentinel); | 282 LiveEnd.assign(NumVars, Sentinel); |
297 // Initialize Live to be the union of all successors' LiveIn. | 283 // Initialize Live to be the union of all successors' LiveIn. |
298 for (NodeList::const_iterator I = OutEdges.begin(), E = OutEdges.end(); | 284 for (CfgNode *Succ : OutEdges) { |
299 I != E; ++I) { | |
300 CfgNode *Succ = *I; | |
301 Live |= Liveness->getLiveIn(Succ); | 285 Live |= Liveness->getLiveIn(Succ); |
302 // Mark corresponding argument of phis in successor as live. | 286 // Mark corresponding argument of phis in successor as live. |
303 for (PhiList::const_iterator I1 = Succ->Phis.begin(), E1 = Succ->Phis.end(); | 287 for (InstPhi *I : Succ->Phis) |
304 I1 != E1; ++I1) { | 288 I->livenessPhiOperand(Live, this, Liveness); |
305 (*I1)->livenessPhiOperand(Live, this, Liveness); | |
306 } | |
307 } | 289 } |
308 Liveness->getLiveOut(this) = Live; | 290 Liveness->getLiveOut(this) = Live; |
309 | 291 |
310 // Process regular instructions in reverse order. | 292 // Process regular instructions in reverse order. |
311 for (InstList::const_reverse_iterator I = Insts.rbegin(), E = Insts.rend(); | 293 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
312 I != E; ++I) { | 294 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
313 if ((*I)->isDeleted()) | 295 if ((*I)->isDeleted()) |
314 continue; | 296 continue; |
315 (*I)->liveness((*I)->getNumber(), Live, Liveness, this); | 297 (*I)->liveness((*I)->getNumber(), Live, Liveness, this); |
316 } | 298 } |
317 // Process phis in forward order so that we can override the | 299 // Process phis in forward order so that we can override the |
318 // instruction number to be that of the earliest phi instruction in | 300 // instruction number to be that of the earliest phi instruction in |
319 // the block. | 301 // the block. |
320 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 302 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
321 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 303 for (InstPhi *I : Phis) { |
322 if ((*I)->isDeleted()) | 304 if (I->isDeleted()) |
323 continue; | 305 continue; |
324 if (FirstPhiNumber == Inst::NumberSentinel) | 306 if (FirstPhiNumber == Inst::NumberSentinel) |
325 FirstPhiNumber = (*I)->getNumber(); | 307 FirstPhiNumber = I->getNumber(); |
326 (*I)->liveness(FirstPhiNumber, Live, Liveness, this); | 308 I->liveness(FirstPhiNumber, Live, Liveness, this); |
327 } | 309 } |
328 | 310 |
329 // When using the sparse representation, after traversing the | 311 // When using the sparse representation, after traversing the |
330 // instructions in the block, the Live bitvector should only contain | 312 // instructions in the block, the Live bitvector should only contain |
331 // set bits for global variables upon block entry. We validate this | 313 // set bits for global variables upon block entry. We validate this |
332 // by shrinking the Live vector and then testing it against the | 314 // by shrinking the Live vector and then testing it against the |
333 // pre-shrunk version. (The shrinking is required, but the | 315 // pre-shrunk version. (The shrinking is required, but the |
334 // validation is not.) | 316 // validation is not.) |
335 llvm::BitVector LiveOrig = Live; | 317 llvm::BitVector LiveOrig = Live; |
336 Live.resize(Liveness->getNumGlobalVars()); | 318 Live.resize(Liveness->getNumGlobalVars()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // It is assumed that within a single basic block, a live range begins | 351 // It is assumed that within a single basic block, a live range begins |
370 // at most once and ends at most once. This is certainly true for | 352 // at most once and ends at most once. This is certainly true for |
371 // pure SSA form. It is also true once phis are lowered, since each | 353 // pure SSA form. It is also true once phis are lowered, since each |
372 // assignment to the phi-based temporary is in a different basic | 354 // assignment to the phi-based temporary is in a different basic |
373 // block, and there is a single read that ends the live in the basic | 355 // block, and there is a single read that ends the live in the basic |
374 // block that contained the actual phi instruction. | 356 // block that contained the actual phi instruction. |
375 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { | 357 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { |
376 InstNumberT FirstInstNum = Inst::NumberSentinel; | 358 InstNumberT FirstInstNum = Inst::NumberSentinel; |
377 InstNumberT LastInstNum = Inst::NumberSentinel; | 359 InstNumberT LastInstNum = Inst::NumberSentinel; |
378 // Process phis in any order. Process only Dest operands. | 360 // Process phis in any order. Process only Dest operands. |
379 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 361 for (InstPhi *I : Phis) { |
380 InstPhi *Inst = *I; | 362 I->deleteIfDead(); |
381 Inst->deleteIfDead(); | 363 if (I->isDeleted()) |
382 if (Inst->isDeleted()) | |
383 continue; | 364 continue; |
384 if (FirstInstNum == Inst::NumberSentinel) | 365 if (FirstInstNum == Inst::NumberSentinel) |
385 FirstInstNum = Inst->getNumber(); | 366 FirstInstNum = I->getNumber(); |
386 assert(Inst->getNumber() > LastInstNum); | 367 assert(I->getNumber() > LastInstNum); |
387 LastInstNum = Inst->getNumber(); | 368 LastInstNum = I->getNumber(); |
388 } | 369 } |
389 // Process instructions | 370 // Process instructions |
390 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 371 for (Inst *I : Insts) { |
391 ++I) { | 372 I->deleteIfDead(); |
392 Inst *Inst = *I; | 373 if (I->isDeleted()) |
393 Inst->deleteIfDead(); | |
394 if (Inst->isDeleted()) | |
395 continue; | 374 continue; |
396 if (FirstInstNum == Inst::NumberSentinel) | 375 if (FirstInstNum == Inst::NumberSentinel) |
397 FirstInstNum = Inst->getNumber(); | 376 FirstInstNum = I->getNumber(); |
398 assert(Inst->getNumber() > LastInstNum); | 377 assert(I->getNumber() > LastInstNum); |
399 LastInstNum = Inst->getNumber(); | 378 LastInstNum = I->getNumber(); |
400 // Create fake live ranges for a Kill instruction, but only if the | 379 // Create fake live ranges for a Kill instruction, but only if the |
401 // linked instruction is still alive. | 380 // linked instruction is still alive. |
402 if (Mode == Liveness_Intervals) { | 381 if (Mode == Liveness_Intervals) { |
403 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(Inst)) { | 382 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { |
404 if (!Kill->getLinked()->isDeleted()) { | 383 if (!Kill->getLinked()->isDeleted()) { |
405 SizeT NumSrcs = Inst->getSrcSize(); | 384 SizeT NumSrcs = I->getSrcSize(); |
406 for (SizeT i = 0; i < NumSrcs; ++i) { | 385 for (SizeT Src = 0; Src < NumSrcs; ++Src) { |
407 Variable *Var = llvm::cast<Variable>(Inst->getSrc(i)); | 386 Variable *Var = llvm::cast<Variable>(I->getSrc(Src)); |
408 InstNumberT InstNumber = Inst->getNumber(); | 387 InstNumberT InstNumber = I->getNumber(); |
409 Liveness->addLiveRange(Var, InstNumber, InstNumber, 1); | 388 Liveness->addLiveRange(Var, InstNumber, InstNumber, 1); |
410 } | 389 } |
411 } | 390 } |
412 } | 391 } |
413 } | 392 } |
414 } | 393 } |
415 if (Mode != Liveness_Intervals) | 394 if (Mode != Liveness_Intervals) |
416 return; | 395 return; |
417 | 396 |
418 SizeT NumVars = Liveness->getNumVarsInNode(this); | 397 SizeT NumVars = Liveness->getNumVarsInNode(this); |
(...skipping 28 matching lines...) Expand all Loading... |
447 } | 426 } |
448 } | 427 } |
449 | 428 |
450 void CfgNode::doBranchOpt(const CfgNode *NextNode) { | 429 void CfgNode::doBranchOpt(const CfgNode *NextNode) { |
451 TargetLowering *Target = Func->getTarget(); | 430 TargetLowering *Target = Func->getTarget(); |
452 // Check every instruction for a branch optimization opportunity. | 431 // Check every instruction for a branch optimization opportunity. |
453 // It may be more efficient to iterate in reverse and stop after the | 432 // It may be more efficient to iterate in reverse and stop after the |
454 // first opportunity, unless there is some target lowering where we | 433 // first opportunity, unless there is some target lowering where we |
455 // have the possibility of multiple such optimizations per block | 434 // have the possibility of multiple such optimizations per block |
456 // (currently not the case for x86 lowering). | 435 // (currently not the case for x86 lowering). |
457 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 436 for (Inst *I : Insts) |
458 ++I) { | 437 Target->doBranchOpt(I, NextNode); |
459 Target->doBranchOpt(*I, NextNode); | |
460 } | |
461 } | 438 } |
462 | 439 |
463 // ======================== Dump routines ======================== // | 440 // ======================== Dump routines ======================== // |
464 | 441 |
465 void CfgNode::emit(Cfg *Func) const { | 442 void CfgNode::emit(Cfg *Func) const { |
466 Func->setCurrentNode(this); | 443 Func->setCurrentNode(this); |
467 Ostream &Str = Func->getContext()->getStrEmit(); | 444 Ostream &Str = Func->getContext()->getStrEmit(); |
468 if (Func->getEntryNode() == this) { | 445 if (Func->getEntryNode() == this) { |
469 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n"; | 446 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n"; |
470 } | 447 } |
471 Str << getAsmName() << ":\n"; | 448 Str << getAsmName() << ":\n"; |
472 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 449 for (InstPhi *Phi : Phis) { |
473 InstPhi *Phi = *I; | |
474 if (Phi->isDeleted()) | 450 if (Phi->isDeleted()) |
475 continue; | 451 continue; |
476 // Emitting a Phi instruction should cause an error. | 452 // Emitting a Phi instruction should cause an error. |
477 Inst *Instr = Phi; | 453 Inst *Instr = Phi; |
478 Instr->emit(Func); | 454 Instr->emit(Func); |
479 } | 455 } |
480 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 456 for (Inst *I : Insts) { |
481 ++I) { | 457 if (I->isDeleted()) |
482 Inst *Inst = *I; | |
483 if (Inst->isDeleted()) | |
484 continue; | 458 continue; |
485 // Here we detect redundant assignments like "mov eax, eax" and | 459 // Here we detect redundant assignments like "mov eax, eax" and |
486 // suppress them. | 460 // suppress them. |
487 if (Inst->isRedundantAssign()) | 461 if (I->isRedundantAssign()) |
488 continue; | 462 continue; |
489 if (Func->UseIntegratedAssembler()) { | 463 if (Func->UseIntegratedAssembler()) { |
490 (*I)->emitIAS(Func); | 464 I->emitIAS(Func); |
491 } else { | 465 } else { |
492 (*I)->emit(Func); | 466 I->emit(Func); |
493 } | 467 } |
494 // Update emitted instruction count, plus fill/spill count for | 468 // Update emitted instruction count, plus fill/spill count for |
495 // Variable operands without a physical register. | 469 // Variable operands without a physical register. |
496 if (uint32_t Count = (*I)->getEmitInstCount()) { | 470 if (uint32_t Count = I->getEmitInstCount()) { |
497 Func->getContext()->statsUpdateEmitted(Count); | 471 Func->getContext()->statsUpdateEmitted(Count); |
498 if (Variable *Dest = (*I)->getDest()) { | 472 if (Variable *Dest = I->getDest()) { |
499 if (!Dest->hasReg()) | 473 if (!Dest->hasReg()) |
500 Func->getContext()->statsUpdateFills(); | 474 Func->getContext()->statsUpdateFills(); |
501 } | 475 } |
502 for (SizeT S = 0; S < (*I)->getSrcSize(); ++S) { | 476 for (SizeT S = 0; S < I->getSrcSize(); ++S) { |
503 if (Variable *Src = llvm::dyn_cast<Variable>((*I)->getSrc(S))) { | 477 if (Variable *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) { |
504 if (!Src->hasReg()) | 478 if (!Src->hasReg()) |
505 Func->getContext()->statsUpdateSpills(); | 479 Func->getContext()->statsUpdateSpills(); |
506 } | 480 } |
507 } | 481 } |
508 } | 482 } |
509 } | 483 } |
510 } | 484 } |
511 | 485 |
512 void CfgNode::dump(Cfg *Func) const { | 486 void CfgNode::dump(Cfg *Func) const { |
513 Func->setCurrentNode(this); | 487 Func->setCurrentNode(this); |
514 Ostream &Str = Func->getContext()->getStrDump(); | 488 Ostream &Str = Func->getContext()->getStrDump(); |
515 Liveness *Liveness = Func->getLiveness(); | 489 Liveness *Liveness = Func->getLiveness(); |
516 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 490 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
517 Str << getName() << ":\n"; | 491 Str << getName() << ":\n"; |
518 } | 492 } |
519 // Dump list of predecessor nodes. | 493 // Dump list of predecessor nodes. |
520 if (Func->getContext()->isVerbose(IceV_Preds) && !InEdges.empty()) { | 494 if (Func->getContext()->isVerbose(IceV_Preds) && !InEdges.empty()) { |
521 Str << " // preds = "; | 495 Str << " // preds = "; |
522 for (NodeList::const_iterator I = InEdges.begin(), E = InEdges.end(); | 496 bool First = true; |
523 I != E; ++I) { | 497 for (CfgNode *I : InEdges) { |
524 if (I != InEdges.begin()) | 498 if (First) |
525 Str << ", "; | 499 Str << ", "; |
526 Str << "%" << (*I)->getName(); | 500 First = false; |
| 501 Str << "%" << I->getName(); |
527 } | 502 } |
528 Str << "\n"; | 503 Str << "\n"; |
529 } | 504 } |
530 // Dump the live-in variables. | 505 // Dump the live-in variables. |
531 llvm::BitVector LiveIn; | 506 llvm::BitVector LiveIn; |
532 if (Liveness) | 507 if (Liveness) |
533 LiveIn = Liveness->getLiveIn(this); | 508 LiveIn = Liveness->getLiveIn(this); |
534 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) { | 509 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) { |
535 Str << " // LiveIn:"; | 510 Str << " // LiveIn:"; |
536 for (SizeT i = 0; i < LiveIn.size(); ++i) { | 511 for (SizeT i = 0; i < LiveIn.size(); ++i) { |
537 if (LiveIn[i]) { | 512 if (LiveIn[i]) { |
538 Str << " %" << Liveness->getVariable(i, this)->getName(); | 513 Str << " %" << Liveness->getVariable(i, this)->getName(); |
539 } | 514 } |
540 } | 515 } |
541 Str << "\n"; | 516 Str << "\n"; |
542 } | 517 } |
543 // Dump each instruction. | 518 // Dump each instruction. |
544 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 519 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
545 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; | 520 for (InstPhi *I : Phis) |
546 ++I) { | 521 I->dumpDecorated(Func); |
547 const Inst *Inst = *I; | 522 for (Inst *I : Insts) |
548 Inst->dumpDecorated(Func); | 523 I->dumpDecorated(Func); |
549 } | |
550 InstList::const_iterator I = Insts.begin(), E = Insts.end(); | |
551 while (I != E) { | |
552 Inst *Inst = *I++; | |
553 Inst->dumpDecorated(Func); | |
554 } | |
555 } | 524 } |
556 // Dump the live-out variables. | 525 // Dump the live-out variables. |
557 llvm::BitVector LiveOut; | 526 llvm::BitVector LiveOut; |
558 if (Liveness) | 527 if (Liveness) |
559 LiveOut = Liveness->getLiveOut(this); | 528 LiveOut = Liveness->getLiveOut(this); |
560 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { | 529 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { |
561 Str << " // LiveOut:"; | 530 Str << " // LiveOut:"; |
562 for (SizeT i = 0; i < LiveOut.size(); ++i) { | 531 for (SizeT i = 0; i < LiveOut.size(); ++i) { |
563 if (LiveOut[i]) { | 532 if (LiveOut[i]) { |
564 Str << " %" << Liveness->getVariable(i, this)->getName(); | 533 Str << " %" << Liveness->getVariable(i, this)->getName(); |
565 } | 534 } |
566 } | 535 } |
567 Str << "\n"; | 536 Str << "\n"; |
568 } | 537 } |
569 // Dump list of successor nodes. | 538 // Dump list of successor nodes. |
570 if (Func->getContext()->isVerbose(IceV_Succs)) { | 539 if (Func->getContext()->isVerbose(IceV_Succs)) { |
571 Str << " // succs = "; | 540 Str << " // succs = "; |
572 for (NodeList::const_iterator I = OutEdges.begin(), E = OutEdges.end(); | 541 bool First = true; |
573 I != E; ++I) { | 542 for (CfgNode *I : OutEdges) { |
574 if (I != OutEdges.begin()) | 543 if (First) |
575 Str << ", "; | 544 Str << ", "; |
576 Str << "%" << (*I)->getName(); | 545 First = false; |
| 546 Str << "%" << I->getName(); |
577 } | 547 } |
578 Str << "\n"; | 548 Str << "\n"; |
579 } | 549 } |
580 } | 550 } |
581 | 551 |
582 } // end of namespace Ice | 552 } // end of namespace Ice |
OLD | NEW |