| OLD | NEW |
| 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 // This file declares the Operand class and its target-independent | 10 // This file declares the Operand class and its target-independent |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 // portion. TODO: It's wasteful to penalize all variables on all | 504 // portion. TODO: It's wasteful to penalize all variables on all |
| 505 // targets this way; use a sparser representation. It's also | 505 // targets this way; use a sparser representation. It's also |
| 506 // wasteful for a 64-bit target. | 506 // wasteful for a 64-bit target. |
| 507 Variable *LoVar; | 507 Variable *LoVar; |
| 508 Variable *HiVar; | 508 Variable *HiVar; |
| 509 // VarsReal (and Operand::Vars) are set up such that Vars[0] == | 509 // VarsReal (and Operand::Vars) are set up such that Vars[0] == |
| 510 // this. | 510 // this. |
| 511 Variable *VarsReal[1]; | 511 Variable *VarsReal[1]; |
| 512 }; | 512 }; |
| 513 | 513 |
| 514 enum MetadataKind { |
| 515 VMK_Uses, // Track only uses, not defs |
| 516 VMK_SingleDefs, // Track uses+defs, but only record single def |
| 517 VMK_All // Track uses+defs, including full def list |
| 518 }; |
| 514 typedef std::vector<const Inst *> InstDefList; | 519 typedef std::vector<const Inst *> InstDefList; |
| 515 | 520 |
| 516 // VariableTracking tracks the metadata for a single variable. It is | 521 // VariableTracking tracks the metadata for a single variable. It is |
| 517 // only meant to be used internally by VariablesMetadata. | 522 // only meant to be used internally by VariablesMetadata. |
| 518 class VariableTracking { | 523 class VariableTracking { |
| 519 public: | 524 public: |
| 520 enum MultiDefState { | 525 enum MultiDefState { |
| 521 // TODO(stichnot): Consider using just a simple counter. | 526 // TODO(stichnot): Consider using just a simple counter. |
| 522 MDS_Unknown, | 527 MDS_Unknown, |
| 523 MDS_SingleDef, | 528 MDS_SingleDef, |
| 524 MDS_MultiDefSingleBlock, | 529 MDS_MultiDefSingleBlock, |
| 525 MDS_MultiDefMultiBlock | 530 MDS_MultiDefMultiBlock |
| 526 }; | 531 }; |
| 527 enum MultiBlockState { | 532 enum MultiBlockState { |
| 528 MBS_Unknown, | 533 MBS_Unknown, |
| 529 MBS_SingleBlock, | 534 MBS_SingleBlock, |
| 530 MBS_MultiBlock | 535 MBS_MultiBlock |
| 531 }; | 536 }; |
| 532 VariableTracking() | 537 VariableTracking() |
| 533 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), | 538 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), |
| 534 SingleDefNode(NULL) {} | 539 SingleDefNode(NULL), FirstOrSingleDefinition(NULL) {} |
| 535 MultiDefState getMultiDef() const { return MultiDef; } | 540 MultiDefState getMultiDef() const { return MultiDef; } |
| 536 MultiBlockState getMultiBlock() const { return MultiBlock; } | 541 MultiBlockState getMultiBlock() const { return MultiBlock; } |
| 537 const Inst *getFirstDefinition() const; | 542 const Inst *getFirstDefinition() const; |
| 538 const Inst *getSingleDefinition() const; | 543 const Inst *getSingleDefinition() const; |
| 539 const InstDefList &getDefinitions() const { return Definitions; } | 544 const InstDefList &getLatterDefinitions() const { return Definitions; } |
| 540 const CfgNode *getNode() const { return SingleUseNode; } | 545 const CfgNode *getNode() const { return SingleUseNode; } |
| 541 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef, | 546 void markUse(MetadataKind TrackingKind, const Inst *Instr, |
| 542 bool IsImplicit); | 547 const CfgNode *Node, bool IsFromDef, bool IsImplicit); |
| 543 void markDef(const Inst *Instr, const CfgNode *Node); | 548 void markDef(MetadataKind TrackingKind, const Inst *Instr, |
| 549 const CfgNode *Node); |
| 544 | 550 |
| 545 private: | 551 private: |
| 546 VariableTracking &operator=(const VariableTracking &) = delete; | 552 VariableTracking &operator=(const VariableTracking &) = delete; |
| 547 MultiDefState MultiDef; | 553 MultiDefState MultiDef; |
| 548 MultiBlockState MultiBlock; | 554 MultiBlockState MultiBlock; |
| 549 const CfgNode *SingleUseNode; | 555 const CfgNode *SingleUseNode; |
| 550 const CfgNode *SingleDefNode; | 556 const CfgNode *SingleDefNode; |
| 551 // All definitions of the variable are collected here, in increasing | 557 // All definitions of the variable are collected here, in increasing |
| 552 // order of instruction number. | 558 // order of instruction number. |
| 553 InstDefList Definitions; | 559 InstDefList Definitions; // Only used if Kind==VMK_All |
| 560 const Inst *FirstOrSingleDefinition; // == Definitions[0] if Kind==VMK_All |
| 554 }; | 561 }; |
| 555 | 562 |
| 556 // VariablesMetadata analyzes and summarizes the metadata for the | 563 // VariablesMetadata analyzes and summarizes the metadata for the |
| 557 // complete set of Variables. | 564 // complete set of Variables. |
| 558 class VariablesMetadata { | 565 class VariablesMetadata { |
| 559 public: | 566 public: |
| 560 VariablesMetadata(const Cfg *Func) : Func(Func) {} | 567 VariablesMetadata(const Cfg *Func) : Func(Func) {} |
| 561 // Initialize the state by traversing all instructions/variables in | 568 // Initialize the state by traversing all instructions/variables in |
| 562 // the CFG. | 569 // the CFG. |
| 563 void init(); | 570 void init(MetadataKind TrackingKind); |
| 564 // Returns whether the given Variable is tracked in this object. It | 571 // Returns whether the given Variable is tracked in this object. It |
| 565 // should only return false if changes were made to the CFG after | 572 // should only return false if changes were made to the CFG after |
| 566 // running init(), in which case the state is stale and the results | 573 // running init(), in which case the state is stale and the results |
| 567 // shouldn't be trusted (but it may be OK e.g. for dumping). | 574 // shouldn't be trusted (but it may be OK e.g. for dumping). |
| 568 bool isTracked(const Variable *Var) const { | 575 bool isTracked(const Variable *Var) const { |
| 569 return Var->getIndex() < Metadata.size(); | 576 return Var->getIndex() < Metadata.size(); |
| 570 } | 577 } |
| 571 | 578 |
| 572 // Returns whether the given Variable has multiple definitions. | 579 // Returns whether the given Variable has multiple definitions. |
| 573 bool isMultiDef(const Variable *Var) const; | 580 bool isMultiDef(const Variable *Var) const; |
| 574 // Returns the first definition instruction of the given Variable. | 581 // Returns the first definition instruction of the given Variable. |
| 575 // This is only valid for variables whose definitions are all within | 582 // This is only valid for variables whose definitions are all within |
| 576 // the same block, e.g. T after the lowered sequence "T=B; T+=C; | 583 // the same block, e.g. T after the lowered sequence "T=B; T+=C; |
| 577 // A=T", for which getFirstDefinition(T) would return the "T=B" | 584 // A=T", for which getFirstDefinition(T) would return the "T=B" |
| 578 // instruction. For variables with definitions span multiple | 585 // instruction. For variables with definitions span multiple |
| 579 // blocks, NULL is returned. | 586 // blocks, NULL is returned. |
| 580 const Inst *getFirstDefinition(const Variable *Var) const; | 587 const Inst *getFirstDefinition(const Variable *Var) const; |
| 581 // Returns the definition instruction of the given Variable, when | 588 // Returns the definition instruction of the given Variable, when |
| 582 // the variable has exactly one definition. Otherwise, NULL is | 589 // the variable has exactly one definition. Otherwise, NULL is |
| 583 // returned. | 590 // returned. |
| 584 const Inst *getSingleDefinition(const Variable *Var) const; | 591 const Inst *getSingleDefinition(const Variable *Var) const; |
| 585 // Returns the list of all definition instructions of the given | 592 // Returns the list of all definition instructions of the given |
| 586 // Variable. | 593 // Variable. |
| 587 const InstDefList &getDefinitions(const Variable *Var) const; | 594 const InstDefList &getLatterDefinitions(const Variable *Var) const; |
| 588 | 595 |
| 589 // Returns whether the given Variable is live across multiple | 596 // Returns whether the given Variable is live across multiple |
| 590 // blocks. Mainly, this is used to partition Variables into | 597 // blocks. Mainly, this is used to partition Variables into |
| 591 // single-block versus multi-block sets for leveraging sparsity in | 598 // single-block versus multi-block sets for leveraging sparsity in |
| 592 // liveness analysis, and for implementing simple stack slot | 599 // liveness analysis, and for implementing simple stack slot |
| 593 // coalescing. As a special case, function arguments are always | 600 // coalescing. As a special case, function arguments are always |
| 594 // considered multi-block because they are live coming into the | 601 // considered multi-block because they are live coming into the |
| 595 // entry block. | 602 // entry block. |
| 596 bool isMultiBlock(const Variable *Var) const; | 603 bool isMultiBlock(const Variable *Var) const; |
| 597 // Returns the node that the given Variable is used in, assuming | 604 // Returns the node that the given Variable is used in, assuming |
| 598 // isMultiBlock() returns false. Otherwise, NULL is returned. | 605 // isMultiBlock() returns false. Otherwise, NULL is returned. |
| 599 const CfgNode *getLocalUseNode(const Variable *Var) const; | 606 const CfgNode *getLocalUseNode(const Variable *Var) const; |
| 600 | 607 |
| 601 private: | 608 private: |
| 602 const Cfg *Func; | 609 const Cfg *Func; |
| 610 MetadataKind Kind; |
| 603 std::vector<VariableTracking> Metadata; | 611 std::vector<VariableTracking> Metadata; |
| 604 const static InstDefList NoDefinitions; | 612 const static InstDefList NoDefinitions; |
| 605 VariablesMetadata(const VariablesMetadata &) = delete; | 613 VariablesMetadata(const VariablesMetadata &) = delete; |
| 606 VariablesMetadata &operator=(const VariablesMetadata &) = delete; | 614 VariablesMetadata &operator=(const VariablesMetadata &) = delete; |
| 607 }; | 615 }; |
| 608 | 616 |
| 609 } // end of namespace Ice | 617 } // end of namespace Ice |
| 610 | 618 |
| 611 #endif // SUBZERO_SRC_ICEOPERAND_H | 619 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |