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

Side by Side Diff: src/IceOperand.h

Issue 589003002: Subzero: Refactor tracking of Defs and block-local Variables. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: "Mark args as being used in the entry node" was unnecessary. Created 6 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/IceLiveness.cpp ('k') | src/IceOperand.cpp » ('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 // This file declares the Operand class and its target-independent 10 // This file declares the Operand class and its target-independent
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 Ostream &operator<<(Ostream &Str, const LiveRange &L); 340 Ostream &operator<<(Ostream &Str, const LiveRange &L);
341 341
342 // Variable represents an operand that is register-allocated or 342 // Variable represents an operand that is register-allocated or
343 // stack-allocated. If it is register-allocated, it will ultimately 343 // stack-allocated. If it is register-allocated, it will ultimately
344 // have a non-negative RegNum field. 344 // have a non-negative RegNum field.
345 class Variable : public Operand { 345 class Variable : public Operand {
346 Variable(const Variable &) LLVM_DELETED_FUNCTION; 346 Variable(const Variable &) LLVM_DELETED_FUNCTION;
347 Variable &operator=(const Variable &) LLVM_DELETED_FUNCTION; 347 Variable &operator=(const Variable &) LLVM_DELETED_FUNCTION;
348 348
349 public: 349 public:
350 static Variable *create(Cfg *Func, Type Ty, const CfgNode *Node, SizeT Index, 350 static Variable *create(Cfg *Func, Type Ty, SizeT Index,
351 const IceString &Name) { 351 const IceString &Name) {
352 return new (Func->allocate<Variable>()) 352 return new (Func->allocate<Variable>())
353 Variable(kVariable, Ty, Node, Index, Name); 353 Variable(kVariable, Ty, Index, Name);
354 } 354 }
355 355
356 SizeT getIndex() const { return Number; } 356 SizeT getIndex() const { return Number; }
357 IceString getName() const; 357 IceString getName() const;
358 void setName(IceString &NewName) { 358 void setName(IceString &NewName) {
359 // Make sure that the name can only be set once. 359 // Make sure that the name can only be set once.
360 assert(Name.empty()); 360 assert(Name.empty());
361 Name = NewName; 361 Name = NewName;
362 } 362 }
363 363
364 Inst *getDefinition() const { return DefInst; }
365 void setDefinition(Inst *Inst, const CfgNode *Node);
366 void replaceDefinition(Inst *Inst, const CfgNode *Node);
367
368 const CfgNode *getLocalUseNode() const { return DefNode; }
369 bool isMultiblockLife() const { return (DefNode == NULL); }
370 void setUse(const Inst *Inst, const CfgNode *Node);
371
372 // Multidef means a variable is non-SSA and has multiple defining
373 // instructions. Currently this classification is limited to SSA
374 // lowering temporaries where the definitions are in different basic
375 // blocks, and it is not maintained during target lowering when the
376 // same temporary may be updated in consecutive instructions.
377 bool getIsMultidef() const { return IsMultidef; }
378 void setIsMultidef() { IsMultidef = true; }
379
380 bool getIsArg() const { return IsArgument; } 364 bool getIsArg() const { return IsArgument; }
381 void setIsArg(Cfg *Func, bool IsArg = true); 365 void setIsArg(bool Val = true) { IsArgument = Val; }
366 bool getIsImplicitArg() const { return IsImplicitArgument; }
367 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; }
382 368
383 int32_t getStackOffset() const { return StackOffset; } 369 int32_t getStackOffset() const { return StackOffset; }
384 void setStackOffset(int32_t Offset) { StackOffset = Offset; } 370 void setStackOffset(int32_t Offset) { StackOffset = Offset; }
385 371
386 static const int32_t NoRegister = -1; 372 static const int32_t NoRegister = -1;
387 bool hasReg() const { return getRegNum() != NoRegister; } 373 bool hasReg() const { return getRegNum() != NoRegister; }
388 int32_t getRegNum() const { return RegNum; } 374 int32_t getRegNum() const { return RegNum; }
389 void setRegNum(int32_t NewRegNum) { 375 void setRegNum(int32_t NewRegNum) {
390 // Regnum shouldn't be set more than once. 376 // Regnum shouldn't be set more than once.
391 assert(!hasReg() || RegNum == NewRegNum); 377 assert(!hasReg() || RegNum == NewRegNum);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 426
441 static bool classof(const Operand *Operand) { 427 static bool classof(const Operand *Operand) {
442 OperandKind Kind = Operand->getKind(); 428 OperandKind Kind = Operand->getKind();
443 return Kind >= kVariable && Kind <= kVariable_Num; 429 return Kind >= kVariable && Kind <= kVariable_Num;
444 } 430 }
445 431
446 // The destructor is public because of the asType() method. 432 // The destructor is public because of the asType() method.
447 virtual ~Variable() {} 433 virtual ~Variable() {}
448 434
449 protected: 435 protected:
450 Variable(OperandKind K, Type Ty, const CfgNode *Node, SizeT Index, 436 Variable(OperandKind K, Type Ty, SizeT Index, const IceString &Name)
451 const IceString &Name) 437 : Operand(K, Ty), Number(Index), Name(Name), IsArgument(false),
452 : Operand(K, Ty), Number(Index), Name(Name), DefInst(NULL), DefNode(Node), 438 IsImplicitArgument(false), StackOffset(0), RegNum(NoRegister),
453 IsMultidef(false), IsArgument(false), StackOffset(0), 439 RegNumTmp(NoRegister), Weight(1), RegisterPreference(NULL),
454 RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), 440 AllowRegisterOverlap(false), LoVar(NULL), HiVar(NULL) {
455 RegisterPreference(NULL), AllowRegisterOverlap(false), LoVar(NULL),
456 HiVar(NULL) {
457 Vars = VarsReal; 441 Vars = VarsReal;
458 Vars[0] = this; 442 Vars[0] = this;
459 NumVars = 1; 443 NumVars = 1;
460 } 444 }
461 // Number is unique across all variables, and is used as a 445 // Number is unique across all variables, and is used as a
462 // (bit)vector index for liveness analysis. 446 // (bit)vector index for liveness analysis.
463 const SizeT Number; 447 const SizeT Number;
464 // Name is optional. 448 // Name is optional.
465 IceString Name; 449 IceString Name;
466 // DefInst is the instruction that produces this variable as its
467 // dest.
468 Inst *DefInst;
469 // DefNode is the node where this variable was produced, and is
470 // reset to NULL if it is used outside that node. This is used for
471 // detecting isMultiblockLife(). TODO: Collapse this to a single
472 // bit and use a separate pass to calculate the values across the
473 // Cfg. This saves space in the Variable, and removes the fragility
474 // of incrementally computing and maintaining the information.
475 const CfgNode *DefNode;
476 bool IsMultidef;
477 bool IsArgument; 450 bool IsArgument;
451 bool IsImplicitArgument;
478 // StackOffset is the canonical location on stack (only if 452 // StackOffset is the canonical location on stack (only if
479 // RegNum<0 || IsArgument). 453 // RegNum<0 || IsArgument).
480 int32_t StackOffset; 454 int32_t StackOffset;
481 // RegNum is the allocated register, or NoRegister if it isn't 455 // RegNum is the allocated register, or NoRegister if it isn't
482 // register-allocated. 456 // register-allocated.
483 int32_t RegNum; 457 int32_t RegNum;
484 // RegNumTmp is the tentative assignment during register allocation. 458 // RegNumTmp is the tentative assignment during register allocation.
485 int32_t RegNumTmp; 459 int32_t RegNumTmp;
486 RegWeight Weight; // Register allocation priority 460 RegWeight Weight; // Register allocation priority
487 // RegisterPreference says that if possible, the register allocator 461 // RegisterPreference says that if possible, the register allocator
(...skipping 14 matching lines...) Expand all
502 // portion. TODO: It's wasteful to penalize all variables on all 476 // portion. TODO: It's wasteful to penalize all variables on all
503 // targets this way; use a sparser representation. It's also 477 // targets this way; use a sparser representation. It's also
504 // wasteful for a 64-bit target. 478 // wasteful for a 64-bit target.
505 Variable *LoVar; 479 Variable *LoVar;
506 Variable *HiVar; 480 Variable *HiVar;
507 // VarsReal (and Operand::Vars) are set up such that Vars[0] == 481 // VarsReal (and Operand::Vars) are set up such that Vars[0] ==
508 // this. 482 // this.
509 Variable *VarsReal[1]; 483 Variable *VarsReal[1];
510 }; 484 };
511 485
486 // VariableTracking tracks the metadata for a single variable.
487 class VariableTracking {
488 public:
489 enum MultiDefState {
490 // TODO(stichnot): Consider using just a simple counter.
491 MDS_Unknown,
492 MDS_SingleDef,
493 MDS_MultiDef
494 };
495 enum MultiBlockState {
496 MBS_Unknown,
497 MBS_SingleBlock,
498 MBS_MultiBlock
499 };
500 VariableTracking()
501 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL),
502 SingleDefInst(NULL) {}
503 MultiDefState getMultiDef() const { return MultiDef; }
504 MultiBlockState getMultiBlock() const { return MultiBlock; }
505 const Inst *getDefinition() const { return SingleDefInst; }
506 const CfgNode *getNode() const { return SingleUseNode; }
507 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef,
508 bool IsImplicit);
509 void markDef(const Inst *Instr, const CfgNode *Node);
510
511 private:
512 VariableTracking &operator=(const VariableTracking &) LLVM_DELETED_FUNCTION;
513 MultiDefState MultiDef;
514 MultiBlockState MultiBlock;
515 const CfgNode *SingleUseNode;
516 const Inst *SingleDefInst;
517 };
518
519 // VariablesMetadata analyzes and summarizes the metadata for the
520 // complete set of Variables.
521 class VariablesMetadata {
522 public:
523 VariablesMetadata(const Cfg *Func) : Func(Func) {}
524 void init();
525 bool isTracked(const Variable *Var) const {
526 return Var->getIndex() < Metadata.size();
527 }
528 bool isMultiDef(const Variable *Var) const;
529 const Inst *getDefinition(const Variable *Var) const;
530 bool isMultiBlock(const Variable *Var) const;
531 const CfgNode *getLocalUseNode(const Variable *Var) const;
532
533 private:
534 const Cfg *Func;
535 std::vector<VariableTracking> Metadata;
536 VariablesMetadata(const VariablesMetadata &) LLVM_DELETED_FUNCTION;
537 VariablesMetadata &operator=(const VariablesMetadata &) LLVM_DELETED_FUNCTION;
538 };
539
512 } // end of namespace Ice 540 } // end of namespace Ice
513 541
514 #endif // SUBZERO_SRC_ICEOPERAND_H 542 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW
« no previous file with comments | « src/IceLiveness.cpp ('k') | src/IceOperand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698