Lifetime.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. class Lifetime
  7. {
  8. public:
  9. Lifetime(JitArenaAllocator * alloc, StackSym *sym, RegNum reg, uint32 start, uint32 end, Func *func)
  10. : sym(sym), reg(reg), start(start), end(end), previousDefBlockNumber(0), defList(alloc),
  11. useList(alloc), lastUseLabel(NULL), region(NULL), isSpilled(false), useCount(0), useCountAdjust(0), allDefsCost(0), isLiveAcrossCalls(false),
  12. isLiveAcrossUserCalls(false), isDeadStore(true), isOpHelperSpilled(false), cantOpHelperSpill(false), isOpHelperSpillAsArg(false),
  13. isFloat(false), isSimd128F4(false), isSimd128I4(false), isSimd128D2(false), cantSpill(false), dontAllocate(false), isSecondChanceAllocated(false), isCheapSpill(false), spillStackSlot(NULL),
  14. totalOpHelperLengthByEnd(0), needsStoreCompensation(false), alloc(alloc), regionUseCount(NULL), regionUseCountAdjust(NULL),
  15. cantStackPack(false)
  16. {
  17. intUsageBv.ClearAll();
  18. regPreference.ClearAll();
  19. }
  20. public:
  21. StackSym * sym;
  22. uint32 * regionUseCount;
  23. uint32 * regionUseCountAdjust;
  24. SList<IR::Instr *> defList;
  25. SList<IR::Instr *> useList;
  26. IR::LabelInstr * lastUseLabel;
  27. Region * region;
  28. StackSlot * spillStackSlot;
  29. JitArenaAllocator * alloc;
  30. BitVector intUsageBv;
  31. BitVector regPreference;
  32. uint32 start;
  33. uint32 end;
  34. uint32 previousDefBlockNumber;
  35. uint32 useCount;
  36. uint32 useCountAdjust;
  37. uint32 allDefsCost;
  38. uint32 lastAllocationStart;
  39. RegNum reg;
  40. uint totalOpHelperLengthByEnd;
  41. uint8 isSpilled:1;
  42. uint8 isLiveAcrossCalls:1;
  43. uint8 isLiveAcrossUserCalls:1;
  44. uint8 isDeadStore:1;
  45. uint8 isOpHelperSpilled:1;
  46. uint8 isOpHelperSpillAsArg : 1;
  47. uint8 cantOpHelperSpill:1;
  48. uint8 isFloat:1;
  49. uint8 isSimd128F4 : 1;
  50. uint8 isSimd128I4 : 1;
  51. uint8 isSimd128D2 : 1;
  52. uint8 cantSpill:1;
  53. uint8 dontAllocate:1;
  54. uint8 isSecondChanceAllocated:1;
  55. uint8 isCheapSpill:1;
  56. uint8 needsStoreCompensation:1;
  57. uint8 cantStackPack : 1;
  58. bool isSimd128()
  59. {
  60. return (isSimd128F4 | isSimd128I4 | isSimd128D2) != 0;
  61. }
  62. void AddToUseCount(uint32 newUseValue, Loop *loop, Func *func)
  63. {
  64. Assert((this->useCount + newUseValue) >= this->useCount);
  65. this->useCount += newUseValue;
  66. if (loop)
  67. {
  68. if (!this->regionUseCount)
  69. {
  70. this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  71. this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  72. }
  73. while (loop)
  74. {
  75. this->regionUseCount[loop->loopNumber] += newUseValue;
  76. loop = loop->parent;
  77. }
  78. }
  79. }
  80. void SubFromUseCount(uint32 newUseValue, Loop *loop)
  81. {
  82. Assert((this->useCount - newUseValue) <= this->useCount);
  83. this->useCount -= newUseValue;
  84. Assert(!loop || this->regionUseCount);
  85. while (loop)
  86. {
  87. Assert((this->regionUseCount[loop->loopNumber] - newUseValue) <= this->regionUseCount[loop->loopNumber]);
  88. this->regionUseCount[loop->loopNumber] -= newUseValue;
  89. loop = loop->parent;
  90. }
  91. }
  92. uint32 GetRegionUseCount(Loop *loop)
  93. {
  94. if (loop && !PHASE_OFF1(Js::RegionUseCountPhase))
  95. {
  96. if (this->regionUseCount)
  97. {
  98. return this->regionUseCount[loop->loopNumber];
  99. }
  100. else
  101. {
  102. return 0;
  103. }
  104. }
  105. else
  106. {
  107. return this->useCount;
  108. }
  109. }
  110. void AddToUseCountAdjust(uint32 newUseValue, Loop *loop, Func *func)
  111. {
  112. Assert((this->useCountAdjust + newUseValue) >= this->useCountAdjust);
  113. this->useCountAdjust += newUseValue;
  114. if (loop)
  115. {
  116. if (!this->regionUseCount)
  117. {
  118. this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  119. this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  120. }
  121. do
  122. {
  123. this->regionUseCountAdjust[loop->loopNumber] += newUseValue;
  124. loop = loop->parent;
  125. } while (loop);
  126. }
  127. }
  128. void ApplyUseCountAdjust(Loop *loop)
  129. {
  130. Assert((this->useCount + this->useCountAdjust) >= this->useCount);
  131. this->useCount -= this->useCountAdjust;
  132. this->useCountAdjust = 0;
  133. if (loop && this->regionUseCount)
  134. {
  135. do
  136. {
  137. Assert((this->regionUseCount[loop->loopNumber] - this->regionUseCountAdjust[loop->loopNumber]) <= this->regionUseCount[loop->loopNumber]);
  138. this->regionUseCount[loop->loopNumber] -= this->regionUseCountAdjust[loop->loopNumber];
  139. this->regionUseCountAdjust[loop->loopNumber] = 0;
  140. loop = loop->parent;
  141. } while (loop);
  142. }
  143. }
  144. };