Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: src/IceOperand.h

Issue 1326013002: Refactor Lo and Hi out of Variable. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Refactor Hi and Lo out of Variable Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInst.cpp ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===//
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 25 matching lines...) Expand all
36 kConst_Base, 36 kConst_Base,
37 kConstInteger32, 37 kConstInteger32,
38 kConstInteger64, 38 kConstInteger64,
39 kConstFloat, 39 kConstFloat,
40 kConstDouble, 40 kConstDouble,
41 kConstRelocatable, 41 kConstRelocatable,
42 kConstUndef, 42 kConstUndef,
43 kConst_Target, // leave space for target-specific constant kinds 43 kConst_Target, // leave space for target-specific constant kinds
44 kConst_Max = kConst_Target + MaxTargetKinds, 44 kConst_Max = kConst_Target + MaxTargetKinds,
45 kVariable, 45 kVariable,
46 kVariable64On32,
46 kVariable_Target, // leave space for target-specific variable kinds 47 kVariable_Target, // leave space for target-specific variable kinds
47 kVariable_Max = kVariable_Target + MaxTargetKinds, 48 kVariable_Max = kVariable_Target + MaxTargetKinds,
48 // Target-specific operand classes use kTarget as the starting point for 49 // Target-specific operand classes use kTarget as the starting point for
49 // their Kind enum space. Note that the value-spaces are shared across 50 // their Kind enum space. Note that the value-spaces are shared across
50 // targets. To avoid confusion over the definition of shared values, an 51 // targets. To avoid confusion over the definition of shared values, an
51 // object specific to one target should never be passed to a different 52 // object specific to one target should never be passed to a different
52 // target. 53 // target.
53 kTarget, 54 kTarget,
54 kTarget_Max = std::numeric_limits<uint8_t>::max(), 55 kTarget_Max = std::numeric_limits<uint8_t>::max(),
55 }; 56 };
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 Ostream &operator<<(Ostream &Str, const LiveRange &L); 405 Ostream &operator<<(Ostream &Str, const LiveRange &L);
405 406
406 /// Variable represents an operand that is register-allocated or 407 /// Variable represents an operand that is register-allocated or
407 /// stack-allocated. If it is register-allocated, it will ultimately have a 408 /// stack-allocated. If it is register-allocated, it will ultimately have a
408 /// non-negative RegNum field. 409 /// non-negative RegNum field.
409 class Variable : public Operand { 410 class Variable : public Operand {
410 Variable() = delete; 411 Variable() = delete;
411 Variable(const Variable &) = delete; 412 Variable(const Variable &) = delete;
412 Variable &operator=(const Variable &) = delete; 413 Variable &operator=(const Variable &) = delete;
413 414
414 enum RegRequirement { 415 enum RegRequirement : uint8_t {
415 RR_MayHaveRegister, 416 RR_MayHaveRegister,
416 RR_MustHaveRegister, 417 RR_MustHaveRegister,
417 RR_MustNotHaveRegister, 418 RR_MustNotHaveRegister,
418 }; 419 };
419 420
420 public: 421 public:
421 static Variable *create(Cfg *Func, Type Ty, SizeT Index) { 422 static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
422 return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index); 423 return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index);
423 } 424 }
424 425
425 SizeT getIndex() const { return Number; } 426 SizeT getIndex() const { return Number; }
426 IceString getName(const Cfg *Func) const; 427 IceString getName(const Cfg *Func) const;
427 void setName(Cfg *Func, const IceString &NewName) { 428 virtual void setName(Cfg *Func, const IceString &NewName) {
428 // Make sure that the name can only be set once. 429 // Make sure that the name can only be set once.
429 assert(NameIndex == Cfg::IdentifierIndexInvalid); 430 assert(NameIndex == Cfg::IdentifierIndexInvalid);
430 if (!NewName.empty()) 431 if (!NewName.empty())
431 NameIndex = Func->addIdentifierName(NewName); 432 NameIndex = Func->addIdentifierName(NewName);
432 } 433 }
433 434
434 bool getIsArg() const { return IsArgument; } 435 bool getIsArg() const { return IsArgument; }
435 void setIsArg(bool Val = true) { IsArgument = Val; } 436 virtual void setIsArg(bool Val = true) { IsArgument = Val; }
436 bool getIsImplicitArg() const { return IsImplicitArgument; } 437 bool getIsImplicitArg() const { return IsImplicitArgument; }
437 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; } 438 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; }
438 439
439 void setIgnoreLiveness() { IgnoreLiveness = true; } 440 void setIgnoreLiveness() { IgnoreLiveness = true; }
440 bool getIgnoreLiveness() const { return IgnoreLiveness; } 441 bool getIgnoreLiveness() const { return IgnoreLiveness; }
441 442
442 int32_t getStackOffset() const { return StackOffset; } 443 int32_t getStackOffset() const { return StackOffset; }
443 void setStackOffset(int32_t Offset) { StackOffset = Offset; } 444 void setStackOffset(int32_t Offset) { StackOffset = Offset; }
444 445
445 static const int32_t NoRegister = -1; 446 static const int32_t NoRegister = -1;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 } 479 }
479 bool rangeOverlaps(const Variable *Other) const { 480 bool rangeOverlaps(const Variable *Other) const {
480 const bool UseTrimmed = true; 481 const bool UseTrimmed = true;
481 return Live.overlaps(Other->Live, UseTrimmed); 482 return Live.overlaps(Other->Live, UseTrimmed);
482 } 483 }
483 bool rangeOverlapsStart(const Variable *Other) const { 484 bool rangeOverlapsStart(const Variable *Other) const {
484 const bool UseTrimmed = true; 485 const bool UseTrimmed = true;
485 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed); 486 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed);
486 } 487 }
487 488
488 Variable *getLo() const { return LoVar; }
489 Variable *getHi() const { return HiVar; }
490 void setLoHi(Variable *Lo, Variable *Hi) {
491 assert(LoVar == nullptr);
492 assert(HiVar == nullptr);
493 LoVar = Lo;
494 HiVar = Hi;
495 }
496 /// Creates a temporary copy of the variable with a different type. Used 489 /// Creates a temporary copy of the variable with a different type. Used
497 /// primarily for syntactic correctness of textual assembly emission. Note 490 /// primarily for syntactic correctness of textual assembly emission. Note
498 /// that only basic information is copied, in particular not IsArgument, 491 /// that only basic information is copied, in particular not IsArgument,
499 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar, 492 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
500 /// VarsReal. 493 /// VarsReal.
501 Variable *asType(Type Ty); 494 Variable *asType(Type Ty);
502 495
503 void emit(const Cfg *Func) const override; 496 void emit(const Cfg *Func) const override;
504 using Operand::dump; 497 using Operand::dump;
505 void dump(const Cfg *Func, Ostream &Str) const override; 498 void dump(const Cfg *Func, Ostream &Str) const override;
(...skipping 16 matching lines...) Expand all
522 /// Number is unique across all variables, and is used as a (bit)vector index 515 /// Number is unique across all variables, and is used as a (bit)vector index
523 /// for liveness analysis. 516 /// for liveness analysis.
524 const SizeT Number; 517 const SizeT Number;
525 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; 518 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid;
526 bool IsArgument = false; 519 bool IsArgument = false;
527 bool IsImplicitArgument = false; 520 bool IsImplicitArgument = false;
528 /// IgnoreLiveness means that the variable should be ignored when constructing 521 /// IgnoreLiveness means that the variable should be ignored when constructing
529 /// and validating live ranges. This is usually reserved for the stack 522 /// and validating live ranges. This is usually reserved for the stack
530 /// pointer. 523 /// pointer.
531 bool IgnoreLiveness = false; 524 bool IgnoreLiveness = false;
532 /// StackOffset is the canonical location on stack (only if RegNum==NoRegister 525 RegRequirement RegRequirement = RR_MayHaveRegister;
533 /// || IsArgument).
534 int32_t StackOffset = 0;
535 /// RegNum is the allocated register, or NoRegister if it isn't 526 /// RegNum is the allocated register, or NoRegister if it isn't
536 /// register-allocated. 527 /// register-allocated.
537 int32_t RegNum = NoRegister; 528 int32_t RegNum = NoRegister;
538 /// RegNumTmp is the tentative assignment during register allocation. 529 /// RegNumTmp is the tentative assignment during register allocation.
539 int32_t RegNumTmp = NoRegister; 530 int32_t RegNumTmp = NoRegister;
540 RegRequirement RegRequirement = RR_MayHaveRegister; 531 /// StackOffset is the canonical location on stack (only if
532 /// RegNum==NoRegister || IsArgument).
533 int32_t StackOffset = 0;
541 LiveRange Live; 534 LiveRange Live;
542 // LoVar and HiVar are needed for lowering from 64 to 32 bits. When lowering 535 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
543 // from I64 to I32 on a 32-bit architecture, we split the variable into two 536 Variable *VarsReal[1];
544 // machine-size pieces. LoVar is the low-order machine-size portion, and 537 };
545 // HiVar is the remaining high-order portion. 538
546 // TODO: It's wasteful to penalize all variables on all targets this way; use 539 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In
547 // a sparser representation. It's also wasteful for a 64-bit target. 540 // this situation the variable must be split into a low and a high word.
541 class Variable64On32 : public Variable {
542 Variable64On32() = delete;
543 Variable64On32(const Variable64On32 &) = delete;
544 Variable64On32 &operator=(const Variable64On32 &) = delete;
545
546 public:
547 static Variable64On32 *create(Cfg *Func, Type Ty, SizeT Index) {
548 return new (Func->allocate<Variable64On32>()) Variable64On32(
549 kVariable64On32, Ty, Index);
550 }
551
552 void setName(Cfg *Func, const IceString &NewName) override {
553 Variable::setName(Func, NewName);
554 if (LoVar && HiVar) {
555 LoVar->setName(Func, getName(Func) + "__lo");
556 HiVar->setName(Func, getName(Func) + "__hi");
557 }
558 }
559
560 void setIsArg(bool Val = true) override {
561 Variable::setIsArg(Val);
562 if (LoVar && HiVar) {
563 LoVar->setIsArg(Val);
564 HiVar->setIsArg(Val);
565 }
566 }
567
568 Variable *getLo() const {
569 assert(LoVar != nullptr);
570 return LoVar;
571 }
572 Variable *getHi() const {
573 assert(HiVar != nullptr);
574 return HiVar;
575 }
576
577 void initHiLo(Cfg *Func) {
578 assert(LoVar == nullptr);
579 assert(HiVar == nullptr);
580 LoVar = Func->makeVariable(IceType_i32);
581 HiVar = Func->makeVariable(IceType_i32);
582 LoVar->setIsArg(getIsArg());
583 HiVar->setIsArg(getIsArg());
584 LoVar->setName(Func, getName(Func) + "__lo");
585 HiVar->setName(Func, getName(Func) + "__hi");
586 }
587
588 static bool classof(const Operand *Operand) {
589 OperandKind Kind = Operand->getKind();
590 return Kind == kVariable64On32;
591 }
592
593 protected:
594 Variable64On32(OperandKind K, Type Ty, SizeT Index)
595 : Variable(K, Ty, Index) {
596 assert(typeWidthInBytes(Ty) == 8);
597 }
598
548 Variable *LoVar = nullptr; 599 Variable *LoVar = nullptr;
549 Variable *HiVar = nullptr; 600 Variable *HiVar = nullptr;
550 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
551 Variable *VarsReal[1];
552 }; 601 };
553 602
554 enum MetadataKind { 603 enum MetadataKind {
555 VMK_Uses, /// Track only uses, not defs 604 VMK_Uses, /// Track only uses, not defs
556 VMK_SingleDefs, /// Track uses+defs, but only record single def 605 VMK_SingleDefs, /// Track uses+defs, but only record single def
557 VMK_All /// Track uses+defs, including full def list 606 VMK_All /// Track uses+defs, including full def list
558 }; 607 };
559 using InstDefList = CfgVector<const Inst *>; 608 using InstDefList = CfgVector<const Inst *>;
560 609
561 /// VariableTracking tracks the metadata for a single variable. It is 610 /// VariableTracking tracks the metadata for a single variable. It is
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 private: 701 private:
653 const Cfg *Func; 702 const Cfg *Func;
654 MetadataKind Kind; 703 MetadataKind Kind;
655 CfgVector<VariableTracking> Metadata; 704 CfgVector<VariableTracking> Metadata;
656 const static InstDefList NoDefinitions; 705 const static InstDefList NoDefinitions;
657 }; 706 };
658 707
659 } // end of namespace Ice 708 } // end of namespace Ice
660 709
661 #endif // SUBZERO_SRC_ICEOPERAND_H 710 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW
« no previous file with comments | « src/IceInst.cpp ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698