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; }