diff options
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
| -rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 43 | 
1 files changed, 22 insertions, 21 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 800354d2f5b4..a746ddfd7a63 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -629,19 +629,19 @@ static int CompareSCEVComplexity(      const SCEVAddRecExpr *LA = cast<SCEVAddRecExpr>(LHS);      const SCEVAddRecExpr *RA = cast<SCEVAddRecExpr>(RHS); -    // If there is a dominance relationship between the loops, sort by the -    // dominance. Otherwise, sort by depth. We require such order in getAddExpr. +    // There is always a dominance between two recs that are used by one SCEV, +    // so we can safely sort recs by loop header dominance. We require such +    // order in getAddExpr.      const Loop *LLoop = LA->getLoop(), *RLoop = RA->getLoop();      if (LLoop != RLoop) {        const BasicBlock *LHead = LLoop->getHeader(), *RHead = RLoop->getHeader();        assert(LHead != RHead && "Two loops share the same header?");        if (DT.dominates(LHead, RHead))          return 1; -      else if (DT.dominates(RHead, LHead)) -        return -1; -      unsigned LDepth = LLoop->getLoopDepth(), RDepth = RLoop->getLoopDepth(); -      if (LDepth != RDepth) -        return (int)LDepth - (int)RDepth; +      else +        assert(DT.dominates(RHead, LHead) && +               "No dominance between recurrences used by one SCEV?"); +      return -1;      }      // Addrec complexity grows with operand count. @@ -2512,22 +2512,23 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,          SmallVector<const SCEV *, 4> AddRecOps(AddRec->op_begin(),                                                 AddRec->op_end());          for (; OtherIdx != Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]); -             ++OtherIdx) -          if (const auto *OtherAddRec = dyn_cast<SCEVAddRecExpr>(Ops[OtherIdx])) -            if (OtherAddRec->getLoop() == AddRecLoop) { -              for (unsigned i = 0, e = OtherAddRec->getNumOperands(); -                   i != e; ++i) { -                if (i >= AddRecOps.size()) { -                  AddRecOps.append(OtherAddRec->op_begin()+i, -                                   OtherAddRec->op_end()); -                  break; -                } -                SmallVector<const SCEV *, 2> TwoOps = { -                    AddRecOps[i], OtherAddRec->getOperand(i)}; -                AddRecOps[i] = getAddExpr(TwoOps, SCEV::FlagAnyWrap, Depth + 1); +             ++OtherIdx) { +          const auto *OtherAddRec = cast<SCEVAddRecExpr>(Ops[OtherIdx]); +          if (OtherAddRec->getLoop() == AddRecLoop) { +            for (unsigned i = 0, e = OtherAddRec->getNumOperands(); +                 i != e; ++i) { +              if (i >= AddRecOps.size()) { +                AddRecOps.append(OtherAddRec->op_begin()+i, +                                 OtherAddRec->op_end()); +                break;                } -              Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; +              SmallVector<const SCEV *, 2> TwoOps = { +                  AddRecOps[i], OtherAddRec->getOperand(i)}; +              AddRecOps[i] = getAddExpr(TwoOps, SCEV::FlagAnyWrap, Depth + 1);              } +            Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; +          } +        }          // Step size has changed, so we cannot guarantee no self-wraparound.          Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop, SCEV::FlagAnyWrap);          return getAddExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);  | 
