bool LoopReroll::DAGRootTracker::collectUsedInstructions(SmallInstructionSet &PossibleRedSet) {
  // Populate the MapVector with all instructions in the block, in order first,
  // so we can iterate over the contents later in perfect order.
  for (auto &I : *L->getHeader()) {
    Uses[&I].resize(IL_End);
  }

  SmallInstructionSet Exclude;
  Exclude.insert(Roots.begin(), Roots.end());
  Exclude.insert(LoopIncs.begin(), LoopIncs.end());

  DenseSet<Instruction*> VBase;
  collectInLoopUserSet(IV, Exclude, PossibleRedSet, VBase);
  for (auto *I : VBase) {
    Uses[I].set(0);
  }

  unsigned Idx = 1;
  for (auto *Root : Roots) {
    DenseSet<Instruction*> V;
    collectInLoopUserSet(Root, Exclude, PossibleRedSet, V);

    // While we're here, check the use sets are the same size.
    if (V.size() != VBase.size()) {
      DEBUG(dbgs() << "LRR: Aborting - use sets are different sizes\n");
      return false;
    }

    for (auto *I : V) {
      Uses[I].set(Idx);
    }
    ++Idx;
  }

  // Make sure the loop increments are also accounted for.
  Exclude.clear();
  Exclude.insert(Roots.begin(), Roots.end());

  DenseSet<Instruction*> V;
  collectInLoopUserSet(LoopIncs, Exclude, PossibleRedSet, V);
  for (auto *I : V) {
    Uses[I].set(IL_LoopIncIdx);
  }
  if (IV != RealIV)
    Uses[RealIV].set(IL_LoopIncIdx);

  return true;

}
// Collect all root increments with respect to the provided induction variable
// (normally the PHI, but sometimes a multiply). A root increment is an
// instruction, normally an add, with a positive constant less than Scale. In a
// rerollable loop, each of these increments is the root of an instruction
// graph isomorphic to the others. Also, we collect the final induction
// increment (the increment equal to the Scale), and its users in LoopIncs.
bool LoopReroll::collectAllRoots(Loop *L, uint64_t Inc, uint64_t Scale,
                                 Instruction *IV,
                                 SmallVector<SmallInstructionVector, 32> &Roots,
                                 SmallInstructionSet &AllRoots,
                                 SmallInstructionVector &LoopIncs) {
  for (Value::use_iterator UI = IV->use_begin(),
       UIE = IV->use_end(); UI != UIE; ++UI) {
    Instruction *User = cast<Instruction>(*UI);
    if (!SE->isSCEVable(User->getType()))
      continue;
    if (User->getType() != IV->getType())
      continue;
    if (!L->contains(User))
      continue;
    if (hasUsesOutsideLoop(User, L))
      continue;

    if (const SCEVConstant *Diff = dyn_cast<SCEVConstant>(SE->getMinusSCEV(
          SE->getSCEV(User), SE->getSCEV(IV)))) {
      uint64_t Idx = Diff->getValue()->getValue().getZExtValue();
      if (Idx > 0 && Idx < Scale) {
        Roots[Idx-1].push_back(User);
        AllRoots.insert(User);
      } else if (Idx == Scale && Inc > 1) {
        LoopIncs.push_back(User);
      }
    }
  }

  if (Roots[0].empty())
    return false;
  bool AllSame = true;
  for (unsigned i = 1; i < Scale-1; ++i)
    if (Roots[i].size() != Roots[0].size()) {
      AllSame = false;
      break;
    }

  if (!AllSame)
    return false;

  return true;
}