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 |
11 // management. | 11 // management. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "IceCfg.h" | 15 #include "IceCfg.h" |
16 #include "IceCfgNode.h" | 16 #include "IceCfgNode.h" |
17 #include "IceDefs.h" | 17 #include "IceDefs.h" |
18 #include "IceInst.h" | 18 #include "IceInst.h" |
19 #include "IceOperand.h" | 19 #include "IceOperand.h" |
| 20 #include "IceTargetLowering.h" |
20 | 21 |
21 namespace Ice { | 22 namespace Ice { |
22 | 23 |
23 Cfg::Cfg(GlobalContext *Ctx) | 24 Cfg::Cfg(GlobalContext *Ctx) |
24 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), | 25 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), |
25 IsInternalLinkage(false), HasError(false), ErrorMessage(""), Entry(NULL), | 26 IsInternalLinkage(false), HasError(false), ErrorMessage(""), Entry(NULL), |
26 NextInstNumber(1), CurrentNode(NULL) {} | 27 NextInstNumber(1), |
| 28 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), |
| 29 CurrentNode(NULL) {} |
27 | 30 |
28 Cfg::~Cfg() {} | 31 Cfg::~Cfg() {} |
29 | 32 |
30 void Cfg::setError(const IceString &Message) { | 33 void Cfg::setError(const IceString &Message) { |
31 HasError = true; | 34 HasError = true; |
32 ErrorMessage = Message; | 35 ErrorMessage = Message; |
33 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n"; | 36 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n"; |
34 } | 37 } |
35 | 38 |
36 CfgNode *Cfg::makeNode(const IceString &Name) { | 39 CfgNode *Cfg::makeNode(const IceString &Name) { |
(...skipping 10 matching lines...) Expand all Loading... |
47 SizeT Index = Variables.size(); | 50 SizeT Index = Variables.size(); |
48 Variables.push_back(Variable::create(this, Ty, Node, Index, Name)); | 51 Variables.push_back(Variable::create(this, Ty, Node, Index, Name)); |
49 return Variables[Index]; | 52 return Variables[Index]; |
50 } | 53 } |
51 | 54 |
52 void Cfg::addArg(Variable *Arg) { | 55 void Cfg::addArg(Variable *Arg) { |
53 Arg->setIsArg(this); | 56 Arg->setIsArg(this); |
54 Args.push_back(Arg); | 57 Args.push_back(Arg); |
55 } | 58 } |
56 | 59 |
| 60 // Returns whether the stack frame layout has been computed yet. This |
| 61 // is used for dumping the stack frame location of Variables. |
| 62 bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); } |
| 63 |
| 64 void Cfg::translate() { |
| 65 Ostream &Str = Ctx->getStrDump(); |
| 66 if (hasError()) |
| 67 return; |
| 68 |
| 69 if (Ctx->isVerbose()) { |
| 70 Str << "================ Initial CFG ================\n"; |
| 71 dump(); |
| 72 } |
| 73 |
| 74 Timer T_translate; |
| 75 // The set of translation passes and their order are determined by |
| 76 // the target. |
| 77 getTarget()->translate(); |
| 78 T_translate.printElapsedUs(getContext(), "translate()"); |
| 79 |
| 80 if (Ctx->isVerbose()) { |
| 81 Str << "================ Final output ================\n"; |
| 82 dump(); |
| 83 } |
| 84 } |
| 85 |
57 void Cfg::computePredecessors() { | 86 void Cfg::computePredecessors() { |
58 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 87 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
59 (*I)->computePredecessors(); | 88 (*I)->computePredecessors(); |
60 } | 89 } |
61 } | 90 } |
62 | 91 |
| 92 // placePhiLoads() must be called before placePhiStores(). |
| 93 void Cfg::placePhiLoads() { |
| 94 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 95 (*I)->placePhiLoads(); |
| 96 } |
| 97 } |
| 98 |
| 99 // placePhiStores() must be called after placePhiLoads(). |
| 100 void Cfg::placePhiStores() { |
| 101 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 102 (*I)->placePhiStores(); |
| 103 } |
| 104 } |
| 105 |
| 106 void Cfg::deletePhis() { |
| 107 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 108 (*I)->deletePhis(); |
| 109 } |
| 110 } |
| 111 |
| 112 void Cfg::genCode() { |
| 113 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 114 (*I)->genCode(); |
| 115 } |
| 116 } |
| 117 |
| 118 // Compute the stack frame layout. |
| 119 void Cfg::genFrame() { |
| 120 getTarget()->addProlog(Entry); |
| 121 // TODO: Consider folding epilog generation into the final |
| 122 // emission/assembly pass to avoid an extra iteration over the node |
| 123 // list. Or keep a separate list of exit nodes. |
| 124 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 125 CfgNode *Node = *I; |
| 126 if (Node->getHasReturn()) |
| 127 getTarget()->addEpilog(Node); |
| 128 } |
| 129 } |
| 130 |
63 // ======================== Dump routines ======================== // | 131 // ======================== Dump routines ======================== // |
64 | 132 |
| 133 void Cfg::emit() { |
| 134 Ostream &Str = Ctx->getStrEmit(); |
| 135 Timer T_emit; |
| 136 if (!Ctx->testAndSetHasEmittedFirstMethod()) { |
| 137 // Print a helpful command for assembling the output. |
| 138 // TODO: have the Target emit the header |
| 139 // TODO: need a per-file emit in addition to per-CFG |
| 140 Str << "# $LLVM_BIN_PATH/llvm-mc" |
| 141 << " -arch=x86" |
| 142 << " -x86-asm-syntax=intel" |
| 143 << " -filetype=obj" |
| 144 << " -o=MyObj.o" |
| 145 << "\n\n"; |
| 146 } |
| 147 Str << "\t.text\n"; |
| 148 if (!getInternal()) { |
| 149 IceString MangledName = getContext()->mangleName(getFunctionName()); |
| 150 Str << "\t.globl\t" << MangledName << "\n"; |
| 151 Str << "\t.type\t" << MangledName << ",@function\n"; |
| 152 } |
| 153 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; |
| 154 ++I) { |
| 155 (*I)->emit(this); |
| 156 } |
| 157 Str << "\n"; |
| 158 T_emit.printElapsedUs(Ctx, "emit()"); |
| 159 } |
| 160 |
65 void Cfg::dump() { | 161 void Cfg::dump() { |
66 Ostream &Str = Ctx->getStrDump(); | 162 Ostream &Str = Ctx->getStrDump(); |
67 setCurrentNode(getEntryNode()); | 163 setCurrentNode(getEntryNode()); |
68 // Print function name+args | 164 // Print function name+args |
69 if (getContext()->isVerbose(IceV_Instructions)) { | 165 if (getContext()->isVerbose(IceV_Instructions)) { |
70 Str << "define "; | 166 Str << "define "; |
71 if (getInternal()) | 167 if (getInternal()) |
72 Str << "internal "; | 168 Str << "internal "; |
73 Str << ReturnType << " @" << getFunctionName() << "("; | 169 Str << ReturnType << " @" << getFunctionName() << "("; |
74 for (SizeT i = 0; i < Args.size(); ++i) { | 170 for (SizeT i = 0; i < Args.size(); ++i) { |
75 if (i > 0) | 171 if (i > 0) |
76 Str << ", "; | 172 Str << ", "; |
77 Str << Args[i]->getType() << " "; | 173 Str << Args[i]->getType() << " "; |
78 Args[i]->dump(this); | 174 Args[i]->dump(this); |
79 } | 175 } |
80 Str << ") {\n"; | 176 Str << ") {\n"; |
81 } | 177 } |
82 setCurrentNode(NULL); | 178 setCurrentNode(NULL); |
83 // Print each basic block | 179 // Print each basic block |
84 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; | 180 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; |
85 ++I) { | 181 ++I) { |
86 (*I)->dump(this); | 182 (*I)->dump(this); |
87 } | 183 } |
88 if (getContext()->isVerbose(IceV_Instructions)) { | 184 if (getContext()->isVerbose(IceV_Instructions)) { |
89 Str << "}\n"; | 185 Str << "}\n"; |
90 } | 186 } |
91 } | 187 } |
92 | 188 |
93 } // end of namespace Ice | 189 } // end of namespace Ice |
OLD | NEW |