OLD | NEW |
1 //===- subzero/src/IceInst.cpp - High-level instruction implementation ----===// | 1 //===- subzero/src/IceInst.cpp - High-level instruction 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 /// \file | 10 /// \file |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 297 |
298 bool InstAssign::isVarAssign() const { return llvm::isa<Variable>(getSrc(0)); } | 298 bool InstAssign::isVarAssign() const { return llvm::isa<Variable>(getSrc(0)); } |
299 | 299 |
300 // If TargetTrue==TargetFalse, we turn it into an unconditional branch. This | 300 // If TargetTrue==TargetFalse, we turn it into an unconditional branch. This |
301 // ensures that, along with the 'switch' instruction semantics, there is at | 301 // ensures that, along with the 'switch' instruction semantics, there is at |
302 // most one edge from one node to another. | 302 // most one edge from one node to another. |
303 InstBr::InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue_, | 303 InstBr::InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue_, |
304 CfgNode *TargetFalse_) | 304 CfgNode *TargetFalse_) |
305 : InstHighLevel(Func, Inst::Br, 1, nullptr), TargetFalse(TargetFalse_), | 305 : InstHighLevel(Func, Inst::Br, 1, nullptr), TargetFalse(TargetFalse_), |
306 TargetTrue(TargetTrue_) { | 306 TargetTrue(TargetTrue_) { |
307 if (TargetTrue == TargetFalse) { | 307 if (auto *Constant = llvm::dyn_cast<ConstantInteger32>(Source)) { |
| 308 int32_t C32 = Constant->getValue(); |
| 309 if (C32 != 0) { |
| 310 TargetFalse = TargetTrue; |
| 311 } |
| 312 TargetTrue = nullptr; // turn into unconditional version |
| 313 } else if (TargetTrue == TargetFalse) { |
308 TargetTrue = nullptr; // turn into unconditional version | 314 TargetTrue = nullptr; // turn into unconditional version |
309 } else { | 315 } else { |
310 addSource(Source); | 316 addSource(Source); |
311 } | 317 } |
312 } | 318 } |
313 | 319 |
314 InstBr::InstBr(Cfg *Func, CfgNode *Target) | 320 InstBr::InstBr(Cfg *Func, CfgNode *Target) |
315 : InstHighLevel(Func, Inst::Br, 0, nullptr), TargetFalse(Target), | 321 : InstHighLevel(Func, Inst::Br, 0, nullptr), TargetFalse(Target), |
316 TargetTrue(nullptr) {} | 322 TargetTrue(nullptr) {} |
317 | 323 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // TODO: A Switch instruction (and maybe others) can add duplicate edges. We | 391 // TODO: A Switch instruction (and maybe others) can add duplicate edges. We |
386 // may want to de-dup Phis and validate consistency (i.e., the source operands | 392 // may want to de-dup Phis and validate consistency (i.e., the source operands |
387 // are the same for duplicate edges), though it seems the current lowering code | 393 // are the same for duplicate edges), though it seems the current lowering code |
388 // is OK with this situation. | 394 // is OK with this situation. |
389 void InstPhi::addArgument(Operand *Source, CfgNode *Label) { | 395 void InstPhi::addArgument(Operand *Source, CfgNode *Label) { |
390 Labels[getSrcSize()] = Label; | 396 Labels[getSrcSize()] = Label; |
391 addSource(Source); | 397 addSource(Source); |
392 } | 398 } |
393 | 399 |
394 // Find the source operand corresponding to the incoming edge for the given | 400 // Find the source operand corresponding to the incoming edge for the given |
395 // node. TODO: This uses a linear-time search, which could be improved if it | 401 // node. |
396 // becomes a problem. | |
397 Operand *InstPhi::getOperandForTarget(CfgNode *Target) const { | 402 Operand *InstPhi::getOperandForTarget(CfgNode *Target) const { |
398 for (SizeT I = 0; I < getSrcSize(); ++I) { | 403 for (SizeT I = 0; I < getSrcSize(); ++I) { |
399 if (Labels[I] == Target) | 404 if (Labels[I] == Target) |
400 return getSrc(I); | 405 return getSrc(I); |
401 } | 406 } |
402 llvm_unreachable("Phi target not found"); | 407 llvm_unreachable("Phi target not found"); |
403 return nullptr; | 408 return nullptr; |
404 } | 409 } |
405 | 410 |
| 411 // Replace the source operand corresponding to the incoming edge for the given |
| 412 // node by a zero of the appropriate type. |
| 413 void InstPhi::clearOperandForTarget(CfgNode *Target) { |
| 414 for (SizeT I = 0; I < getSrcSize(); ++I) { |
| 415 if (getLabel(I) == Target) { |
| 416 Type Ty = Dest->getType(); |
| 417 Srcs[I] = Target->getCfg()->getContext()->getConstantZero(Ty); |
| 418 return; |
| 419 } |
| 420 } |
| 421 llvm_unreachable("Phi target not found"); |
| 422 } |
| 423 |
406 // Updates liveness for a particular operand based on the given predecessor | 424 // Updates liveness for a particular operand based on the given predecessor |
407 // edge. Doesn't mark the operand as live if the Phi instruction is dead or | 425 // edge. Doesn't mark the operand as live if the Phi instruction is dead or |
408 // deleted. | 426 // deleted. |
409 void InstPhi::livenessPhiOperand(LivenessBV &Live, CfgNode *Target, | 427 void InstPhi::livenessPhiOperand(LivenessBV &Live, CfgNode *Target, |
410 Liveness *Liveness) { | 428 Liveness *Liveness) { |
411 if (isDeleted() || Dead) | 429 if (isDeleted() || Dead) |
412 return; | 430 return; |
413 for (SizeT I = 0; I < getSrcSize(); ++I) { | 431 for (SizeT I = 0; I < getSrcSize(); ++I) { |
414 if (Labels[I] == Target) { | 432 if (Labels[I] == Target) { |
415 if (auto *Var = llvm::dyn_cast<Variable>(getSrc(I))) { | 433 if (auto *Var = llvm::dyn_cast<Variable>(getSrc(I))) { |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 // upper 32 bits of rax. We need to recognize and preserve these. | 1033 // upper 32 bits of rax. We need to recognize and preserve these. |
1016 return true; | 1034 return true; |
1017 } | 1035 } |
1018 if (!Dest->hasReg() && !SrcVar->hasReg() && | 1036 if (!Dest->hasReg() && !SrcVar->hasReg() && |
1019 Dest->getStackOffset() == SrcVar->getStackOffset()) | 1037 Dest->getStackOffset() == SrcVar->getStackOffset()) |
1020 return true; | 1038 return true; |
1021 return false; | 1039 return false; |
1022 } | 1040 } |
1023 | 1041 |
1024 } // end of namespace Ice | 1042 } // end of namespace Ice |
OLD | NEW |