Chromium Code Reviews| 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 14 matching lines...) Expand all Loading... | |
| 25 | 25 |
| 26 namespace Ice { | 26 namespace Ice { |
| 27 | 27 |
| 28 thread_local const Cfg *Cfg::CurrentCfg = nullptr; | 28 thread_local const Cfg *Cfg::CurrentCfg = nullptr; |
| 29 | 29 |
| 30 ArenaAllocator<> *getCurrentCfgAllocator() { | 30 ArenaAllocator<> *getCurrentCfgAllocator() { |
| 31 return Cfg::getCurrentCfgAllocator(); | 31 return Cfg::getCurrentCfgAllocator(); |
| 32 } | 32 } |
| 33 | 33 |
| 34 Cfg::Cfg(GlobalContext *Ctx) | 34 Cfg::Cfg(GlobalContext *Ctx) |
| 35 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), | 35 : Ctx(Ctx), VMask(Ctx->getVerbose()), FunctionName(""), |
| 36 IsInternalLinkage(false), HasError(false), FocusedTiming(false), | 36 ReturnType(IceType_void), IsInternalLinkage(false), HasError(false), |
| 37 ErrorMessage(""), Entry(nullptr), NextInstNumber(Inst::NumberInitial), | 37 FocusedTiming(false), ErrorMessage(""), Entry(nullptr), |
| 38 Allocator(new ArenaAllocator<>()), Live(nullptr), | 38 NextInstNumber(Inst::NumberInitial), Allocator(new ArenaAllocator<>()), |
| 39 Live(nullptr), | |
| 39 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), | 40 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), |
| 40 VMetadata(new VariablesMetadata(this)), | 41 VMetadata(new VariablesMetadata(this)), |
| 41 TargetAssembler( | 42 TargetAssembler( |
| 42 TargetLowering::createAssembler(Ctx->getTargetArch(), this)), | 43 TargetLowering::createAssembler(Ctx->getTargetArch(), this)), |
| 43 CurrentNode(nullptr) { | 44 CurrentNode(nullptr) { |
| 44 assert(!Ctx->isIRGenerationDisabled() && | 45 assert(!Ctx->isIRGenerationDisabled() && |
| 45 "Attempt to build cfg when IR generation disabled"); | 46 "Attempt to build cfg when IR generation disabled"); |
| 46 } | 47 } |
| 47 | 48 |
| 48 Cfg::~Cfg() { | 49 Cfg::~Cfg() { CurrentCfg = nullptr; } |
|
JF
2015/01/22 20:50:56
Comment that this is TLS.
Jim Stichnoth
2015/01/23 07:55:54
Done.
| |
| 49 // TODO(stichnot,kschimpf): Set CurrentCfg=nullptr in the dtor for | |
| 50 // safety. This can't be done currently because the translator | |
| 51 // manages the Cfg by creating a new Cfg (which sets CurrentCfg to | |
| 52 // the new value), then deleting the old Cfg (which would then reset | |
| 53 // CurrentCfg to nullptr). | |
| 54 } | |
| 55 | 50 |
| 56 void Cfg::setError(const IceString &Message) { | 51 void Cfg::setError(const IceString &Message) { |
| 57 HasError = true; | 52 HasError = true; |
| 58 ErrorMessage = Message; | 53 ErrorMessage = Message; |
| 59 OstreamLocker L(Ctx); | |
| 60 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n"; | |
| 61 } | 54 } |
| 62 | 55 |
| 63 CfgNode *Cfg::makeNode() { | 56 CfgNode *Cfg::makeNode() { |
| 64 SizeT LabelIndex = Nodes.size(); | 57 SizeT LabelIndex = Nodes.size(); |
| 65 CfgNode *Node = CfgNode::create(this, LabelIndex); | 58 CfgNode *Node = CfgNode::create(this, LabelIndex); |
| 66 Nodes.push_back(Node); | 59 Nodes.push_back(Node); |
| 67 return Node; | 60 return Node; |
| 68 } | 61 } |
| 69 | 62 |
| 70 void Cfg::addArg(Variable *Arg) { | 63 void Cfg::addArg(Variable *Arg) { |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 471 OstreamLocker L(Ctx); | 464 OstreamLocker L(Ctx); |
| 472 emitTextHeader(MangledName); | 465 emitTextHeader(MangledName); |
| 473 getAssembler<Assembler>()->emitIASBytes(Ctx); | 466 getAssembler<Assembler>()->emitIASBytes(Ctx); |
| 474 } | 467 } |
| 475 } | 468 } |
| 476 | 469 |
| 477 // Dumps the IR with an optional introductory message. | 470 // Dumps the IR with an optional introductory message. |
| 478 void Cfg::dump(const IceString &Message) { | 471 void Cfg::dump(const IceString &Message) { |
| 479 if (!ALLOW_DUMP) | 472 if (!ALLOW_DUMP) |
| 480 return; | 473 return; |
| 481 if (!Ctx->isVerbose()) | 474 if (!isVerbose()) |
| 482 return; | 475 return; |
| 483 OstreamLocker L(Ctx); | 476 OstreamLocker L(Ctx); |
| 484 Ostream &Str = Ctx->getStrDump(); | 477 Ostream &Str = Ctx->getStrDump(); |
| 485 if (!Message.empty()) | 478 if (!Message.empty()) |
| 486 Str << "================ " << Message << " ================\n"; | 479 Str << "================ " << Message << " ================\n"; |
| 487 setCurrentNode(getEntryNode()); | 480 setCurrentNode(getEntryNode()); |
| 488 // Print function name+args | 481 // Print function name+args |
| 489 if (getContext()->isVerbose(IceV_Instructions)) { | 482 if (isVerbose(IceV_Instructions)) { |
| 490 Str << "define "; | 483 Str << "define "; |
| 491 if (getInternal() && !Ctx->getFlags().DisableInternal) | 484 if (getInternal() && !Ctx->getFlags().DisableInternal) |
| 492 Str << "internal "; | 485 Str << "internal "; |
| 493 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "("; | 486 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "("; |
| 494 for (SizeT i = 0; i < Args.size(); ++i) { | 487 for (SizeT i = 0; i < Args.size(); ++i) { |
| 495 if (i > 0) | 488 if (i > 0) |
| 496 Str << ", "; | 489 Str << ", "; |
| 497 Str << Args[i]->getType() << " "; | 490 Str << Args[i]->getType() << " "; |
| 498 Args[i]->dump(this); | 491 Args[i]->dump(this); |
| 499 } | 492 } |
| 500 Str << ") {\n"; | 493 Str << ") {\n"; |
| 501 } | 494 } |
| 502 resetCurrentNode(); | 495 resetCurrentNode(); |
| 503 if (getContext()->isVerbose(IceV_Liveness)) { | 496 if (isVerbose(IceV_Liveness)) { |
| 504 // Print summary info about variables | 497 // Print summary info about variables |
| 505 for (Variable *Var : Variables) { | 498 for (Variable *Var : Variables) { |
| 506 Str << "// multiblock="; | 499 Str << "// multiblock="; |
| 507 if (getVMetadata()->isTracked(Var)) | 500 if (getVMetadata()->isTracked(Var)) |
| 508 Str << getVMetadata()->isMultiBlock(Var); | 501 Str << getVMetadata()->isMultiBlock(Var); |
| 509 else | 502 else |
| 510 Str << "?"; | 503 Str << "?"; |
| 511 Str << " weight=" << Var->getWeight() << " "; | 504 Str << " weight=" << Var->getWeight() << " "; |
| 512 Var->dump(this); | 505 Var->dump(this); |
| 513 Str << " LIVE=" << Var->getLiveRange() << "\n"; | 506 Str << " LIVE=" << Var->getLiveRange() << "\n"; |
| 514 } | 507 } |
| 515 } | 508 } |
| 516 // Print each basic block | 509 // Print each basic block |
| 517 for (CfgNode *Node : Nodes) | 510 for (CfgNode *Node : Nodes) |
| 518 Node->dump(this); | 511 Node->dump(this); |
| 519 if (getContext()->isVerbose(IceV_Instructions)) | 512 if (isVerbose(IceV_Instructions)) |
| 520 Str << "}\n"; | 513 Str << "}\n"; |
| 521 } | 514 } |
| 522 | 515 |
| 523 } // end of namespace Ice | 516 } // end of namespace Ice |
| OLD | NEW |