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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 } InstIcmpAttributes[] = { | 63 } InstIcmpAttributes[] = { |
| 64 #define X(tag, str) \ | 64 #define X(tag, str) \ |
| 65 { str } \ | 65 { str } \ |
| 66 , | 66 , |
| 67 ICEINSTICMP_TABLE | 67 ICEINSTICMP_TABLE |
| 68 #undef X | 68 #undef X |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 } // end of anonymous namespace | 71 } // end of anonymous namespace |
| 72 | 72 |
| 73 Inst::Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 73 Inst::Inst(Cfg *Func, InstKind MyKind, SizeT MyMaxSrcs, Variable *MyDest) |
| 74 : Kind(Kind), Number(Func->newInstNumber()), Dest(Dest), MaxSrcs(MaxSrcs), | 74 : Kind(MyKind), Number(Func->newInstNumber()), Dest(MyDest), |
| 75 Srcs(Func->allocateArrayOf<Operand *>(MaxSrcs)), LiveRangesEnded(0) {} | 75 MaxSrcs(MyMaxSrcs), Srcs(Func->allocateArrayOf<Operand *>(MyMaxSrcs)), |
| 76 LiveRangesEnded(0) {} | |
| 76 | 77 |
| 77 // Assign the instruction a new number. | 78 // Assign the instruction a new number. |
| 78 void Inst::renumber(Cfg *Func) { | 79 void Inst::renumber(Cfg *Func) { |
| 79 Number = isDeleted() ? NumberDeleted : Func->newInstNumber(); | 80 Number = isDeleted() ? NumberDeleted : Func->newInstNumber(); |
| 80 } | 81 } |
| 81 | 82 |
| 82 // Delete the instruction if its tentative Dead flag is still set | 83 // Delete the instruction if its tentative Dead flag is still set |
| 83 // after liveness analysis. | 84 // after liveness analysis. |
| 84 void Inst::deleteIfDead() { | 85 void Inst::deleteIfDead() { |
| 85 if (Dead) | 86 if (Dead) |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 // has been sorted. | 230 // has been sorted. |
| 230 LiveEnd->push_back(std::make_pair(VarNum, InstNumber)); | 231 LiveEnd->push_back(std::make_pair(VarNum, InstNumber)); |
| 231 } | 232 } |
| 232 } | 233 } |
| 233 } | 234 } |
| 234 } | 235 } |
| 235 } | 236 } |
| 236 return true; | 237 return true; |
| 237 } | 238 } |
| 238 | 239 |
| 239 InstAlloca::InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, | 240 InstAlloca::InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t MyAlignInBytes, |
|
Karl
2015/07/07 17:00:40
Silly question. I don't understand why you choose
John
2015/07/07 17:07:49
AlignInBytes shadows a member variable (which LLVM
Karl
2015/07/07 18:21:13
I disagree. Func is a protected inherited member v
John
2015/07/07 18:28:32
I don't see a
Ice::Inst::Func
neither a
Ice::In
Karl
2015/07/07 19:09:34
Ok. I'm wrong about Func. However Dest is defined
Jim Stichnoth
2015/07/13 19:33:37
I think the rules might read something like this:
| |
| 240 Variable *Dest) | 241 Variable *Dest) |
| 241 : InstHighLevel(Func, Inst::Alloca, 1, Dest), AlignInBytes(AlignInBytes) { | 242 : InstHighLevel(Func, Inst::Alloca, 1, Dest), AlignInBytes(MyAlignInBytes) { |
| 242 // Verify AlignInBytes is 0 or a power of 2. | 243 // Verify AlignInBytes is 0 or a power of 2. |
| 243 assert(AlignInBytes == 0 || llvm::isPowerOf2_32(AlignInBytes)); | 244 assert(AlignInBytes == 0 || llvm::isPowerOf2_32(AlignInBytes)); |
| 244 addSource(ByteCount); | 245 addSource(ByteCount); |
| 245 } | 246 } |
| 246 | 247 |
| 247 InstArithmetic::InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, | 248 InstArithmetic::InstArithmetic(Cfg *Func, OpKind MyOp, Variable *Dest, |
| 248 Operand *Source1, Operand *Source2) | 249 Operand *Source1, Operand *Source2) |
| 249 : InstHighLevel(Func, Inst::Arithmetic, 2, Dest), Op(Op) { | 250 : InstHighLevel(Func, Inst::Arithmetic, 2, Dest), Op(MyOp) { |
| 250 addSource(Source1); | 251 addSource(Source1); |
| 251 addSource(Source2); | 252 addSource(Source2); |
| 252 } | 253 } |
| 253 | 254 |
| 254 const char *InstArithmetic::getOpName(OpKind Op) { | 255 const char *InstArithmetic::getOpName(OpKind Op) { |
| 255 size_t OpIndex = static_cast<size_t>(Op); | 256 size_t OpIndex = static_cast<size_t>(Op); |
| 256 return OpIndex < InstArithmetic::_num | 257 return OpIndex < InstArithmetic::_num |
| 257 ? InstArithmeticAttributes[OpIndex].DisplayString | 258 ? InstArithmeticAttributes[OpIndex].DisplayString |
| 258 : "???"; | 259 : "???"; |
| 259 } | 260 } |
| 260 | 261 |
| 261 bool InstArithmetic::isCommutative() const { | 262 bool InstArithmetic::isCommutative() const { |
| 262 return InstArithmeticAttributes[getOp()].IsCommutative; | 263 return InstArithmeticAttributes[getOp()].IsCommutative; |
| 263 } | 264 } |
| 264 | 265 |
| 265 InstAssign::InstAssign(Cfg *Func, Variable *Dest, Operand *Source) | 266 InstAssign::InstAssign(Cfg *Func, Variable *Dest, Operand *Source) |
| 266 : InstHighLevel(Func, Inst::Assign, 1, Dest) { | 267 : InstHighLevel(Func, Inst::Assign, 1, Dest) { |
| 267 addSource(Source); | 268 addSource(Source); |
| 268 } | 269 } |
| 269 | 270 |
| 270 // If TargetTrue==TargetFalse, we turn it into an unconditional | 271 // If TargetTrue==TargetFalse, we turn it into an unconditional |
| 271 // branch. This ensures that, along with the 'switch' instruction | 272 // branch. This ensures that, along with the 'switch' instruction |
| 272 // semantics, there is at most one edge from one node to another. | 273 // semantics, there is at most one edge from one node to another. |
| 273 InstBr::InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue_, | 274 InstBr::InstBr(Cfg *Func, Operand *Source, CfgNode *MyTargetTrue, |
| 274 CfgNode *TargetFalse_) | 275 CfgNode *MyTargetFalse) |
| 275 : InstHighLevel(Func, Inst::Br, 1, nullptr), TargetFalse(TargetFalse_), | 276 : InstHighLevel(Func, Inst::Br, 1, nullptr), TargetFalse(MyTargetFalse), |
| 276 TargetTrue(TargetTrue_) { | 277 TargetTrue(MyTargetTrue) { |
| 277 if (TargetTrue == TargetFalse) { | 278 if (TargetTrue == TargetFalse) { |
| 278 TargetTrue = nullptr; // turn into unconditional version | 279 TargetTrue = nullptr; // turn into unconditional version |
| 279 } else { | 280 } else { |
| 280 addSource(Source); | 281 addSource(Source); |
| 281 } | 282 } |
| 282 } | 283 } |
| 283 | 284 |
| 284 InstBr::InstBr(Cfg *Func, CfgNode *Target) | 285 InstBr::InstBr(Cfg *Func, CfgNode *Target) |
| 285 : InstHighLevel(Func, Inst::Br, 0, nullptr), TargetFalse(Target), | 286 : InstHighLevel(Func, Inst::Br, 0, nullptr), TargetFalse(Target), |
| 286 TargetTrue(nullptr) {} | 287 TargetTrue(nullptr) {} |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 298 if (TargetFalse == OldNode) { | 299 if (TargetFalse == OldNode) { |
| 299 TargetFalse = NewNode; | 300 TargetFalse = NewNode; |
| 300 return true; | 301 return true; |
| 301 } else if (TargetTrue == OldNode) { | 302 } else if (TargetTrue == OldNode) { |
| 302 TargetTrue = NewNode; | 303 TargetTrue = NewNode; |
| 303 return true; | 304 return true; |
| 304 } | 305 } |
| 305 return false; | 306 return false; |
| 306 } | 307 } |
| 307 | 308 |
| 308 InstCast::InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source) | 309 InstCast::InstCast(Cfg *Func, OpKind MyCastKind, Variable *Dest, |
| 309 : InstHighLevel(Func, Inst::Cast, 1, Dest), CastKind(CastKind) { | 310 Operand *Source) |
| 311 : InstHighLevel(Func, Inst::Cast, 1, Dest), CastKind(MyCastKind) { | |
| 310 addSource(Source); | 312 addSource(Source); |
| 311 } | 313 } |
| 312 | 314 |
| 313 InstExtractElement::InstExtractElement(Cfg *Func, Variable *Dest, | 315 InstExtractElement::InstExtractElement(Cfg *Func, Variable *Dest, |
| 314 Operand *Source1, Operand *Source2) | 316 Operand *Source1, Operand *Source2) |
| 315 : InstHighLevel(Func, Inst::ExtractElement, 2, Dest) { | 317 : InstHighLevel(Func, Inst::ExtractElement, 2, Dest) { |
| 316 addSource(Source1); | 318 addSource(Source1); |
| 317 addSource(Source2); | 319 addSource(Source2); |
| 318 } | 320 } |
| 319 | 321 |
| 320 InstFcmp::InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, | 322 InstFcmp::InstFcmp(Cfg *Func, FCond MyCondition, Variable *Dest, |
| 321 Operand *Source2) | 323 Operand *Source1, Operand *Source2) |
| 322 : InstHighLevel(Func, Inst::Fcmp, 2, Dest), Condition(Condition) { | 324 : InstHighLevel(Func, Inst::Fcmp, 2, Dest), Condition(MyCondition) { |
| 323 addSource(Source1); | 325 addSource(Source1); |
| 324 addSource(Source2); | 326 addSource(Source2); |
| 325 } | 327 } |
| 326 | 328 |
| 327 InstIcmp::InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 329 InstIcmp::InstIcmp(Cfg *Func, ICond MyCondition, Variable *Dest, |
| 328 Operand *Source2) | 330 Operand *Source1, Operand *Source2) |
| 329 : InstHighLevel(Func, Inst::Icmp, 2, Dest), Condition(Condition) { | 331 : InstHighLevel(Func, Inst::Icmp, 2, Dest), Condition(MyCondition) { |
| 330 addSource(Source1); | 332 addSource(Source1); |
| 331 addSource(Source2); | 333 addSource(Source2); |
| 332 } | 334 } |
| 333 | 335 |
| 334 InstInsertElement::InstInsertElement(Cfg *Func, Variable *Dest, | 336 InstInsertElement::InstInsertElement(Cfg *Func, Variable *Dest, |
| 335 Operand *Source1, Operand *Source2, | 337 Operand *Source1, Operand *Source2, |
| 336 Operand *Source3) | 338 Operand *Source3) |
| 337 : InstHighLevel(Func, Inst::InsertElement, 3, Dest) { | 339 : InstHighLevel(Func, Inst::InsertElement, 3, Dest) { |
| 338 addSource(Source1); | 340 addSource(Source1); |
| 339 addSource(Source2); | 341 addSource(Source2); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 addSource(Addr); | 428 addSource(Addr); |
| 427 // The 3rd operand is a dummy placeholder for the RMW beacon. | 429 // The 3rd operand is a dummy placeholder for the RMW beacon. |
| 428 addSource(Data); | 430 addSource(Data); |
| 429 } | 431 } |
| 430 | 432 |
| 431 void InstStore::setRmwBeacon(Variable *Beacon) { | 433 void InstStore::setRmwBeacon(Variable *Beacon) { |
| 432 Dest = llvm::dyn_cast<Variable>(getData()); | 434 Dest = llvm::dyn_cast<Variable>(getData()); |
| 433 Srcs[2] = Beacon; | 435 Srcs[2] = Beacon; |
| 434 } | 436 } |
| 435 | 437 |
| 436 InstSwitch::InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, | 438 InstSwitch::InstSwitch(Cfg *Func, SizeT MyNumCases, Operand *Source, |
| 437 CfgNode *LabelDefault) | 439 CfgNode *MyLabelDefault) |
| 438 : InstHighLevel(Func, Inst::Switch, 1, nullptr), LabelDefault(LabelDefault), | 440 : InstHighLevel(Func, Inst::Switch, 1, nullptr), |
| 439 NumCases(NumCases) { | 441 LabelDefault(MyLabelDefault), NumCases(MyNumCases) { |
| 440 addSource(Source); | 442 addSource(Source); |
| 441 Values = Func->allocateArrayOf<uint64_t>(NumCases); | 443 Values = Func->allocateArrayOf<uint64_t>(NumCases); |
| 442 Labels = Func->allocateArrayOf<CfgNode *>(NumCases); | 444 Labels = Func->allocateArrayOf<CfgNode *>(NumCases); |
| 443 // Initialize in case buggy code doesn't set all entries | 445 // Initialize in case buggy code doesn't set all entries |
| 444 for (SizeT I = 0; I < NumCases; ++I) { | 446 for (SizeT I = 0; I < NumCases; ++I) { |
| 445 Values[I] = 0; | 447 Values[I] = 0; |
| 446 Labels[I] = nullptr; | 448 Labels[I] = nullptr; |
| 447 } | 449 } |
| 448 } | 450 } |
| 449 | 451 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 473 Labels[I] = NewNode; | 475 Labels[I] = NewNode; |
| 474 return true; | 476 return true; |
| 475 } | 477 } |
| 476 } | 478 } |
| 477 return false; | 479 return false; |
| 478 } | 480 } |
| 479 | 481 |
| 480 InstUnreachable::InstUnreachable(Cfg *Func) | 482 InstUnreachable::InstUnreachable(Cfg *Func) |
| 481 : InstHighLevel(Func, Inst::Unreachable, 0, nullptr) {} | 483 : InstHighLevel(Func, Inst::Unreachable, 0, nullptr) {} |
| 482 | 484 |
| 483 InstBundleLock::InstBundleLock(Cfg *Func, InstBundleLock::Option BundleOption) | 485 InstBundleLock::InstBundleLock(Cfg *Func, InstBundleLock::Option MyBundleOption) |
| 484 : InstHighLevel(Func, Inst::BundleLock, 0, nullptr), | 486 : InstHighLevel(Func, Inst::BundleLock, 0, nullptr), |
| 485 BundleOption(BundleOption) {} | 487 BundleOption(MyBundleOption) {} |
| 486 | 488 |
| 487 InstBundleUnlock::InstBundleUnlock(Cfg *Func) | 489 InstBundleUnlock::InstBundleUnlock(Cfg *Func) |
| 488 : InstHighLevel(Func, Inst::BundleUnlock, 0, nullptr) {} | 490 : InstHighLevel(Func, Inst::BundleUnlock, 0, nullptr) {} |
| 489 | 491 |
| 490 InstFakeDef::InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src) | 492 InstFakeDef::InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src) |
| 491 : InstHighLevel(Func, Inst::FakeDef, Src ? 1 : 0, Dest) { | 493 : InstHighLevel(Func, Inst::FakeDef, Src ? 1 : 0, Dest) { |
| 492 assert(Dest); | 494 assert(Dest); |
| 493 if (Src) | 495 if (Src) |
| 494 addSource(Src); | 496 addSource(Src); |
| 495 } | 497 } |
| 496 | 498 |
| 497 InstFakeUse::InstFakeUse(Cfg *Func, Variable *Src) | 499 InstFakeUse::InstFakeUse(Cfg *Func, Variable *Src) |
| 498 : InstHighLevel(Func, Inst::FakeUse, 1, nullptr) { | 500 : InstHighLevel(Func, Inst::FakeUse, 1, nullptr) { |
| 499 assert(Src); | 501 assert(Src); |
| 500 addSource(Src); | 502 addSource(Src); |
| 501 } | 503 } |
| 502 | 504 |
| 503 InstFakeKill::InstFakeKill(Cfg *Func, const Inst *Linked) | 505 InstFakeKill::InstFakeKill(Cfg *Func, const Inst *MyLinked) |
| 504 : InstHighLevel(Func, Inst::FakeKill, 0, nullptr), Linked(Linked) {} | 506 : InstHighLevel(Func, Inst::FakeKill, 0, nullptr), Linked(MyLinked) {} |
| 505 | 507 |
| 506 Type InstCall::getReturnType() const { | 508 Type InstCall::getReturnType() const { |
| 507 if (Dest == nullptr) | 509 if (Dest == nullptr) |
| 508 return IceType_void; | 510 return IceType_void; |
| 509 return Dest->getType(); | 511 return Dest->getType(); |
| 510 } | 512 } |
| 511 | 513 |
| 512 // ======================== Dump routines ======================== // | 514 // ======================== Dump routines ======================== // |
| 513 | 515 |
| 514 void Inst::dumpDecorated(const Cfg *Func) const { | 516 void Inst::dumpDecorated(const Cfg *Func) const { |
| 515 if (!BuildDefs::dump()) | 517 if (!BuildDefs::dump()) |
| 516 return; | 518 return; |
| 517 Ostream &Str = Func->getContext()->getStrDump(); | 519 Ostream &Str = Func->getContext()->getStrDump(); |
| 518 if (!Func->isVerbose(IceV_Deleted) && (isDeleted() || isRedundantAssign())) | 520 if (!Func->isVerbose(IceV_Deleted) && (isDeleted() || isRedundantAssign())) |
| 519 return; | 521 return; |
| 520 if (Func->isVerbose(IceV_InstNumbers)) { | 522 if (Func->isVerbose(IceV_InstNumbers)) { |
| 521 char buf[30]; | 523 char buf[30]; |
| 522 InstNumberT Number = getNumber(); | 524 if (getNumber() == NumberDeleted) |
| 523 if (Number == NumberDeleted) | |
| 524 snprintf(buf, llvm::array_lengthof(buf), "[XXX]"); | 525 snprintf(buf, llvm::array_lengthof(buf), "[XXX]"); |
| 525 else | 526 else |
| 526 snprintf(buf, llvm::array_lengthof(buf), "[%3d]", Number); | 527 snprintf(buf, llvm::array_lengthof(buf), "[%3d]", getNumber()); |
| 527 Str << buf; | 528 Str << buf; |
| 528 } | 529 } |
| 529 Str << " "; | 530 Str << " "; |
| 530 if (isDeleted()) | 531 if (isDeleted()) |
| 531 Str << " //"; | 532 Str << " //"; |
| 532 dump(Func); | 533 dump(Func); |
| 533 dumpExtras(Func); | 534 dumpExtras(Func); |
| 534 Str << "\n"; | 535 Str << "\n"; |
| 535 } | 536 } |
| 536 | 537 |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 // preserve these. | 935 // preserve these. |
| 935 return true; | 936 return true; |
| 936 } | 937 } |
| 937 if (!Dest->hasReg() && !SrcVar->hasReg() && | 938 if (!Dest->hasReg() && !SrcVar->hasReg() && |
| 938 Dest->getStackOffset() == SrcVar->getStackOffset()) | 939 Dest->getStackOffset() == SrcVar->getStackOffset()) |
| 939 return true; | 940 return true; |
| 940 return false; | 941 return false; |
| 941 } | 942 } |
| 942 | 943 |
| 943 } // end of namespace Ice | 944 } // end of namespace Ice |
| OLD | NEW |