| 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 if (Mode == Liveness_Intervals) { | 200 if (Mode == Liveness_Intervals) { |
| 201 // Reset each variable's live range. | 201 // Reset each variable's live range. |
| 202 for (Variable *Var : Variables) | 202 for (Variable *Var : Variables) |
| 203 Var->resetLiveRange(); | 203 Var->resetLiveRange(); |
| 204 } | 204 } |
| 205 // Collect timing for just the portion that constructs the live | 205 // Collect timing for just the portion that constructs the live |
| 206 // range intervals based on the end-of-live-range computation, for a | 206 // range intervals based on the end-of-live-range computation, for a |
| 207 // finer breakdown of the cost. | 207 // finer breakdown of the cost. |
| 208 TimerMarker T1(TimerStack::TT_liveRange, this); |
| 208 // Make a final pass over instructions to delete dead instructions | 209 // Make a final pass over instructions to delete dead instructions |
| 209 // and build each Variable's live range. | 210 // and build each Variable's live range. |
| 210 TimerMarker T1(TimerStack::TT_liveRange, this); | |
| 211 for (CfgNode *Node : Nodes) | 211 for (CfgNode *Node : Nodes) |
| 212 Node->livenessPostprocess(Mode, getLiveness()); | 212 Node->livenessPostprocess(Mode, getLiveness()); |
| 213 if (Mode == Liveness_Intervals) { | 213 if (Mode == Liveness_Intervals) { |
| 214 // Special treatment for live in-args. Their liveness needs to | 214 // Special treatment for live in-args. Their liveness needs to |
| 215 // extend beyond the beginning of the function, otherwise an arg | 215 // extend beyond the beginning of the function, otherwise an arg |
| 216 // whose only use is in the first instruction will end up having | 216 // whose only use is in the first instruction will end up having |
| 217 // the trivial live range [1,1) and will *not* interfere with | 217 // the trivial live range [1,1) and will *not* interfere with |
| 218 // other arguments. So if the first instruction of the method is | 218 // other arguments. So if the first instruction of the method is |
| 219 // "r=arg1+arg2", both args may be assigned the same register. | 219 // "r=arg1+arg2", both args may be assigned the same register. |
| 220 for (SizeT I = 0; I < Args.size(); ++I) { | 220 for (SizeT I = 0; I < Args.size(); ++I) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 239 // Remove Variable::LiveRange and redirect to | 239 // Remove Variable::LiveRange and redirect to |
| 240 // Liveness::LiveRanges. TODO: make sure Variable weights | 240 // Liveness::LiveRanges. TODO: make sure Variable weights |
| 241 // are applied properly. | 241 // are applied properly. |
| 242 SizeT NumVars = Variables.size(); | 242 SizeT NumVars = Variables.size(); |
| 243 for (SizeT i = 0; i < NumVars; ++i) { | 243 for (SizeT i = 0; i < NumVars; ++i) { |
| 244 Variable *Var = Variables[i]; | 244 Variable *Var = Variables[i]; |
| 245 Var->setLiveRange(Live->getLiveRange(Var)); | 245 Var->setLiveRange(Live->getLiveRange(Var)); |
| 246 if (Var->getWeight().isInf()) | 246 if (Var->getWeight().isInf()) |
| 247 Var->setLiveRangeInfiniteWeight(); | 247 Var->setLiveRangeInfiniteWeight(); |
| 248 } | 248 } |
| 249 dump(); | |
| 250 } | 249 } |
| 251 } | 250 } |
| 252 | 251 |
| 253 // Traverse every Variable of every Inst and verify that it | 252 // Traverse every Variable of every Inst and verify that it |
| 254 // appears within the Variable's computed live range. | 253 // appears within the Variable's computed live range. |
| 255 bool Cfg::validateLiveness() const { | 254 bool Cfg::validateLiveness() const { |
| 256 TimerMarker T(TimerStack::TT_validateLiveness, this); | 255 TimerMarker T(TimerStack::TT_validateLiveness, this); |
| 257 bool Valid = true; | 256 bool Valid = true; |
| 258 Ostream &Str = Ctx->getStrDump(); | 257 Ostream &Str = Ctx->getStrDump(); |
| 259 for (CfgNode *Node : Nodes) { | 258 for (CfgNode *Node : Nodes) { |
| 259 Inst *FirstInst = NULL; |
| 260 for (Inst *Inst : Node->getInsts()) { | 260 for (Inst *Inst : Node->getInsts()) { |
| 261 if (Inst->isDeleted()) | 261 if (Inst->isDeleted()) |
| 262 continue; | 262 continue; |
| 263 if (llvm::isa<InstFakeKill>(Inst)) | 263 if (llvm::isa<InstFakeKill>(Inst)) |
| 264 continue; | 264 continue; |
| 265 if (FirstInst == NULL) |
| 266 FirstInst = Inst; |
| 265 InstNumberT InstNumber = Inst->getNumber(); | 267 InstNumberT InstNumber = Inst->getNumber(); |
| 266 Variable *Dest = Inst->getDest(); | 268 if (Variable *Dest = Inst->getDest()) { |
| 267 if (Dest) { | 269 if (!Dest->getIgnoreLiveness()) { |
| 268 // TODO: This instruction should actually begin Dest's live | 270 bool Invalid = false; |
| 269 // range, so we could probably test that this instruction is | 271 const bool IsDest = true; |
| 270 // the beginning of some segment of Dest's live range. But | 272 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest)) |
| 271 // this wouldn't work with non-SSA temporaries during | 273 Invalid = true; |
| 272 // lowering. | 274 // Check that this instruction actually *begins* Dest's live |
| 273 if (!Dest->getLiveRange().containsValue(InstNumber)) { | 275 // range, by checking that Dest is not live in the previous |
| 274 Valid = false; | 276 // instruction. As a special exception, we don't check this |
| 275 Str << "Liveness error: inst " << Inst->getNumber() << " dest "; | 277 // for the first instruction of the block, because a Phi |
| 276 Dest->dump(this); | 278 // temporary may be live at the end of the previous block, |
| 277 Str << " live range " << Dest->getLiveRange() << "\n"; | 279 // and if it is also assigned in the first instruction of |
| 280 // this block, the adjacent live ranges get merged. |
| 281 if (Inst != FirstInst && !Inst->isDestNonKillable() && |
| 282 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest)) |
| 283 Invalid = true; |
| 284 if (Invalid) { |
| 285 Valid = false; |
| 286 Str << "Liveness error: inst " << Inst->getNumber() << " dest "; |
| 287 Dest->dump(this); |
| 288 Str << " live range " << Dest->getLiveRange() << "\n"; |
| 289 } |
| 278 } | 290 } |
| 279 } | 291 } |
| 280 for (SizeT I = 0; I < Inst->getSrcSize(); ++I) { | 292 for (SizeT I = 0; I < Inst->getSrcSize(); ++I) { |
| 281 Operand *Src = Inst->getSrc(I); | 293 Operand *Src = Inst->getSrc(I); |
| 282 SizeT NumVars = Src->getNumVars(); | 294 SizeT NumVars = Src->getNumVars(); |
| 283 for (SizeT J = 0; J < NumVars; ++J) { | 295 for (SizeT J = 0; J < NumVars; ++J) { |
| 284 const Variable *Var = Src->getVar(J); | 296 const Variable *Var = Src->getVar(J); |
| 285 if (!Var->getLiveRange().containsValue(InstNumber)) { | 297 const bool IsDest = false; |
| 298 if (!Var->getIgnoreLiveness() && |
| 299 !Var->getLiveRange().containsValue(InstNumber, IsDest)) { |
| 286 Valid = false; | 300 Valid = false; |
| 287 Str << "Liveness error: inst " << Inst->getNumber() << " var "; | 301 Str << "Liveness error: inst " << Inst->getNumber() << " var "; |
| 288 Var->dump(this); | 302 Var->dump(this); |
| 289 Str << " live range " << Var->getLiveRange() << "\n"; | 303 Str << " live range " << Var->getLiveRange() << "\n"; |
| 290 } | 304 } |
| 291 } | 305 } |
| 292 } | 306 } |
| 293 } | 307 } |
| 294 } | 308 } |
| 295 return Valid; | 309 return Valid; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 } | 388 } |
| 375 } | 389 } |
| 376 // Print each basic block | 390 // Print each basic block |
| 377 for (CfgNode *Node : Nodes) | 391 for (CfgNode *Node : Nodes) |
| 378 Node->dump(this); | 392 Node->dump(this); |
| 379 if (getContext()->isVerbose(IceV_Instructions)) | 393 if (getContext()->isVerbose(IceV_Instructions)) |
| 380 Str << "}\n"; | 394 Str << "}\n"; |
| 381 } | 395 } |
| 382 | 396 |
| 383 } // end of namespace Ice | 397 } // end of namespace Ice |
| OLD | NEW |