Lifetime.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. 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)
  10. :
  11. sym(sym),
  12. regionUseCount(nullptr),
  13. regionUseCountAdjust(nullptr),
  14. defList(alloc),
  15. useList(alloc),
  16. lastUseLabel(nullptr),
  17. region(nullptr),
  18. spillStackSlot(nullptr),
  19. alloc(alloc),
  20. intUsageBv(0),
  21. regPreference(0),
  22. start(start),
  23. end(end),
  24. previousDefBlockNumber(0),
  25. useCount(0),
  26. useCountAdjust(0),
  27. allDefsCost(0),
  28. lastAllocationStart(0),
  29. reg(reg),
  30. totalOpHelperLengthByEnd(0),
  31. isSpilled(false),
  32. isLiveAcrossCalls(false),
  33. isLiveAcrossUserCalls(false),
  34. isDeadStore(true),
  35. isOpHelperSpilled(false),
  36. isOpHelperSpillAsArg(false),
  37. cantOpHelperSpill(false),
  38. cantSpill(false),
  39. dontAllocate(false),
  40. isSecondChanceAllocated(false),
  41. isCheapSpill(false),
  42. needsStoreCompensation(false),
  43. cantStackPack(false),
  44. isFloat(false)
  45. {
  46. }
  47. public:
  48. StackSym * sym;
  49. uint32 * regionUseCount;
  50. uint32 * regionUseCountAdjust;
  51. SList<IR::Instr *> defList;
  52. SList<IR::Instr *> useList;
  53. IR::LabelInstr * lastUseLabel;
  54. Region * region;
  55. StackSlot * spillStackSlot;
  56. JitArenaAllocator * alloc;
  57. BitVector intUsageBv;
  58. BitVector regPreference;
  59. uint32 start;
  60. uint32 end;
  61. uint32 previousDefBlockNumber;
  62. uint32 useCount;
  63. uint32 useCountAdjust;
  64. uint32 allDefsCost;
  65. uint32 lastAllocationStart;
  66. RegNum reg;
  67. uint totalOpHelperLengthByEnd;
  68. uint8 isSpilled:1;
  69. uint8 isLiveAcrossCalls:1;
  70. uint8 isLiveAcrossUserCalls:1;
  71. uint8 isDeadStore:1;
  72. uint8 isOpHelperSpilled:1;
  73. uint8 isOpHelperSpillAsArg : 1;
  74. uint8 cantOpHelperSpill:1;
  75. uint8 cantSpill:1;
  76. uint8 dontAllocate:1;
  77. uint8 isSecondChanceAllocated:1;
  78. uint8 isCheapSpill:1;
  79. uint8 needsStoreCompensation:1;
  80. uint8 cantStackPack : 1;
  81. uint8 isFloat : 1;
  82. bool IsInt()
  83. {
  84. return !isFloat;
  85. }
  86. void AddToUseCount(uint32 newUseValue, Loop *loop, Func *func)
  87. {
  88. Assert((this->useCount + newUseValue) >= this->useCount);
  89. this->useCount += newUseValue;
  90. if (loop)
  91. {
  92. if (!this->regionUseCount)
  93. {
  94. this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  95. this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  96. }
  97. while (loop)
  98. {
  99. this->regionUseCount[loop->loopNumber] += newUseValue;
  100. loop = loop->parent;
  101. }
  102. }
  103. }
  104. void SubFromUseCount(uint32 newUseValue, Loop *loop)
  105. {
  106. Assert((this->useCount - newUseValue) <= this->useCount);
  107. this->useCount -= newUseValue;
  108. Assert(!loop || this->regionUseCount);
  109. while (loop)
  110. {
  111. Assert((this->regionUseCount[loop->loopNumber] - newUseValue) <= this->regionUseCount[loop->loopNumber]);
  112. this->regionUseCount[loop->loopNumber] -= newUseValue;
  113. loop = loop->parent;
  114. }
  115. }
  116. uint32 GetRegionUseCount(Loop *loop)
  117. {
  118. if (loop && !PHASE_OFF1(Js::RegionUseCountPhase))
  119. {
  120. if (this->regionUseCount)
  121. {
  122. return this->regionUseCount[loop->loopNumber];
  123. }
  124. else
  125. {
  126. return 0;
  127. }
  128. }
  129. else
  130. {
  131. return this->useCount;
  132. }
  133. }
  134. void AddToUseCountAdjust(uint32 newUseValue, Loop *loop, Func *func)
  135. {
  136. Assert((this->useCountAdjust + newUseValue) >= this->useCountAdjust);
  137. this->useCountAdjust += newUseValue;
  138. if (loop)
  139. {
  140. if (!this->regionUseCount)
  141. {
  142. this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  143. this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
  144. }
  145. do
  146. {
  147. this->regionUseCountAdjust[loop->loopNumber] += newUseValue;
  148. loop = loop->parent;
  149. } while (loop);
  150. }
  151. }
  152. void ApplyUseCountAdjust(Loop *loop)
  153. {
  154. Assert((this->useCount + this->useCountAdjust) >= this->useCount);
  155. this->useCount -= this->useCountAdjust;
  156. this->useCountAdjust = 0;
  157. if (loop && this->regionUseCount)
  158. {
  159. do
  160. {
  161. Assert((this->regionUseCount[loop->loopNumber] - this->regionUseCountAdjust[loop->loopNumber]) <= this->regionUseCount[loop->loopNumber]);
  162. this->regionUseCount[loop->loopNumber] -= this->regionUseCountAdjust[loop->loopNumber];
  163. this->regionUseCountAdjust[loop->loopNumber] = 0;
  164. loop = loop->parent;
  165. } while (loop);
  166. }
  167. }
  168. };