Chromium Code Reviews| Index: src/IceCfg.cpp |
| diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp |
| index f2b1cc9df9c9aa297c97000a5711c894a85b7246..90ffbf9477e44567c055d0a75db3dbd32120300f 100644 |
| --- a/src/IceCfg.cpp |
| +++ b/src/IceCfg.cpp |
| @@ -17,13 +17,16 @@ |
| #include "IceDefs.h" |
| #include "IceInst.h" |
| #include "IceOperand.h" |
| +#include "IceTargetLowering.h" |
| namespace Ice { |
| Cfg::Cfg(GlobalContext *Ctx) |
| : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), |
| IsInternalLinkage(false), HasError(false), ErrorMessage(""), Entry(NULL), |
| - NextInstNumber(1), CurrentNode(NULL) {} |
| + NextInstNumber(1), |
| + Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), |
| + CurrentNode(NULL) {} |
| Cfg::~Cfg() {} |
| @@ -54,14 +57,105 @@ void Cfg::addArg(Variable *Arg) { |
| Args.push_back(Arg); |
| } |
| +// Returns whether the stack frame layout has been computed yet. This |
| +// is used for dumping the stack frame location of Variables. |
| +bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); } |
| + |
| +void Cfg::translate() { |
| + Ostream &Str = Ctx->getStrDump(); |
| + if (hasError()) |
| + return; |
| + |
| + if (Ctx->isVerbose()) |
| + Str << "================ Initial CFG ================\n"; |
| + dump(); |
|
jvoung (off chromium)
2014/05/15 23:47:34
Is the dump() meant to be within the isVerbose() t
Jim Stichnoth
2014/05/17 14:14:32
It was intentional, but it looks like a good idea
|
| + |
| + Timer T_translate; |
| + // The set of translation passes and their order are determined by |
| + // the target. |
| + getTarget()->translate(); |
| + T_translate.printElapsedUs(getContext(), "translate()"); |
| + |
| + if (Ctx->isVerbose()) |
| + Str << "================ Final output ================\n"; |
| + dump(); |
| +} |
| + |
| void Cfg::computePredecessors() { |
| for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| (*I)->computePredecessors(); |
| } |
| } |
| +// placePhiLoads() must be called before placePhiStores(). |
| +void Cfg::placePhiLoads() { |
| + for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| + (*I)->placePhiLoads(); |
| + } |
| +} |
| + |
| +// placePhiStores() must be called after placePhiLoads(). |
| +void Cfg::placePhiStores() { |
| + for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| + (*I)->placePhiStores(); |
| + } |
| +} |
| + |
| +void Cfg::deletePhis() { |
| + for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| + (*I)->deletePhis(); |
| + } |
| +} |
| + |
| +void Cfg::genCode() { |
| + for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| + (*I)->genCode(); |
| + } |
| +} |
| + |
| +// Compute the stack frame layout. |
| +void Cfg::genFrame() { |
| + getTarget()->addProlog(Entry); |
| + // TODO: Consider folding epilog generation into the final |
| + // emission/assembly pass to avoid an extra iteration over the node |
| + // list. Or keep a separate list of exit nodes. |
| + for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| + CfgNode *Node = *I; |
| + if (Node->getHasReturn()) |
| + getTarget()->addEpilog(Node); |
| + } |
| +} |
| + |
| // ======================== Dump routines ======================== // |
| +void Cfg::emit() { |
| + Ostream &Str = Ctx->getStrEmit(); |
| + Timer T_emit; |
| + if (!Ctx->testAndSetHasEmittedFirstMethod()) { |
| + // Print a helpful command for assembling the output. |
| + // TODO: have the Target emit the header |
| + // TODO: need a per-file emit in addition to per-CFG |
| + Str << "# $LLVM_BIN_PATH/llvm-mc" |
| + << " -arch=x86" |
| + << " -x86-asm-syntax=intel" |
| + << " -filetype=obj" |
| + << " -o=MyObj.o" |
| + << "\n\n"; |
| + } |
| + Str << "\t.text\n"; |
| + if (!getInternal()) { |
| + IceString MangledName = getContext()->mangleName(getFunctionName()); |
| + Str << "\t.globl\t" << MangledName << "\n"; |
| + Str << "\t.type\t" << MangledName << ",@function\n"; |
| + } |
| + for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; |
| + ++I) { |
| + (*I)->emit(this); |
| + } |
| + Str << "\n"; |
| + T_emit.printElapsedUs(Ctx, "emit()"); |
| +} |
| + |
| void Cfg::dump() { |
| Ostream &Str = Ctx->getStrDump(); |
| setCurrentNode(getEntryNode()); |