InductionVariable.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #include "Backend.h"
  6. const int InductionVariable::ChangeMagnitudeLimitForLoopCountBasedHoisting = 64 << 10;
  7. InductionVariable::InductionVariable()
  8. #if DBG
  9. : sym(nullptr)
  10. #endif
  11. {
  12. Assert(!IsValid());
  13. }
  14. InductionVariable::InductionVariable(StackSym *const sym, const ValueNumber symValueNumber, const int change)
  15. : sym(sym), symValueNumber(symValueNumber), changeBounds(change, change), isChangeDeterminate(true)
  16. {
  17. Assert(sym);
  18. Assert(!sym->IsTypeSpec());
  19. Assert(IsValid());
  20. }
  21. #if DBG
  22. bool InductionVariable::IsValid() const
  23. {
  24. return !!sym;
  25. }
  26. #endif
  27. StackSym *InductionVariable::Sym() const
  28. {
  29. Assert(IsValid());
  30. return sym;
  31. }
  32. ValueNumber InductionVariable::SymValueNumber() const
  33. {
  34. Assert(IsChangeDeterminate());
  35. return symValueNumber;
  36. }
  37. void InductionVariable::SetSymValueNumber(const ValueNumber symValueNumber)
  38. {
  39. Assert(IsChangeDeterminate());
  40. this->symValueNumber = symValueNumber;
  41. }
  42. bool InductionVariable::IsChangeDeterminate() const
  43. {
  44. Assert(IsValid());
  45. return isChangeDeterminate;
  46. }
  47. void InductionVariable::SetChangeIsIndeterminate()
  48. {
  49. Assert(IsValid());
  50. isChangeDeterminate = false;
  51. }
  52. const IntConstantBounds &InductionVariable::ChangeBounds() const
  53. {
  54. Assert(IsChangeDeterminate());
  55. return changeBounds;
  56. }
  57. bool InductionVariable::IsChangeUnidirectional() const
  58. {
  59. return
  60. (ChangeBounds().LowerBound() >= 0 && ChangeBounds().UpperBound() != 0) ||
  61. (ChangeBounds().UpperBound() <= 0 && ChangeBounds().LowerBound() != 0);
  62. }
  63. bool InductionVariable::Add(const int n)
  64. {
  65. Assert(IsChangeDeterminate());
  66. if(n == 0)
  67. return true;
  68. int newLowerBound;
  69. if(changeBounds.LowerBound() == IntConstMin)
  70. {
  71. if(n >= 0)
  72. {
  73. isChangeDeterminate = false;
  74. return false;
  75. }
  76. newLowerBound = IntConstMin;
  77. }
  78. else if(changeBounds.LowerBound() == IntConstMax)
  79. {
  80. if(n < 0)
  81. {
  82. isChangeDeterminate = false;
  83. return false;
  84. }
  85. newLowerBound = IntConstMax;
  86. }
  87. else if(Int32Math::Add(changeBounds.LowerBound(), n, &newLowerBound))
  88. newLowerBound = n < 0 ? IntConstMin : IntConstMax;
  89. int newUpperBound;
  90. if(changeBounds.UpperBound() == IntConstMin)
  91. {
  92. if(n >= 0)
  93. {
  94. isChangeDeterminate = false;
  95. return false;
  96. }
  97. newUpperBound = IntConstMin;
  98. }
  99. else if(changeBounds.UpperBound() == IntConstMax)
  100. {
  101. if(n < 0)
  102. {
  103. isChangeDeterminate = false;
  104. return false;
  105. }
  106. newUpperBound = IntConstMax;
  107. }
  108. else if(Int32Math::Add(changeBounds.UpperBound(), n, &newUpperBound))
  109. newUpperBound = n < 0 ? IntConstMin : IntConstMax;
  110. changeBounds = IntConstantBounds(newLowerBound, newUpperBound);
  111. return true;
  112. }
  113. void InductionVariable::ExpandInnerLoopChange()
  114. {
  115. Assert(IsValid());
  116. if(!isChangeDeterminate)
  117. return;
  118. changeBounds =
  119. IntConstantBounds(
  120. changeBounds.LowerBound() < 0 ? IntConstMin : changeBounds.LowerBound(),
  121. changeBounds.UpperBound() > 0 ? IntConstMax : changeBounds.UpperBound());
  122. }
  123. void InductionVariable::Merge(const InductionVariable &other)
  124. {
  125. Assert(Sym() == other.Sym());
  126. // The value number may be different, the caller will give the merged info the appropriate value number
  127. isChangeDeterminate &= other.isChangeDeterminate;
  128. if(!isChangeDeterminate)
  129. return;
  130. changeBounds =
  131. IntConstantBounds(
  132. min(changeBounds.LowerBound(), other.changeBounds.LowerBound()),
  133. max(changeBounds.UpperBound(), other.changeBounds.UpperBound()));
  134. }