| OLD | NEW |
| 1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===// | 1 //===- subzero/src/IceOperand.cpp - High-level operand 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 Operand class and its target-independent | 10 // This file implements the Operand class and its target-independent |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 I != E; ++I) { | 84 I != E; ++I) { |
| 85 if (OtherBegin < I->first) { | 85 if (OtherBegin < I->first) { |
| 86 Result = false; | 86 Result = false; |
| 87 break; | 87 break; |
| 88 } | 88 } |
| 89 if (OtherBegin < I->second) { | 89 if (OtherBegin < I->second) { |
| 90 Result = true; | 90 Result = true; |
| 91 break; | 91 break; |
| 92 } | 92 } |
| 93 } | 93 } |
| 94 #if 0 | 94 // This is an equivalent but less inefficient implementation. It's |
| 95 // An equivalent but less inefficient implementation: | 95 // expensive enough that we wouldn't want to run it under any build, |
| 96 LiveRange Temp; | 96 // but it could be enabled if e.g. the LiveRange implementation |
| 97 Temp.addSegment(OtherBegin, OtherBegin + 1); | 97 // changes and extra testing is needed. |
| 98 bool Validation = overlaps(Temp); | 98 if (buildAllowsExtraValidation()) { |
| 99 assert(Result == Validation); | 99 LiveRange Temp; |
| 100 #endif | 100 Temp.addSegment(OtherBegin, OtherBegin + 1); |
| 101 bool Validation = overlaps(Temp); |
| 102 (void)Validation; |
| 103 assert(Result == Validation); |
| 104 } |
| 101 return Result; | 105 return Result; |
| 102 } | 106 } |
| 103 | 107 |
| 104 // Returns true if the live range contains the given instruction | 108 // Returns true if the live range contains the given instruction |
| 105 // number. This is only used for validating the live range | 109 // number. This is only used for validating the live range |
| 106 // calculation. The IsDest argument indicates whether the Variable | 110 // calculation. The IsDest argument indicates whether the Variable |
| 107 // being tested is used in the Dest position (as opposed to a Src | 111 // being tested is used in the Dest position (as opposed to a Src |
| 108 // position). | 112 // position). |
| 109 bool LiveRange::containsValue(InstNumberT Value, bool IsDest) const { | 113 bool LiveRange::containsValue(InstNumberT Value, bool IsDest) const { |
| 110 for (const RangeElementType &I : Range) { | 114 for (const RangeElementType &I : Range) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 122 | 126 |
| 123 IceString Variable::getName(const Cfg *Func) const { | 127 IceString Variable::getName(const Cfg *Func) const { |
| 124 if (Func && NameIndex >= 0) | 128 if (Func && NameIndex >= 0) |
| 125 return Func->getIdentifierName(NameIndex); | 129 return Func->getIdentifierName(NameIndex); |
| 126 return "__" + std::to_string(getIndex()); | 130 return "__" + std::to_string(getIndex()); |
| 127 } | 131 } |
| 128 | 132 |
| 129 Variable *Variable::asType(Type Ty) { | 133 Variable *Variable::asType(Type Ty) { |
| 130 // Note: This returns a Variable, even if the "this" object is a | 134 // Note: This returns a Variable, even if the "this" object is a |
| 131 // subclass of Variable. | 135 // subclass of Variable. |
| 132 if (!ALLOW_DUMP || getType() == Ty) | 136 if (!buildAllowsDump() || getType() == Ty) |
| 133 return this; | 137 return this; |
| 134 Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>()) | 138 Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>()) |
| 135 Variable(kVariable, Ty, Number); | 139 Variable(kVariable, Ty, Number); |
| 136 V->NameIndex = NameIndex; | 140 V->NameIndex = NameIndex; |
| 137 V->RegNum = RegNum; | 141 V->RegNum = RegNum; |
| 138 V->StackOffset = StackOffset; | 142 V->StackOffset = StackOffset; |
| 139 return V; | 143 return V; |
| 140 } | 144 } |
| 141 | 145 |
| 142 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr, | 146 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr, |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 return nullptr; // conservative answer | 385 return nullptr; // conservative answer |
| 382 SizeT VarNum = Var->getIndex(); | 386 SizeT VarNum = Var->getIndex(); |
| 383 return Metadata[VarNum].getNode(); | 387 return Metadata[VarNum].getNode(); |
| 384 } | 388 } |
| 385 | 389 |
| 386 const InstDefList VariablesMetadata::NoDefinitions; | 390 const InstDefList VariablesMetadata::NoDefinitions; |
| 387 | 391 |
| 388 // ======================== dump routines ======================== // | 392 // ======================== dump routines ======================== // |
| 389 | 393 |
| 390 void Variable::emit(const Cfg *Func) const { | 394 void Variable::emit(const Cfg *Func) const { |
| 391 if (ALLOW_DUMP) | 395 if (buildAllowsDump()) |
| 392 Func->getTarget()->emitVariable(this); | 396 Func->getTarget()->emitVariable(this); |
| 393 } | 397 } |
| 394 | 398 |
| 395 void Variable::dump(const Cfg *Func, Ostream &Str) const { | 399 void Variable::dump(const Cfg *Func, Ostream &Str) const { |
| 396 if (!ALLOW_DUMP) | 400 if (!buildAllowsDump()) |
| 397 return; | 401 return; |
| 398 if (Func == nullptr) { | 402 if (Func == nullptr) { |
| 399 Str << "%" << getName(Func); | 403 Str << "%" << getName(Func); |
| 400 return; | 404 return; |
| 401 } | 405 } |
| 402 if (Func->isVerbose(IceV_RegOrigins) || | 406 if (Func->isVerbose(IceV_RegOrigins) || |
| 403 (!hasReg() && !Func->getTarget()->hasComputedFrame())) | 407 (!hasReg() && !Func->getTarget()->hasComputedFrame())) |
| 404 Str << "%" << getName(Func); | 408 Str << "%" << getName(Func); |
| 405 if (hasReg()) { | 409 if (hasReg()) { |
| 406 if (Func->isVerbose(IceV_RegOrigins)) | 410 if (Func->isVerbose(IceV_RegOrigins)) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 | 444 |
| 441 void ConstantRelocatable::emit(TargetLowering *Target) const { | 445 void ConstantRelocatable::emit(TargetLowering *Target) const { |
| 442 Target->emit(this); | 446 Target->emit(this); |
| 443 } | 447 } |
| 444 | 448 |
| 445 void ConstantRelocatable::emitWithoutPrefix(TargetLowering *Target) const { | 449 void ConstantRelocatable::emitWithoutPrefix(TargetLowering *Target) const { |
| 446 Target->emitWithoutPrefix(this); | 450 Target->emitWithoutPrefix(this); |
| 447 } | 451 } |
| 448 | 452 |
| 449 void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const { | 453 void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const { |
| 450 if (!ALLOW_DUMP) | 454 if (!buildAllowsDump()) |
| 451 return; | 455 return; |
| 452 Str << "@"; | 456 Str << "@"; |
| 453 if (Func && !SuppressMangling) { | 457 if (Func && !SuppressMangling) { |
| 454 Str << Func->getContext()->mangleName(Name); | 458 Str << Func->getContext()->mangleName(Name); |
| 455 } else { | 459 } else { |
| 456 Str << Name; | 460 Str << Name; |
| 457 } | 461 } |
| 458 if (Offset) | 462 if (Offset) |
| 459 Str << "+" << Offset; | 463 Str << "+" << Offset; |
| 460 } | 464 } |
| 461 | 465 |
| 462 void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); } | 466 void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); } |
| 463 | 467 |
| 464 void LiveRange::dump(Ostream &Str) const { | 468 void LiveRange::dump(Ostream &Str) const { |
| 465 if (!ALLOW_DUMP) | 469 if (!buildAllowsDump()) |
| 466 return; | 470 return; |
| 467 Str << "(weight=" << Weight << ") "; | 471 Str << "(weight=" << Weight << ") "; |
| 468 bool First = true; | 472 bool First = true; |
| 469 for (const RangeElementType &I : Range) { | 473 for (const RangeElementType &I : Range) { |
| 470 if (!First) | 474 if (!First) |
| 471 Str << ", "; | 475 Str << ", "; |
| 472 First = false; | 476 First = false; |
| 473 Str << "[" << I.first << ":" << I.second << ")"; | 477 Str << "[" << I.first << ":" << I.second << ")"; |
| 474 } | 478 } |
| 475 } | 479 } |
| 476 | 480 |
| 477 Ostream &operator<<(Ostream &Str, const LiveRange &L) { | 481 Ostream &operator<<(Ostream &Str, const LiveRange &L) { |
| 478 if (!ALLOW_DUMP) | 482 if (!buildAllowsDump()) |
| 479 return Str; | 483 return Str; |
| 480 L.dump(Str); | 484 L.dump(Str); |
| 481 return Str; | 485 return Str; |
| 482 } | 486 } |
| 483 | 487 |
| 484 Ostream &operator<<(Ostream &Str, const RegWeight &W) { | 488 Ostream &operator<<(Ostream &Str, const RegWeight &W) { |
| 485 if (!ALLOW_DUMP) | 489 if (!buildAllowsDump()) |
| 486 return Str; | 490 return Str; |
| 487 if (W.getWeight() == RegWeight::Inf) | 491 if (W.getWeight() == RegWeight::Inf) |
| 488 Str << "Inf"; | 492 Str << "Inf"; |
| 489 else | 493 else |
| 490 Str << W.getWeight(); | 494 Str << W.getWeight(); |
| 491 return Str; | 495 return Str; |
| 492 } | 496 } |
| 493 | 497 |
| 494 // =========== Immediate Randomization and Pooling routines ============== | 498 // =========== Immediate Randomization and Pooling routines ============== |
| 495 // Specialization of the template member function for ConstantInteger32 | 499 // Specialization of the template member function for ConstantInteger32 |
| 496 // TODO(stichnot): try to move this specialization into a target-specific | 500 // TODO(stichnot): try to move this specialization into a target-specific |
| 497 // file. | 501 // file. |
| 498 template <> | 502 template <> |
| 499 bool ConstantInteger32::shouldBeRandomizedOrPooled(const GlobalContext *Ctx) { | 503 bool ConstantInteger32::shouldBeRandomizedOrPooled(const GlobalContext *Ctx) { |
| 500 uint32_t Threshold = Ctx->getFlags().getRandomizeAndPoolImmediatesThreshold(); | 504 uint32_t Threshold = Ctx->getFlags().getRandomizeAndPoolImmediatesThreshold(); |
| 501 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None) | 505 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None) |
| 502 return false; | 506 return false; |
| 503 if (getType() != IceType_i32 && getType() != IceType_i16 && | 507 if (getType() != IceType_i32 && getType() != IceType_i16 && |
| 504 getType() != IceType_i8) | 508 getType() != IceType_i8) |
| 505 return false; | 509 return false; |
| 506 // The Following checks if the signed representation of Value is between | 510 // The Following checks if the signed representation of Value is between |
| 507 // -Threshold/2 and +Threshold/2 | 511 // -Threshold/2 and +Threshold/2 |
| 508 bool largerThanThreshold = Threshold / 2 + Value >= Threshold; | 512 bool largerThanThreshold = Threshold / 2 + Value >= Threshold; |
| 509 return largerThanThreshold; | 513 return largerThanThreshold; |
| 510 } | 514 } |
| 511 | 515 |
| 512 } // end of namespace Ice | 516 } // end of namespace Ice |
| OLD | NEW |