| OLD | NEW |
| 1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// | 1 //===- subzero/src/IceCfg.cpp - Control flow graph 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 Cfg class, including constant pool | 10 // This file implements the Cfg class, including constant pool |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 Var->dump(this); | 358 Var->dump(this); |
| 359 Str << " live range " << Var->getLiveRange() << "\n"; | 359 Str << " live range " << Var->getLiveRange() << "\n"; |
| 360 } | 360 } |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 return Valid; | 365 return Valid; |
| 366 } | 366 } |
| 367 | 367 |
| 368 // Deletes redundant assignments like "var=var". This includes | |
| 369 // architecturally redundant moves like "var1:eax=var2:eax". As such, | |
| 370 // this needs to be done very late in the translation to avoid | |
| 371 // liveness inconsistencies. | |
| 372 void Cfg::deleteRedundantAssignments() { | |
| 373 for (CfgNode *Node : Nodes) { | |
| 374 // Ignore Phi instructions. | |
| 375 for (Inst *I : Node->getInsts()) | |
| 376 if (I->isRedundantAssign()) | |
| 377 I->setDeleted(); | |
| 378 } | |
| 379 } | |
| 380 | |
| 381 void Cfg::contractEmptyNodes() { | 368 void Cfg::contractEmptyNodes() { |
| 369 // If we're decorating the asm output with register liveness info, |
| 370 // this information may become corrupted or incorrect after |
| 371 // contracting nodes that contain only redundant assignments. As |
| 372 // such, we disable this pass when DecorateAsm is specified. This |
| 373 // may make the resulting code look more branchy, but it should have |
| 374 // no effect on the register assignments. |
| 375 if (Ctx->getFlags().DecorateAsm) |
| 376 return; |
| 382 for (CfgNode *Node : Nodes) { | 377 for (CfgNode *Node : Nodes) { |
| 383 Node->contractIfEmpty(); | 378 Node->contractIfEmpty(); |
| 384 } | 379 } |
| 385 } | 380 } |
| 386 | 381 |
| 387 void Cfg::doBranchOpt() { | 382 void Cfg::doBranchOpt() { |
| 388 TimerMarker T(TimerStack::TT_doBranchOpt, this); | 383 TimerMarker T(TimerStack::TT_doBranchOpt, this); |
| 389 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 384 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 390 auto NextNode = I; | 385 auto NextNode = I; |
| 391 ++NextNode; | 386 ++NextNode; |
| 392 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); | 387 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); |
| 393 } | 388 } |
| 394 } | 389 } |
| 395 | 390 |
| 396 // ======================== Dump routines ======================== // | 391 // ======================== Dump routines ======================== // |
| 397 | 392 |
| 398 void Cfg::emit() { | 393 void Cfg::emit() { |
| 399 TimerMarker T(TimerStack::TT_emit, this); | 394 TimerMarker T(TimerStack::TT_emit, this); |
| 395 if (Ctx->getFlags().DecorateAsm) { |
| 396 renumberInstructions(); |
| 397 getVMetadata()->init(VMK_Uses); |
| 398 liveness(Liveness_Basic); |
| 399 dump("After recomputing liveness for -decorate-asm"); |
| 400 } |
| 400 Ostream &Str = Ctx->getStrEmit(); | 401 Ostream &Str = Ctx->getStrEmit(); |
| 401 if (!Ctx->testAndSetHasEmittedFirstMethod()) { | 402 if (!Ctx->testAndSetHasEmittedFirstMethod()) { |
| 402 // Print a helpful command for assembling the output. | 403 // Print a helpful command for assembling the output. |
| 403 // TODO: have the Target emit the header | 404 // TODO: have the Target emit the header |
| 404 // TODO: need a per-file emit in addition to per-CFG | 405 // TODO: need a per-file emit in addition to per-CFG |
| 405 Str << "# $LLVM_BIN_PATH/llvm-mc" | 406 Str << "# $LLVM_BIN_PATH/llvm-mc" |
| 406 << " -arch=x86" | 407 << " -arch=x86" |
| 407 << " -x86-asm-syntax=intel" | 408 << " -x86-asm-syntax=intel" |
| 408 << " -filetype=obj" | 409 << " -filetype=obj" |
| 409 << " -o=MyObj.o" | 410 << " -o=MyObj.o" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 } | 464 } |
| 464 } | 465 } |
| 465 // Print each basic block | 466 // Print each basic block |
| 466 for (CfgNode *Node : Nodes) | 467 for (CfgNode *Node : Nodes) |
| 467 Node->dump(this); | 468 Node->dump(this); |
| 468 if (getContext()->isVerbose(IceV_Instructions)) | 469 if (getContext()->isVerbose(IceV_Instructions)) |
| 469 Str << "}\n"; | 470 Str << "}\n"; |
| 470 } | 471 } |
| 471 | 472 |
| 472 } // end of namespace Ice | 473 } // end of namespace Ice |
| OLD | NEW |