Chromium Code Reviews| 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 // This file implements the Inst class, primarily the various | 10 // This file implements the Inst class, primarily the various |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 continue; | 128 continue; |
| 129 SizeT Index = Var->getIndex(); | 129 SizeT Index = Var->getIndex(); |
| 130 if (Live[Index]) | 130 if (Live[Index]) |
| 131 continue; | 131 continue; |
| 132 Live[Index] = true; | 132 Live[Index] = true; |
| 133 setLastUse(VarIndex); | 133 setLastUse(VarIndex); |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 void Inst::liveness(InstNumberT InstNumber, LivenessBV &Live, | 138 // Returns true if the instruction is tentatively retained, or false |
|
jvoung (off chromium)
2014/10/27 22:12:21
nit: Might be clearer if the return value is descr
Jim Stichnoth
2014/10/28 01:20:14
Tried to clarify the description (in the .h file).
| |
| 139 // if the instruction is tentatively deleted. | |
| 140 bool Inst::liveness(InstNumberT InstNumber, LivenessBV &Live, | |
| 139 Liveness *Liveness, LiveBeginEndMap *LiveBegin, | 141 Liveness *Liveness, LiveBeginEndMap *LiveBegin, |
| 140 LiveBeginEndMap *LiveEnd) { | 142 LiveBeginEndMap *LiveEnd) { |
| 141 assert(!isDeleted()); | 143 assert(!isDeleted()); |
| 142 if (llvm::isa<InstFakeKill>(this)) | 144 if (llvm::isa<InstFakeKill>(this)) |
| 143 return; | 145 return true; |
| 144 | 146 |
| 145 Dead = false; | 147 Dead = false; |
| 146 if (Dest) { | 148 if (Dest) { |
| 147 SizeT VarNum = Liveness->getLiveIndex(Dest->getIndex()); | 149 SizeT VarNum = Liveness->getLiveIndex(Dest->getIndex()); |
| 148 if (Live[VarNum]) { | 150 if (Live[VarNum]) { |
| 149 if (!isDestNonKillable()) { | 151 if (!isDestNonKillable()) { |
| 150 Live[VarNum] = false; | 152 Live[VarNum] = false; |
| 151 if (LiveBegin) { | 153 if (LiveBegin) { |
| 152 LiveBegin->push_back(std::make_pair(VarNum, InstNumber)); | 154 LiveBegin->push_back(std::make_pair(VarNum, InstNumber)); |
| 153 } | 155 } |
| 154 } | 156 } |
| 155 } else { | 157 } else { |
| 156 if (!hasSideEffects()) | 158 if (!hasSideEffects()) |
| 157 Dead = true; | 159 Dead = true; |
| 158 } | 160 } |
| 159 } | 161 } |
| 160 if (Dead) | 162 if (Dead) |
| 161 return; | 163 return false; |
| 162 // Phi arguments only get added to Live in the predecessor node, but | 164 // Phi arguments only get added to Live in the predecessor node, but |
| 163 // we still need to update LiveRangesEnded. | 165 // we still need to update LiveRangesEnded. |
| 164 bool IsPhi = llvm::isa<InstPhi>(this); | 166 bool IsPhi = llvm::isa<InstPhi>(this); |
| 165 resetLastUses(); | 167 resetLastUses(); |
| 166 SizeT VarIndex = 0; | 168 SizeT VarIndex = 0; |
| 167 for (SizeT I = 0; I < getSrcSize(); ++I) { | 169 for (SizeT I = 0; I < getSrcSize(); ++I) { |
| 168 Operand *Src = getSrc(I); | 170 Operand *Src = getSrc(I); |
| 169 SizeT NumVars = Src->getNumVars(); | 171 SizeT NumVars = Src->getNumVars(); |
| 170 for (SizeT J = 0; J < NumVars; ++J, ++VarIndex) { | 172 for (SizeT J = 0; J < NumVars; ++J, ++VarIndex) { |
| 171 const Variable *Var = Src->getVar(J); | 173 const Variable *Var = Src->getVar(J); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 195 // added in this block, but this can't be done very | 197 // added in this block, but this can't be done very |
| 196 // efficiently with LiveEnd as a vector. Instead, | 198 // efficiently with LiveEnd as a vector. Instead, |
| 197 // livenessPostprocess() verifies this after the vector | 199 // livenessPostprocess() verifies this after the vector |
| 198 // has been sorted. | 200 // has been sorted. |
| 199 LiveEnd->push_back(std::make_pair(VarNum, InstNumber)); | 201 LiveEnd->push_back(std::make_pair(VarNum, InstNumber)); |
| 200 } | 202 } |
| 201 } | 203 } |
| 202 } | 204 } |
| 203 } | 205 } |
| 204 } | 206 } |
| 207 return true; | |
| 205 } | 208 } |
| 206 | 209 |
| 207 InstAlloca::InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, | 210 InstAlloca::InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, |
| 208 Variable *Dest) | 211 Variable *Dest) |
| 209 : InstHighLevel(Func, Inst::Alloca, 1, Dest), AlignInBytes(AlignInBytes) { | 212 : InstHighLevel(Func, Inst::Alloca, 1, Dest), AlignInBytes(AlignInBytes) { |
| 210 // Verify AlignInBytes is 0 or a power of 2. | 213 // Verify AlignInBytes is 0 or a power of 2. |
| 211 assert(AlignInBytes == 0 || llvm::isPowerOf2_32(AlignInBytes)); | 214 assert(AlignInBytes == 0 || llvm::isPowerOf2_32(AlignInBytes)); |
| 212 addSource(ByteCount); | 215 addSource(ByteCount); |
| 213 } | 216 } |
| 214 | 217 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 TargetTrue(NULL) {} | 257 TargetTrue(NULL) {} |
| 255 | 258 |
| 256 NodeList InstBr::getTerminatorEdges() const { | 259 NodeList InstBr::getTerminatorEdges() const { |
| 257 NodeList OutEdges; | 260 NodeList OutEdges; |
| 258 OutEdges.push_back(TargetFalse); | 261 OutEdges.push_back(TargetFalse); |
| 259 if (TargetTrue) | 262 if (TargetTrue) |
| 260 OutEdges.push_back(TargetTrue); | 263 OutEdges.push_back(TargetTrue); |
| 261 return OutEdges; | 264 return OutEdges; |
| 262 } | 265 } |
| 263 | 266 |
| 267 bool InstBr::repointEdge(CfgNode *OldNode, CfgNode *NewNode) { | |
| 268 if (TargetFalse == OldNode) { | |
| 269 TargetFalse = NewNode; | |
| 270 return true; | |
| 271 } else if (TargetTrue == OldNode) { | |
| 272 TargetTrue = NewNode; | |
| 273 return true; | |
| 274 } | |
| 275 return false; | |
|
jvoung (off chromium)
2014/10/27 22:12:21
Should this always succeed or no (only be one term
Jim Stichnoth
2014/10/28 01:20:14
It should fail (return false) only if something ge
| |
| 276 } | |
| 277 | |
| 264 InstCast::InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source) | 278 InstCast::InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source) |
| 265 : InstHighLevel(Func, Inst::Cast, 1, Dest), CastKind(CastKind) { | 279 : InstHighLevel(Func, Inst::Cast, 1, Dest), CastKind(CastKind) { |
| 266 addSource(Source); | 280 addSource(Source); |
| 267 } | 281 } |
| 268 | 282 |
| 269 InstExtractElement::InstExtractElement(Cfg *Func, Variable *Dest, | 283 InstExtractElement::InstExtractElement(Cfg *Func, Variable *Dest, |
| 270 Operand *Source1, Operand *Source2) | 284 Operand *Source1, Operand *Source2) |
| 271 : InstHighLevel(Func, Inst::ExtractElement, 2, Dest) { | 285 : InstHighLevel(Func, Inst::ExtractElement, 2, Dest) { |
| 272 addSource(Source1); | 286 addSource(Source1); |
| 273 addSource(Source2); | 287 addSource(Source2); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 | 417 |
| 404 NodeList InstSwitch::getTerminatorEdges() const { | 418 NodeList InstSwitch::getTerminatorEdges() const { |
| 405 NodeList OutEdges; | 419 NodeList OutEdges; |
| 406 OutEdges.push_back(LabelDefault); | 420 OutEdges.push_back(LabelDefault); |
| 407 for (SizeT I = 0; I < NumCases; ++I) { | 421 for (SizeT I = 0; I < NumCases; ++I) { |
| 408 OutEdges.push_back(Labels[I]); | 422 OutEdges.push_back(Labels[I]); |
| 409 } | 423 } |
| 410 return OutEdges; | 424 return OutEdges; |
| 411 } | 425 } |
| 412 | 426 |
| 427 bool InstSwitch::repointEdge(CfgNode *OldNode, CfgNode *NewNode) { | |
| 428 if (LabelDefault == OldNode) { | |
| 429 LabelDefault = NewNode; | |
| 430 return true; | |
| 431 } | |
| 432 for (SizeT I = 0; I < NumCases; ++I) { | |
| 433 if (Labels[I] == OldNode) { | |
| 434 Labels[I] = NewNode; | |
| 435 return true; | |
| 436 } | |
| 437 } | |
| 438 return false; | |
| 439 } | |
| 440 | |
| 413 InstUnreachable::InstUnreachable(Cfg *Func) | 441 InstUnreachable::InstUnreachable(Cfg *Func) |
| 414 : InstHighLevel(Func, Inst::Unreachable, 0, NULL) {} | 442 : InstHighLevel(Func, Inst::Unreachable, 0, NULL) {} |
| 415 | 443 |
| 416 InstFakeDef::InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src) | 444 InstFakeDef::InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src) |
| 417 : InstHighLevel(Func, Inst::FakeDef, Src ? 1 : 0, Dest) { | 445 : InstHighLevel(Func, Inst::FakeDef, Src ? 1 : 0, Dest) { |
| 418 assert(Dest); | 446 assert(Dest); |
| 419 if (Src) | 447 if (Src) |
| 420 addSource(Src); | 448 addSource(Src); |
| 421 } | 449 } |
| 422 | 450 |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 dumpSources(Func); | 779 dumpSources(Func); |
| 752 } | 780 } |
| 753 | 781 |
| 754 void InstTarget::dump(const Cfg *Func) const { | 782 void InstTarget::dump(const Cfg *Func) const { |
| 755 Ostream &Str = Func->getContext()->getStrDump(); | 783 Ostream &Str = Func->getContext()->getStrDump(); |
| 756 Str << "[TARGET] "; | 784 Str << "[TARGET] "; |
| 757 Inst::dump(Func); | 785 Inst::dump(Func); |
| 758 } | 786 } |
| 759 | 787 |
| 760 } // end of namespace Ice | 788 } // end of namespace Ice |
| OLD | NEW |