| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 dump("Initial CFG"); | 75 dump("Initial CFG"); |
| 76 | 76 |
| 77 // The set of translation passes and their order are determined by | 77 // The set of translation passes and their order are determined by |
| 78 // the target. | 78 // the target. |
| 79 getTarget()->translate(); | 79 getTarget()->translate(); |
| 80 | 80 |
| 81 dump("Final output"); | 81 dump("Final output"); |
| 82 } | 82 } |
| 83 | 83 |
| 84 void Cfg::computePredecessors() { | 84 void Cfg::computePredecessors() { |
| 85 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 85 for (CfgNode *Node : Nodes) |
| 86 (*I)->computePredecessors(); | 86 Node->computePredecessors(); |
| 87 } | |
| 88 } | 87 } |
| 89 | 88 |
| 90 void Cfg::renumberInstructions() { | 89 void Cfg::renumberInstructions() { |
| 91 static TimerIdT IDrenumberInstructions = | 90 static TimerIdT IDrenumberInstructions = |
| 92 GlobalContext::getTimerID("renumberInstructions"); | 91 GlobalContext::getTimerID("renumberInstructions"); |
| 93 TimerMarker T(IDrenumberInstructions, getContext()); | 92 TimerMarker T(IDrenumberInstructions, getContext()); |
| 94 NextInstNumber = 1; | 93 NextInstNumber = 1; |
| 95 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 94 for (CfgNode *Node : Nodes) |
| 96 (*I)->renumberInstructions(); | 95 Node->renumberInstructions(); |
| 97 } | |
| 98 } | 96 } |
| 99 | 97 |
| 100 // placePhiLoads() must be called before placePhiStores(). | 98 // placePhiLoads() must be called before placePhiStores(). |
| 101 void Cfg::placePhiLoads() { | 99 void Cfg::placePhiLoads() { |
| 102 static TimerIdT IDplacePhiLoads = GlobalContext::getTimerID("placePhiLoads"); | 100 static TimerIdT IDplacePhiLoads = GlobalContext::getTimerID("placePhiLoads"); |
| 103 TimerMarker T(IDplacePhiLoads, getContext()); | 101 TimerMarker T(IDplacePhiLoads, getContext()); |
| 104 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 102 for (CfgNode *Node : Nodes) |
| 105 (*I)->placePhiLoads(); | 103 Node->placePhiLoads(); |
| 106 } | |
| 107 } | 104 } |
| 108 | 105 |
| 109 // placePhiStores() must be called after placePhiLoads(). | 106 // placePhiStores() must be called after placePhiLoads(). |
| 110 void Cfg::placePhiStores() { | 107 void Cfg::placePhiStores() { |
| 111 static TimerIdT IDplacePhiStores = | 108 static TimerIdT IDplacePhiStores = |
| 112 GlobalContext::getTimerID("placePhiStores"); | 109 GlobalContext::getTimerID("placePhiStores"); |
| 113 TimerMarker T(IDplacePhiStores, getContext()); | 110 TimerMarker T(IDplacePhiStores, getContext()); |
| 114 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 111 for (CfgNode *Node : Nodes) |
| 115 (*I)->placePhiStores(); | 112 Node->placePhiStores(); |
| 116 } | |
| 117 } | 113 } |
| 118 | 114 |
| 119 void Cfg::deletePhis() { | 115 void Cfg::deletePhis() { |
| 120 static TimerIdT IDdeletePhis = GlobalContext::getTimerID("deletePhis"); | 116 static TimerIdT IDdeletePhis = GlobalContext::getTimerID("deletePhis"); |
| 121 TimerMarker T(IDdeletePhis, getContext()); | 117 TimerMarker T(IDdeletePhis, getContext()); |
| 122 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 118 for (CfgNode *Node : Nodes) |
| 123 (*I)->deletePhis(); | 119 Node->deletePhis(); |
| 124 } | |
| 125 } | 120 } |
| 126 | 121 |
| 127 void Cfg::doArgLowering() { | 122 void Cfg::doArgLowering() { |
| 128 static TimerIdT IDdoArgLowering = GlobalContext::getTimerID("doArgLowering"); | 123 static TimerIdT IDdoArgLowering = GlobalContext::getTimerID("doArgLowering"); |
| 129 TimerMarker T(IDdoArgLowering, getContext()); | 124 TimerMarker T(IDdoArgLowering, getContext()); |
| 130 getTarget()->lowerArguments(); | 125 getTarget()->lowerArguments(); |
| 131 } | 126 } |
| 132 | 127 |
| 133 void Cfg::doAddressOpt() { | 128 void Cfg::doAddressOpt() { |
| 134 static TimerIdT IDdoAddressOpt = GlobalContext::getTimerID("doAddressOpt"); | 129 static TimerIdT IDdoAddressOpt = GlobalContext::getTimerID("doAddressOpt"); |
| 135 TimerMarker T(IDdoAddressOpt, getContext()); | 130 TimerMarker T(IDdoAddressOpt, getContext()); |
| 136 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 131 for (CfgNode *Node : Nodes) |
| 137 (*I)->doAddressOpt(); | 132 Node->doAddressOpt(); |
| 138 } | |
| 139 } | 133 } |
| 140 | 134 |
| 141 void Cfg::doNopInsertion() { | 135 void Cfg::doNopInsertion() { |
| 142 static TimerIdT IDdoNopInsertion = | 136 static TimerIdT IDdoNopInsertion = |
| 143 GlobalContext::getTimerID("doNopInsertion"); | 137 GlobalContext::getTimerID("doNopInsertion"); |
| 144 TimerMarker T(IDdoNopInsertion, getContext()); | 138 TimerMarker T(IDdoNopInsertion, getContext()); |
| 145 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 139 for (CfgNode *Node : Nodes) |
| 146 (*I)->doNopInsertion(); | 140 Node->doNopInsertion(); |
| 147 } | |
| 148 } | 141 } |
| 149 | 142 |
| 150 void Cfg::genCode() { | 143 void Cfg::genCode() { |
| 151 static TimerIdT IDgenCode = GlobalContext::getTimerID("genCode"); | 144 static TimerIdT IDgenCode = GlobalContext::getTimerID("genCode"); |
| 152 TimerMarker T(IDgenCode, getContext()); | 145 TimerMarker T(IDgenCode, getContext()); |
| 153 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 146 for (CfgNode *Node : Nodes) |
| 154 (*I)->genCode(); | 147 Node->genCode(); |
| 155 } | |
| 156 } | 148 } |
| 157 | 149 |
| 158 // Compute the stack frame layout. | 150 // Compute the stack frame layout. |
| 159 void Cfg::genFrame() { | 151 void Cfg::genFrame() { |
| 160 static TimerIdT IDgenFrame = GlobalContext::getTimerID("genFrame"); | 152 static TimerIdT IDgenFrame = GlobalContext::getTimerID("genFrame"); |
| 161 TimerMarker T(IDgenFrame, getContext()); | 153 TimerMarker T(IDgenFrame, getContext()); |
| 162 getTarget()->addProlog(Entry); | 154 getTarget()->addProlog(Entry); |
| 163 // TODO: Consider folding epilog generation into the final | 155 // TODO: Consider folding epilog generation into the final |
| 164 // emission/assembly pass to avoid an extra iteration over the node | 156 // emission/assembly pass to avoid an extra iteration over the node |
| 165 // list. Or keep a separate list of exit nodes. | 157 // list. Or keep a separate list of exit nodes. |
| 166 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 158 for (CfgNode *Node : Nodes) |
| 167 CfgNode *Node = *I; | |
| 168 if (Node->getHasReturn()) | 159 if (Node->getHasReturn()) |
| 169 getTarget()->addEpilog(Node); | 160 getTarget()->addEpilog(Node); |
| 170 } | |
| 171 } | 161 } |
| 172 | 162 |
| 173 // This is a lightweight version of live-range-end calculation. Marks | 163 // This is a lightweight version of live-range-end calculation. Marks |
| 174 // the last use of only those variables whose definition and uses are | 164 // the last use of only those variables whose definition and uses are |
| 175 // completely with a single block. It is a quick single pass and | 165 // completely with a single block. It is a quick single pass and |
| 176 // doesn't need to iterate until convergence. | 166 // doesn't need to iterate until convergence. |
| 177 void Cfg::livenessLightweight() { | 167 void Cfg::livenessLightweight() { |
| 178 static TimerIdT IDlivenessLightweight = | 168 static TimerIdT IDlivenessLightweight = |
| 179 GlobalContext::getTimerID("livenessLightweight"); | 169 GlobalContext::getTimerID("livenessLightweight"); |
| 180 TimerMarker T(IDlivenessLightweight, getContext()); | 170 TimerMarker T(IDlivenessLightweight, getContext()); |
| 181 getVMetadata()->init(); | 171 getVMetadata()->init(); |
| 182 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 172 for (CfgNode *Node : Nodes) |
| 183 (*I)->livenessLightweight(); | 173 Node->livenessLightweight(); |
| 184 } | |
| 185 } | 174 } |
| 186 | 175 |
| 187 void Cfg::liveness(LivenessMode Mode) { | 176 void Cfg::liveness(LivenessMode Mode) { |
| 188 static TimerIdT IDliveness = GlobalContext::getTimerID("liveness"); | 177 static TimerIdT IDliveness = GlobalContext::getTimerID("liveness"); |
| 189 TimerMarker T(IDliveness, getContext()); | 178 TimerMarker T(IDliveness, getContext()); |
| 190 Live.reset(new Liveness(this, Mode)); | 179 Live.reset(new Liveness(this, Mode)); |
| 191 getVMetadata()->init(); | 180 getVMetadata()->init(); |
| 192 Live->init(); | 181 Live->init(); |
| 193 // Initialize with all nodes needing to be processed. | 182 // Initialize with all nodes needing to be processed. |
| 194 llvm::BitVector NeedToProcess(Nodes.size(), true); | 183 llvm::BitVector NeedToProcess(Nodes.size(), true); |
| 195 while (NeedToProcess.any()) { | 184 while (NeedToProcess.any()) { |
| 196 // Iterate in reverse topological order to speed up convergence. | 185 // Iterate in reverse topological order to speed up convergence. |
| 197 for (NodeList::reverse_iterator I = Nodes.rbegin(), E = Nodes.rend(); | 186 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
| 198 I != E; ++I) { | 187 for (auto I = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) { |
| 199 CfgNode *Node = *I; | 188 CfgNode *Node = *I; |
| 200 if (NeedToProcess[Node->getIndex()]) { | 189 if (NeedToProcess[Node->getIndex()]) { |
| 201 NeedToProcess[Node->getIndex()] = false; | 190 NeedToProcess[Node->getIndex()] = false; |
| 202 bool Changed = Node->liveness(getLiveness()); | 191 bool Changed = Node->liveness(getLiveness()); |
| 203 if (Changed) { | 192 if (Changed) { |
| 204 // If the beginning-of-block liveness changed since the last | 193 // If the beginning-of-block liveness changed since the last |
| 205 // iteration, mark all in-edges as needing to be processed. | 194 // iteration, mark all in-edges as needing to be processed. |
| 206 const NodeList &InEdges = Node->getInEdges(); | 195 for (CfgNode *Pred : Node->getInEdges()) |
| 207 for (NodeList::const_iterator I1 = InEdges.begin(), | |
| 208 E1 = InEdges.end(); | |
| 209 I1 != E1; ++I1) { | |
| 210 CfgNode *Pred = *I1; | |
| 211 NeedToProcess[Pred->getIndex()] = true; | 196 NeedToProcess[Pred->getIndex()] = true; |
| 212 } | |
| 213 } | 197 } |
| 214 } | 198 } |
| 215 } | 199 } |
| 216 } | 200 } |
| 217 if (Mode == Liveness_Intervals) { | 201 if (Mode == Liveness_Intervals) { |
| 218 // Reset each variable's live range. | 202 // Reset each variable's live range. |
| 219 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); | 203 for (Variable *Var : Variables) |
| 220 I != E; ++I) { | 204 Var->resetLiveRange(); |
| 221 if (Variable *Var = *I) | |
| 222 Var->resetLiveRange(); | |
| 223 } | |
| 224 } | 205 } |
| 225 // Collect timing for just the portion that constructs the live | 206 // Collect timing for just the portion that constructs the live |
| 226 // range intervals based on the end-of-live-range computation, for a | 207 // range intervals based on the end-of-live-range computation, for a |
| 227 // finer breakdown of the cost. | 208 // finer breakdown of the cost. |
| 228 // Make a final pass over instructions to delete dead instructions | 209 // Make a final pass over instructions to delete dead instructions |
| 229 // and build each Variable's live range. | 210 // and build each Variable's live range. |
| 230 static TimerIdT IDliveRange = GlobalContext::getTimerID("liveRange"); | 211 static TimerIdT IDliveRange = GlobalContext::getTimerID("liveRange"); |
| 231 TimerMarker T1(IDliveRange, getContext()); | 212 TimerMarker T1(IDliveRange, getContext()); |
| 232 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 213 for (CfgNode *Node : Nodes) |
| 233 (*I)->livenessPostprocess(Mode, getLiveness()); | 214 Node->livenessPostprocess(Mode, getLiveness()); |
| 234 } | |
| 235 if (Mode == Liveness_Intervals) { | 215 if (Mode == Liveness_Intervals) { |
| 236 // Special treatment for live in-args. Their liveness needs to | 216 // Special treatment for live in-args. Their liveness needs to |
| 237 // extend beyond the beginning of the function, otherwise an arg | 217 // extend beyond the beginning of the function, otherwise an arg |
| 238 // whose only use is in the first instruction will end up having | 218 // whose only use is in the first instruction will end up having |
| 239 // the trivial live range [1,1) and will *not* interfere with | 219 // the trivial live range [1,1) and will *not* interfere with |
| 240 // other arguments. So if the first instruction of the method is | 220 // other arguments. So if the first instruction of the method is |
| 241 // "r=arg1+arg2", both args may be assigned the same register. | 221 // "r=arg1+arg2", both args may be assigned the same register. |
| 242 for (SizeT I = 0; I < Args.size(); ++I) { | 222 for (SizeT I = 0; I < Args.size(); ++I) { |
| 243 Variable *Arg = Args[I]; | 223 Variable *Arg = Args[I]; |
| 244 if (!Live->getLiveRange(Arg).isEmpty()) { | 224 if (!Live->getLiveRange(Arg).isEmpty()) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 273 } | 253 } |
| 274 | 254 |
| 275 // Traverse every Variable of every Inst and verify that it | 255 // Traverse every Variable of every Inst and verify that it |
| 276 // appears within the Variable's computed live range. | 256 // appears within the Variable's computed live range. |
| 277 bool Cfg::validateLiveness() const { | 257 bool Cfg::validateLiveness() const { |
| 278 static TimerIdT IDvalidateLiveness = | 258 static TimerIdT IDvalidateLiveness = |
| 279 GlobalContext::getTimerID("validateLiveness"); | 259 GlobalContext::getTimerID("validateLiveness"); |
| 280 TimerMarker T(IDvalidateLiveness, getContext()); | 260 TimerMarker T(IDvalidateLiveness, getContext()); |
| 281 bool Valid = true; | 261 bool Valid = true; |
| 282 Ostream &Str = Ctx->getStrDump(); | 262 Ostream &Str = Ctx->getStrDump(); |
| 283 for (NodeList::const_iterator I1 = Nodes.begin(), E1 = Nodes.end(); I1 != E1; | 263 for (CfgNode *Node : Nodes) { |
| 284 ++I1) { | 264 for (Inst *Inst : Node->getInsts()) { |
| 285 CfgNode *Node = *I1; | |
| 286 InstList &Insts = Node->getInsts(); | |
| 287 for (InstList::const_iterator I2 = Insts.begin(), E2 = Insts.end(); | |
| 288 I2 != E2; ++I2) { | |
| 289 Inst *Inst = *I2; | |
| 290 if (Inst->isDeleted()) | 265 if (Inst->isDeleted()) |
| 291 continue; | 266 continue; |
| 292 if (llvm::isa<InstFakeKill>(Inst)) | 267 if (llvm::isa<InstFakeKill>(Inst)) |
| 293 continue; | 268 continue; |
| 294 InstNumberT InstNumber = Inst->getNumber(); | 269 InstNumberT InstNumber = Inst->getNumber(); |
| 295 Variable *Dest = Inst->getDest(); | 270 Variable *Dest = Inst->getDest(); |
| 296 if (Dest) { | 271 if (Dest) { |
| 297 // TODO: This instruction should actually begin Dest's live | 272 // TODO: This instruction should actually begin Dest's live |
| 298 // range, so we could probably test that this instruction is | 273 // range, so we could probably test that this instruction is |
| 299 // the beginning of some segment of Dest's live range. But | 274 // the beginning of some segment of Dest's live range. But |
| (...skipping 20 matching lines...) Expand all Loading... |
| 320 } | 295 } |
| 321 } | 296 } |
| 322 } | 297 } |
| 323 } | 298 } |
| 324 return Valid; | 299 return Valid; |
| 325 } | 300 } |
| 326 | 301 |
| 327 void Cfg::doBranchOpt() { | 302 void Cfg::doBranchOpt() { |
| 328 static TimerIdT IDdoBranchOpt = GlobalContext::getTimerID("doBranchOpt"); | 303 static TimerIdT IDdoBranchOpt = GlobalContext::getTimerID("doBranchOpt"); |
| 329 TimerMarker T(IDdoBranchOpt, getContext()); | 304 TimerMarker T(IDdoBranchOpt, getContext()); |
| 330 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 305 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 331 NodeList::iterator NextNode = I; | 306 auto NextNode = I; |
| 332 ++NextNode; | 307 ++NextNode; |
| 333 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); | 308 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); |
| 334 } | 309 } |
| 335 } | 310 } |
| 336 | 311 |
| 337 // ======================== Dump routines ======================== // | 312 // ======================== Dump routines ======================== // |
| 338 | 313 |
| 339 void Cfg::emit() { | 314 void Cfg::emit() { |
| 340 static TimerIdT IDemit = GlobalContext::getTimerID("emit"); | 315 static TimerIdT IDemit = GlobalContext::getTimerID("emit"); |
| 341 TimerMarker T(IDemit, getContext()); | 316 TimerMarker T(IDemit, getContext()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 353 } | 328 } |
| 354 Str << "\t.text\n"; | 329 Str << "\t.text\n"; |
| 355 IceString MangledName = getContext()->mangleName(getFunctionName()); | 330 IceString MangledName = getContext()->mangleName(getFunctionName()); |
| 356 if (Ctx->getFlags().FunctionSections) | 331 if (Ctx->getFlags().FunctionSections) |
| 357 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; | 332 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; |
| 358 if (!getInternal()) { | 333 if (!getInternal()) { |
| 359 Str << "\t.globl\t" << MangledName << "\n"; | 334 Str << "\t.globl\t" << MangledName << "\n"; |
| 360 Str << "\t.type\t" << MangledName << ",@function\n"; | 335 Str << "\t.type\t" << MangledName << ",@function\n"; |
| 361 } | 336 } |
| 362 Str << "\t.p2align " << getTarget()->getBundleAlignLog2Bytes() << ",0x"; | 337 Str << "\t.p2align " << getTarget()->getBundleAlignLog2Bytes() << ",0x"; |
| 363 llvm::ArrayRef<uint8_t> Pad = getTarget()->getNonExecBundlePadding(); | 338 for (AsmCodeByte I : getTarget()->getNonExecBundlePadding()) |
| 364 for (llvm::ArrayRef<uint8_t>::iterator I = Pad.begin(), E = Pad.end(); | 339 Str.write_hex(I); |
| 365 I != E; ++I) { | |
| 366 Str.write_hex(*I); | |
| 367 } | |
| 368 Str << "\n"; | 340 Str << "\n"; |
| 369 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; | 341 for (CfgNode *Node : Nodes) |
| 370 ++I) { | 342 Node->emit(this); |
| 371 (*I)->emit(this); | |
| 372 } | |
| 373 Str << "\n"; | 343 Str << "\n"; |
| 374 } | 344 } |
| 375 | 345 |
| 376 // Dumps the IR with an optional introductory message. | 346 // Dumps the IR with an optional introductory message. |
| 377 void Cfg::dump(const IceString &Message) { | 347 void Cfg::dump(const IceString &Message) { |
| 378 if (!Ctx->isVerbose()) | 348 if (!Ctx->isVerbose()) |
| 379 return; | 349 return; |
| 380 Ostream &Str = Ctx->getStrDump(); | 350 Ostream &Str = Ctx->getStrDump(); |
| 381 if (!Message.empty()) | 351 if (!Message.empty()) |
| 382 Str << "================ " << Message << " ================\n"; | 352 Str << "================ " << Message << " ================\n"; |
| 383 setCurrentNode(getEntryNode()); | 353 setCurrentNode(getEntryNode()); |
| 384 // Print function name+args | 354 // Print function name+args |
| 385 if (getContext()->isVerbose(IceV_Instructions)) { | 355 if (getContext()->isVerbose(IceV_Instructions)) { |
| 386 Str << "define "; | 356 Str << "define "; |
| 387 if (getInternal()) | 357 if (getInternal()) |
| 388 Str << "internal "; | 358 Str << "internal "; |
| 389 Str << ReturnType << " @" << getFunctionName() << "("; | 359 Str << ReturnType << " @" << getFunctionName() << "("; |
| 390 for (SizeT i = 0; i < Args.size(); ++i) { | 360 for (SizeT i = 0; i < Args.size(); ++i) { |
| 391 if (i > 0) | 361 if (i > 0) |
| 392 Str << ", "; | 362 Str << ", "; |
| 393 Str << Args[i]->getType() << " "; | 363 Str << Args[i]->getType() << " "; |
| 394 Args[i]->dump(this); | 364 Args[i]->dump(this); |
| 395 } | 365 } |
| 396 Str << ") {\n"; | 366 Str << ") {\n"; |
| 397 } | 367 } |
| 398 resetCurrentNode(); | 368 resetCurrentNode(); |
| 399 if (getContext()->isVerbose(IceV_Liveness)) { | 369 if (getContext()->isVerbose(IceV_Liveness)) { |
| 400 // Print summary info about variables | 370 // Print summary info about variables |
| 401 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); | 371 for (Variable *Var : Variables) { |
| 402 I != E; ++I) { | |
| 403 Variable *Var = *I; | |
| 404 Str << "// multiblock="; | 372 Str << "// multiblock="; |
| 405 if (getVMetadata()->isTracked(Var)) | 373 if (getVMetadata()->isTracked(Var)) |
| 406 Str << getVMetadata()->isMultiBlock(Var); | 374 Str << getVMetadata()->isMultiBlock(Var); |
| 407 else | 375 else |
| 408 Str << "?"; | 376 Str << "?"; |
| 409 Str << " weight=" << Var->getWeight() << " "; | 377 Str << " weight=" << Var->getWeight() << " "; |
| 410 Var->dump(this); | 378 Var->dump(this); |
| 411 Str << " LIVE=" << Var->getLiveRange() << "\n"; | 379 Str << " LIVE=" << Var->getLiveRange() << "\n"; |
| 412 } | 380 } |
| 413 } | 381 } |
| 414 // Print each basic block | 382 // Print each basic block |
| 415 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; | 383 for (CfgNode *Node : Nodes) |
| 416 ++I) { | 384 Node->dump(this); |
| 417 (*I)->dump(this); | 385 if (getContext()->isVerbose(IceV_Instructions)) |
| 418 } | |
| 419 if (getContext()->isVerbose(IceV_Instructions)) { | |
| 420 Str << "}\n"; | 386 Str << "}\n"; |
| 421 } | |
| 422 } | 387 } |
| 423 | 388 |
| 424 } // end of namespace Ice | 389 } // end of namespace Ice |
| OLD | NEW |