| 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 (auto &I : Phis) |
| 59 (*I)->renumber(Func); | 59 I->renumber(Func); |
| 60 } | 60 for (auto &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 (auto &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 (auto &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 (auto &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 (auto &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 (auto &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 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 271 I != E; ++I) { | |
| 272 if ((*I)->isDeleted()) | 257 if ((*I)->isDeleted()) |
| 273 continue; | 258 continue; |
| 274 (*I)->livenessLightweight(Func, Live); | 259 (*I)->livenessLightweight(Func, Live); |
| 275 } | 260 } |
| 276 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 261 for (auto &I : Phis) { |
| 277 if ((*I)->isDeleted()) | 262 if (I->isDeleted()) |
| 278 continue; | 263 continue; |
| 279 (*I)->livenessLightweight(Func, Live); | 264 I->livenessLightweight(Func, Live); |
| 280 } | 265 } |
| 281 } | 266 } |
| 282 | 267 |
| 283 // Performs liveness analysis on the block. Returns true if the | 268 // Performs liveness analysis on the block. Returns true if the |
| 284 // incoming liveness changed from before, false if it stayed the same. | 269 // incoming liveness changed from before, false if it stayed the same. |
| 285 // (If it changes, the node's predecessors need to be processed | 270 // (If it changes, the node's predecessors need to be processed |
| 286 // again.) | 271 // again.) |
| 287 bool CfgNode::liveness(Liveness *Liveness) { | 272 bool CfgNode::liveness(Liveness *Liveness) { |
| 288 SizeT NumVars = Liveness->getNumVarsInNode(this); | 273 SizeT NumVars = Liveness->getNumVarsInNode(this); |
| 289 llvm::BitVector Live(NumVars); | 274 llvm::BitVector Live(NumVars); |
| 290 // Mark the beginning and ending of each variable's live range | 275 // Mark the beginning and ending of each variable's live range |
| 291 // with the sentinel instruction number 0. | 276 // with the sentinel instruction number 0. |
| 292 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); | 277 std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(this); |
| 293 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); | 278 std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(this); |
| 294 InstNumberT Sentinel = Inst::NumberSentinel; | 279 InstNumberT Sentinel = Inst::NumberSentinel; |
| 295 LiveBegin.assign(NumVars, Sentinel); | 280 LiveBegin.assign(NumVars, Sentinel); |
| 296 LiveEnd.assign(NumVars, Sentinel); | 281 LiveEnd.assign(NumVars, Sentinel); |
| 297 // Initialize Live to be the union of all successors' LiveIn. | 282 // Initialize Live to be the union of all successors' LiveIn. |
| 298 for (NodeList::const_iterator I = OutEdges.begin(), E = OutEdges.end(); | 283 for (auto &Succ : OutEdges) { |
| 299 I != E; ++I) { | |
| 300 CfgNode *Succ = *I; | |
| 301 Live |= Liveness->getLiveIn(Succ); | 284 Live |= Liveness->getLiveIn(Succ); |
| 302 // Mark corresponding argument of phis in successor as live. | 285 // Mark corresponding argument of phis in successor as live. |
| 303 for (PhiList::const_iterator I1 = Succ->Phis.begin(), E1 = Succ->Phis.end(); | 286 for (auto &I : Succ->Phis) |
| 304 I1 != E1; ++I1) { | 287 I->livenessPhiOperand(Live, this, Liveness); |
| 305 (*I1)->livenessPhiOperand(Live, this, Liveness); | |
| 306 } | |
| 307 } | 288 } |
| 308 Liveness->getLiveOut(this) = Live; | 289 Liveness->getLiveOut(this) = Live; |
| 309 | 290 |
| 310 // Process regular instructions in reverse order. | 291 // Process regular instructions in reverse order. |
| 311 for (InstList::const_reverse_iterator I = Insts.rbegin(), E = Insts.rend(); | 292 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 312 I != E; ++I) { | |
| 313 if ((*I)->isDeleted()) | 293 if ((*I)->isDeleted()) |
| 314 continue; | 294 continue; |
| 315 (*I)->liveness((*I)->getNumber(), Live, Liveness, this); | 295 (*I)->liveness((*I)->getNumber(), Live, Liveness, this); |
| 316 } | 296 } |
| 317 // Process phis in forward order so that we can override the | 297 // Process phis in forward order so that we can override the |
| 318 // instruction number to be that of the earliest phi instruction in | 298 // instruction number to be that of the earliest phi instruction in |
| 319 // the block. | 299 // the block. |
| 320 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 300 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
| 321 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 301 for (auto &I : Phis) { |
| 322 if ((*I)->isDeleted()) | 302 if (I->isDeleted()) |
| 323 continue; | 303 continue; |
| 324 if (FirstPhiNumber == Inst::NumberSentinel) | 304 if (FirstPhiNumber == Inst::NumberSentinel) |
| 325 FirstPhiNumber = (*I)->getNumber(); | 305 FirstPhiNumber = I->getNumber(); |
| 326 (*I)->liveness(FirstPhiNumber, Live, Liveness, this); | 306 I->liveness(FirstPhiNumber, Live, Liveness, this); |
| 327 } | 307 } |
| 328 | 308 |
| 329 // When using the sparse representation, after traversing the | 309 // When using the sparse representation, after traversing the |
| 330 // instructions in the block, the Live bitvector should only contain | 310 // instructions in the block, the Live bitvector should only contain |
| 331 // set bits for global variables upon block entry. We validate this | 311 // set bits for global variables upon block entry. We validate this |
| 332 // by shrinking the Live vector and then testing it against the | 312 // by shrinking the Live vector and then testing it against the |
| 333 // pre-shrunk version. (The shrinking is required, but the | 313 // pre-shrunk version. (The shrinking is required, but the |
| 334 // validation is not.) | 314 // validation is not.) |
| 335 llvm::BitVector LiveOrig = Live; | 315 llvm::BitVector LiveOrig = Live; |
| 336 Live.resize(Liveness->getNumGlobalVars()); | 316 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 | 349 // 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 | 350 // 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 | 351 // 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 | 352 // 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 | 353 // block, and there is a single read that ends the live in the basic |
| 374 // block that contained the actual phi instruction. | 354 // block that contained the actual phi instruction. |
| 375 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { | 355 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { |
| 376 InstNumberT FirstInstNum = Inst::NumberSentinel; | 356 InstNumberT FirstInstNum = Inst::NumberSentinel; |
| 377 InstNumberT LastInstNum = Inst::NumberSentinel; | 357 InstNumberT LastInstNum = Inst::NumberSentinel; |
| 378 // Process phis in any order. Process only Dest operands. | 358 // Process phis in any order. Process only Dest operands. |
| 379 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 359 for (auto &I : Phis) { |
| 380 InstPhi *Inst = *I; | 360 I->deleteIfDead(); |
| 381 Inst->deleteIfDead(); | 361 if (I->isDeleted()) |
| 382 if (Inst->isDeleted()) | |
| 383 continue; | 362 continue; |
| 384 if (FirstInstNum == Inst::NumberSentinel) | 363 if (FirstInstNum == Inst::NumberSentinel) |
| 385 FirstInstNum = Inst->getNumber(); | 364 FirstInstNum = I->getNumber(); |
| 386 assert(Inst->getNumber() > LastInstNum); | 365 assert(I->getNumber() > LastInstNum); |
| 387 LastInstNum = Inst->getNumber(); | 366 LastInstNum = I->getNumber(); |
| 388 } | 367 } |
| 389 // Process instructions | 368 // Process instructions |
| 390 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 369 for (auto &I : Insts) { |
| 391 ++I) { | 370 I->deleteIfDead(); |
| 392 Inst *Inst = *I; | 371 if (I->isDeleted()) |
| 393 Inst->deleteIfDead(); | |
| 394 if (Inst->isDeleted()) | |
| 395 continue; | 372 continue; |
| 396 if (FirstInstNum == Inst::NumberSentinel) | 373 if (FirstInstNum == Inst::NumberSentinel) |
| 397 FirstInstNum = Inst->getNumber(); | 374 FirstInstNum = I->getNumber(); |
| 398 assert(Inst->getNumber() > LastInstNum); | 375 assert(I->getNumber() > LastInstNum); |
| 399 LastInstNum = Inst->getNumber(); | 376 LastInstNum = I->getNumber(); |
| 400 // Create fake live ranges for a Kill instruction, but only if the | 377 // Create fake live ranges for a Kill instruction, but only if the |
| 401 // linked instruction is still alive. | 378 // linked instruction is still alive. |
| 402 if (Mode == Liveness_Intervals) { | 379 if (Mode == Liveness_Intervals) { |
| 403 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(Inst)) { | 380 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { |
| 404 if (!Kill->getLinked()->isDeleted()) { | 381 if (!Kill->getLinked()->isDeleted()) { |
| 405 SizeT NumSrcs = Inst->getSrcSize(); | 382 SizeT NumSrcs = I->getSrcSize(); |
| 406 for (SizeT i = 0; i < NumSrcs; ++i) { | 383 for (SizeT Src = 0; Src < NumSrcs; ++Src) { |
| 407 Variable *Var = llvm::cast<Variable>(Inst->getSrc(i)); | 384 Variable *Var = llvm::cast<Variable>(I->getSrc(Src)); |
| 408 InstNumberT InstNumber = Inst->getNumber(); | 385 InstNumberT InstNumber = I->getNumber(); |
| 409 Liveness->addLiveRange(Var, InstNumber, InstNumber, 1); | 386 Liveness->addLiveRange(Var, InstNumber, InstNumber, 1); |
| 410 } | 387 } |
| 411 } | 388 } |
| 412 } | 389 } |
| 413 } | 390 } |
| 414 } | 391 } |
| 415 if (Mode != Liveness_Intervals) | 392 if (Mode != Liveness_Intervals) |
| 416 return; | 393 return; |
| 417 | 394 |
| 418 SizeT NumVars = Liveness->getNumVarsInNode(this); | 395 SizeT NumVars = Liveness->getNumVarsInNode(this); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 447 } | 424 } |
| 448 } | 425 } |
| 449 | 426 |
| 450 void CfgNode::doBranchOpt(const CfgNode *NextNode) { | 427 void CfgNode::doBranchOpt(const CfgNode *NextNode) { |
| 451 TargetLowering *Target = Func->getTarget(); | 428 TargetLowering *Target = Func->getTarget(); |
| 452 // Check every instruction for a branch optimization opportunity. | 429 // Check every instruction for a branch optimization opportunity. |
| 453 // It may be more efficient to iterate in reverse and stop after the | 430 // It may be more efficient to iterate in reverse and stop after the |
| 454 // first opportunity, unless there is some target lowering where we | 431 // first opportunity, unless there is some target lowering where we |
| 455 // have the possibility of multiple such optimizations per block | 432 // have the possibility of multiple such optimizations per block |
| 456 // (currently not the case for x86 lowering). | 433 // (currently not the case for x86 lowering). |
| 457 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 434 for (auto &I : Insts) |
| 458 ++I) { | 435 Target->doBranchOpt(I, NextNode); |
| 459 Target->doBranchOpt(*I, NextNode); | |
| 460 } | |
| 461 } | 436 } |
| 462 | 437 |
| 463 // ======================== Dump routines ======================== // | 438 // ======================== Dump routines ======================== // |
| 464 | 439 |
| 465 void CfgNode::emit(Cfg *Func) const { | 440 void CfgNode::emit(Cfg *Func) const { |
| 466 Func->setCurrentNode(this); | 441 Func->setCurrentNode(this); |
| 467 Ostream &Str = Func->getContext()->getStrEmit(); | 442 Ostream &Str = Func->getContext()->getStrEmit(); |
| 468 if (Func->getEntryNode() == this) { | 443 if (Func->getEntryNode() == this) { |
| 469 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n"; | 444 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n"; |
| 470 } | 445 } |
| 471 Str << getAsmName() << ":\n"; | 446 Str << getAsmName() << ":\n"; |
| 472 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; ++I) { | 447 for (auto &Phi : Phis) { |
| 473 InstPhi *Phi = *I; | |
| 474 if (Phi->isDeleted()) | 448 if (Phi->isDeleted()) |
| 475 continue; | 449 continue; |
| 476 // Emitting a Phi instruction should cause an error. | 450 // Emitting a Phi instruction should cause an error. |
| 477 Inst *Instr = Phi; | 451 Inst *Instr = Phi; |
| 478 Instr->emit(Func); | 452 Instr->emit(Func); |
| 479 } | 453 } |
| 480 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | 454 for (auto &I : Insts) { |
| 481 ++I) { | 455 if (I->isDeleted()) |
| 482 Inst *Inst = *I; | |
| 483 if (Inst->isDeleted()) | |
| 484 continue; | 456 continue; |
| 485 // Here we detect redundant assignments like "mov eax, eax" and | 457 // Here we detect redundant assignments like "mov eax, eax" and |
| 486 // suppress them. | 458 // suppress them. |
| 487 if (Inst->isRedundantAssign()) | 459 if (I->isRedundantAssign()) |
| 488 continue; | 460 continue; |
| 489 if (Func->UseIntegratedAssembler()) { | 461 if (Func->UseIntegratedAssembler()) { |
| 490 (*I)->emitIAS(Func); | 462 I->emitIAS(Func); |
| 491 } else { | 463 } else { |
| 492 (*I)->emit(Func); | 464 I->emit(Func); |
| 493 } | 465 } |
| 494 // Update emitted instruction count, plus fill/spill count for | 466 // Update emitted instruction count, plus fill/spill count for |
| 495 // Variable operands without a physical register. | 467 // Variable operands without a physical register. |
| 496 if (uint32_t Count = (*I)->getEmitInstCount()) { | 468 if (uint32_t Count = I->getEmitInstCount()) { |
| 497 Func->getContext()->statsUpdateEmitted(Count); | 469 Func->getContext()->statsUpdateEmitted(Count); |
| 498 if (Variable *Dest = (*I)->getDest()) { | 470 if (Variable *Dest = I->getDest()) { |
| 499 if (!Dest->hasReg()) | 471 if (!Dest->hasReg()) |
| 500 Func->getContext()->statsUpdateFills(); | 472 Func->getContext()->statsUpdateFills(); |
| 501 } | 473 } |
| 502 for (SizeT S = 0; S < (*I)->getSrcSize(); ++S) { | 474 for (SizeT S = 0; S < I->getSrcSize(); ++S) { |
| 503 if (Variable *Src = llvm::dyn_cast<Variable>((*I)->getSrc(S))) { | 475 if (Variable *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) { |
| 504 if (!Src->hasReg()) | 476 if (!Src->hasReg()) |
| 505 Func->getContext()->statsUpdateSpills(); | 477 Func->getContext()->statsUpdateSpills(); |
| 506 } | 478 } |
| 507 } | 479 } |
| 508 } | 480 } |
| 509 } | 481 } |
| 510 } | 482 } |
| 511 | 483 |
| 512 void CfgNode::dump(Cfg *Func) const { | 484 void CfgNode::dump(Cfg *Func) const { |
| 513 Func->setCurrentNode(this); | 485 Func->setCurrentNode(this); |
| 514 Ostream &Str = Func->getContext()->getStrDump(); | 486 Ostream &Str = Func->getContext()->getStrDump(); |
| 515 Liveness *Liveness = Func->getLiveness(); | 487 Liveness *Liveness = Func->getLiveness(); |
| 516 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 488 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
| 517 Str << getName() << ":\n"; | 489 Str << getName() << ":\n"; |
| 518 } | 490 } |
| 519 // Dump list of predecessor nodes. | 491 // Dump list of predecessor nodes. |
| 520 if (Func->getContext()->isVerbose(IceV_Preds) && !InEdges.empty()) { | 492 if (Func->getContext()->isVerbose(IceV_Preds) && !InEdges.empty()) { |
| 521 Str << " // preds = "; | 493 Str << " // preds = "; |
| 522 for (NodeList::const_iterator I = InEdges.begin(), E = InEdges.end(); | 494 for (auto I = InEdges.begin(), E = InEdges.end(); I != E; ++I) { |
| 523 I != E; ++I) { | |
| 524 if (I != InEdges.begin()) | 495 if (I != InEdges.begin()) |
| 525 Str << ", "; | 496 Str << ", "; |
| 526 Str << "%" << (*I)->getName(); | 497 Str << "%" << (*I)->getName(); |
| 527 } | 498 } |
| 528 Str << "\n"; | 499 Str << "\n"; |
| 529 } | 500 } |
| 530 // Dump the live-in variables. | 501 // Dump the live-in variables. |
| 531 llvm::BitVector LiveIn; | 502 llvm::BitVector LiveIn; |
| 532 if (Liveness) | 503 if (Liveness) |
| 533 LiveIn = Liveness->getLiveIn(this); | 504 LiveIn = Liveness->getLiveIn(this); |
| 534 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) { | 505 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveIn.empty()) { |
| 535 Str << " // LiveIn:"; | 506 Str << " // LiveIn:"; |
| 536 for (SizeT i = 0; i < LiveIn.size(); ++i) { | 507 for (SizeT i = 0; i < LiveIn.size(); ++i) { |
| 537 if (LiveIn[i]) { | 508 if (LiveIn[i]) { |
| 538 Str << " %" << Liveness->getVariable(i, this)->getName(); | 509 Str << " %" << Liveness->getVariable(i, this)->getName(); |
| 539 } | 510 } |
| 540 } | 511 } |
| 541 Str << "\n"; | 512 Str << "\n"; |
| 542 } | 513 } |
| 543 // Dump each instruction. | 514 // Dump each instruction. |
| 544 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 515 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
| 545 for (PhiList::const_iterator I = Phis.begin(), E = Phis.end(); I != E; | 516 for (auto &I : Phis) |
| 546 ++I) { | 517 I->dumpDecorated(Func); |
| 547 const Inst *Inst = *I; | 518 for (auto &I : Insts) |
| 548 Inst->dumpDecorated(Func); | 519 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 } | 520 } |
| 556 // Dump the live-out variables. | 521 // Dump the live-out variables. |
| 557 llvm::BitVector LiveOut; | 522 llvm::BitVector LiveOut; |
| 558 if (Liveness) | 523 if (Liveness) |
| 559 LiveOut = Liveness->getLiveOut(this); | 524 LiveOut = Liveness->getLiveOut(this); |
| 560 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { | 525 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { |
| 561 Str << " // LiveOut:"; | 526 Str << " // LiveOut:"; |
| 562 for (SizeT i = 0; i < LiveOut.size(); ++i) { | 527 for (SizeT i = 0; i < LiveOut.size(); ++i) { |
| 563 if (LiveOut[i]) { | 528 if (LiveOut[i]) { |
| 564 Str << " %" << Liveness->getVariable(i, this)->getName(); | 529 Str << " %" << Liveness->getVariable(i, this)->getName(); |
| 565 } | 530 } |
| 566 } | 531 } |
| 567 Str << "\n"; | 532 Str << "\n"; |
| 568 } | 533 } |
| 569 // Dump list of successor nodes. | 534 // Dump list of successor nodes. |
| 570 if (Func->getContext()->isVerbose(IceV_Succs)) { | 535 if (Func->getContext()->isVerbose(IceV_Succs)) { |
| 571 Str << " // succs = "; | 536 Str << " // succs = "; |
| 572 for (NodeList::const_iterator I = OutEdges.begin(), E = OutEdges.end(); | 537 for (auto I = OutEdges.begin(), E = OutEdges.end(); I != E; ++I) { |
| 573 I != E; ++I) { | |
| 574 if (I != OutEdges.begin()) | 538 if (I != OutEdges.begin()) |
| 575 Str << ", "; | 539 Str << ", "; |
| 576 Str << "%" << (*I)->getName(); | 540 Str << "%" << (*I)->getName(); |
| 577 } | 541 } |
| 578 Str << "\n"; | 542 Str << "\n"; |
| 579 } | 543 } |
| 580 } | 544 } |
| 581 | 545 |
| 582 } // end of namespace Ice | 546 } // end of namespace Ice |
| OLD | NEW |