| 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 |