Path: blob/main/contrib/llvm-project/llvm/lib/Analysis/IVUsers.cpp
35234 views
//===- IVUsers.cpp - Induction Variable Users -------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements bookkeeping for "interesting" users of expressions9// computed from induction variables.10//11//===----------------------------------------------------------------------===//1213#include "llvm/Analysis/IVUsers.h"14#include "llvm/Analysis/AssumptionCache.h"15#include "llvm/Analysis/CodeMetrics.h"16#include "llvm/Analysis/LoopAnalysisManager.h"17#include "llvm/Analysis/LoopInfo.h"18#include "llvm/Analysis/LoopPass.h"19#include "llvm/Analysis/ScalarEvolutionExpressions.h"20#include "llvm/Analysis/ValueTracking.h"21#include "llvm/Config/llvm-config.h"22#include "llvm/IR/DataLayout.h"23#include "llvm/IR/Dominators.h"24#include "llvm/IR/Instructions.h"25#include "llvm/IR/Module.h"26#include "llvm/InitializePasses.h"27#include "llvm/Support/Debug.h"28#include "llvm/Support/raw_ostream.h"29using namespace llvm;3031#define DEBUG_TYPE "iv-users"3233AnalysisKey IVUsersAnalysis::Key;3435IVUsers IVUsersAnalysis::run(Loop &L, LoopAnalysisManager &AM,36LoopStandardAnalysisResults &AR) {37return IVUsers(&L, &AR.AC, &AR.LI, &AR.DT, &AR.SE);38}3940char IVUsersWrapperPass::ID = 0;41INITIALIZE_PASS_BEGIN(IVUsersWrapperPass, "iv-users",42"Induction Variable Users", false, true)43INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)44INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)45INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)46INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)47INITIALIZE_PASS_END(IVUsersWrapperPass, "iv-users", "Induction Variable Users",48false, true)4950Pass *llvm::createIVUsersPass() { return new IVUsersWrapperPass(); }5152/// isInteresting - Test whether the given expression is "interesting" when53/// used by the given expression, within the context of analyzing the54/// given loop.55static bool isInteresting(const SCEV *S, const Instruction *I, const Loop *L,56ScalarEvolution *SE, LoopInfo *LI) {57// An addrec is interesting if it's affine or if it has an interesting start.58if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {59// Keep things simple. Don't touch loop-variant strides unless they're60// only used outside the loop and we can simplify them.61if (AR->getLoop() == L)62return AR->isAffine() ||63(!L->contains(I) &&64SE->getSCEVAtScope(AR, LI->getLoopFor(I->getParent())) != AR);65// Otherwise recurse to see if the start value is interesting, and that66// the step value is not interesting, since we don't yet know how to67// do effective SCEV expansions for addrecs with interesting steps.68return isInteresting(AR->getStart(), I, L, SE, LI) &&69!isInteresting(AR->getStepRecurrence(*SE), I, L, SE, LI);70}7172// An add is interesting if exactly one of its operands is interesting.73if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {74bool AnyInterestingYet = false;75for (const auto *Op : Add->operands())76if (isInteresting(Op, I, L, SE, LI)) {77if (AnyInterestingYet)78return false;79AnyInterestingYet = true;80}81return AnyInterestingYet;82}8384// Nothing else is interesting here.85return false;86}8788/// IVUseShouldUsePostIncValue - We have discovered a "User" of an IV expression89/// and now we need to decide whether the user should use the preinc or post-inc90/// value. If this user should use the post-inc version of the IV, return true.91///92/// Choosing wrong here can break dominance properties (if we choose to use the93/// post-inc value when we cannot) or it can end up adding extra live-ranges to94/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we95/// should use the post-inc value).96static bool IVUseShouldUsePostIncValue(Instruction *User, Value *Operand,97const Loop *L, DominatorTree *DT) {98// If the user is in the loop, use the preinc value.99if (L->contains(User))100return false;101102BasicBlock *LatchBlock = L->getLoopLatch();103if (!LatchBlock)104return false;105106// Ok, the user is outside of the loop. If it is dominated by the latch107// block, use the post-inc value.108if (DT->dominates(LatchBlock, User->getParent()))109return true;110111// There is one case we have to be careful of: PHI nodes. These little guys112// can live in blocks that are not dominated by the latch block, but (since113// their uses occur in the predecessor block, not the block the PHI lives in)114// should still use the post-inc value. Check for this case now.115PHINode *PN = dyn_cast<PHINode>(User);116if (!PN || !Operand)117return false; // not a phi, not dominated by latch block.118119// Look at all of the uses of Operand by the PHI node. If any use corresponds120// to a block that is not dominated by the latch block, give up and use the121// preincremented value.122for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)123if (PN->getIncomingValue(i) == Operand &&124!DT->dominates(LatchBlock, PN->getIncomingBlock(i)))125return false;126127// Okay, all uses of Operand by PN are in predecessor blocks that really are128// dominated by the latch block. Use the post-incremented value.129return true;130}131132/// Inspect the specified instruction. If it is a reducible SCEV, recursively133/// add its users to the IVUsesByStride set and return true. Otherwise, return134/// false.135bool IVUsers::AddUsersIfInteresting(Instruction *I) {136const DataLayout &DL = I->getDataLayout();137138// Add this IV user to the Processed set before returning false to ensure that139// all IV users are members of the set. See IVUsers::isIVUserOrOperand.140if (!Processed.insert(I).second)141return true; // Instruction already handled.142143if (!SE->isSCEVable(I->getType()))144return false; // Void and FP expressions cannot be reduced.145146// IVUsers is used by LSR which assumes that all SCEV expressions are safe to147// pass to SCEVExpander. Expressions are not safe to expand if they represent148// operations that are not safe to speculate, namely integer division.149if (!isa<PHINode>(I) && !isSafeToSpeculativelyExecute(I))150return false;151152// LSR is not APInt clean, do not touch integers bigger than 64-bits.153// Also avoid creating IVs of non-native types. For example, we don't want a154// 64-bit IV in 32-bit code just because the loop has one 64-bit cast.155uint64_t Width = SE->getTypeSizeInBits(I->getType());156if (Width > 64 || !DL.isLegalInteger(Width))157return false;158159// Don't attempt to promote ephemeral values to indvars. They will be removed160// later anyway.161if (EphValues.count(I))162return false;163164// Get the symbolic expression for this instruction.165const SCEV *ISE = SE->getSCEV(I);166167// If we've come to an uninteresting expression, stop the traversal and168// call this a user.169if (!isInteresting(ISE, I, L, SE, LI))170return false;171172SmallPtrSet<Instruction *, 4> UniqueUsers;173for (Use &U : I->uses()) {174Instruction *User = cast<Instruction>(U.getUser());175if (!UniqueUsers.insert(User).second)176continue;177178// Do not infinitely recurse on PHI nodes.179if (isa<PHINode>(User) && Processed.count(User))180continue;181182// Descend recursively, but not into PHI nodes outside the current loop.183// It's important to see the entire expression outside the loop to get184// choices that depend on addressing mode use right, although we won't185// consider references outside the loop in all cases.186// If User is already in Processed, we don't want to recurse into it again,187// but do want to record a second reference in the same instruction.188bool AddUserToIVUsers = false;189if (LI->getLoopFor(User->getParent()) != L) {190if (isa<PHINode>(User) || Processed.count(User) ||191!AddUsersIfInteresting(User)) {192LLVM_DEBUG(dbgs() << "FOUND USER in other loop: " << *User << '\n'193<< " OF SCEV: " << *ISE << '\n');194AddUserToIVUsers = true;195}196} else if (Processed.count(User) || !AddUsersIfInteresting(User)) {197LLVM_DEBUG(dbgs() << "FOUND USER: " << *User << '\n'198<< " OF SCEV: " << *ISE << '\n');199AddUserToIVUsers = true;200}201202if (AddUserToIVUsers) {203// Okay, we found a user that we cannot reduce.204IVStrideUse &NewUse = AddUser(User, I);205// Autodetect the post-inc loop set, populating NewUse.PostIncLoops.206// The regular return value here is discarded; instead of recording207// it, we just recompute it when we need it.208const SCEV *OriginalISE = ISE;209210auto NormalizePred = [&](const SCEVAddRecExpr *AR) {211auto *L = AR->getLoop();212bool Result = IVUseShouldUsePostIncValue(User, I, L, DT);213if (Result)214NewUse.PostIncLoops.insert(L);215return Result;216};217218ISE = normalizeForPostIncUseIf(ISE, NormalizePred, *SE);219220// PostIncNormalization effectively simplifies the expression under221// pre-increment assumptions. Those assumptions (no wrapping) might not222// hold for the post-inc value. Catch such cases by making sure the223// transformation is invertible.224if (OriginalISE != ISE) {225const SCEV *DenormalizedISE =226denormalizeForPostIncUse(ISE, NewUse.PostIncLoops, *SE);227228// If we normalized the expression, but denormalization doesn't give the229// original one, discard this user.230if (OriginalISE != DenormalizedISE) {231LLVM_DEBUG(dbgs()232<< " DISCARDING (NORMALIZATION ISN'T INVERTIBLE): "233<< *ISE << '\n');234IVUses.pop_back();235return false;236}237}238LLVM_DEBUG(if (SE->getSCEV(I) != ISE) dbgs()239<< " NORMALIZED TO: " << *ISE << '\n');240}241}242return true;243}244245IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand) {246IVUses.push_back(new IVStrideUse(this, User, Operand));247return IVUses.back();248}249250IVUsers::IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,251ScalarEvolution *SE)252: L(L), AC(AC), LI(LI), DT(DT), SE(SE) {253// Collect ephemeral values so that AddUsersIfInteresting skips them.254EphValues.clear();255CodeMetrics::collectEphemeralValues(L, AC, EphValues);256257// Find all uses of induction variables in this loop, and categorize258// them by stride. Start by finding all of the PHI nodes in the header for259// this loop. If they are induction variables, inspect their uses.260for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I)261(void)AddUsersIfInteresting(&*I);262}263264void IVUsers::print(raw_ostream &OS, const Module *M) const {265OS << "IV Users for loop ";266L->getHeader()->printAsOperand(OS, false);267if (SE->hasLoopInvariantBackedgeTakenCount(L)) {268OS << " with backedge-taken count " << *SE->getBackedgeTakenCount(L);269}270OS << ":\n";271272for (const IVStrideUse &IVUse : IVUses) {273OS << " ";274IVUse.getOperandValToReplace()->printAsOperand(OS, false);275OS << " = " << *getReplacementExpr(IVUse);276for (const auto *PostIncLoop : IVUse.PostIncLoops) {277OS << " (post-inc with loop ";278PostIncLoop->getHeader()->printAsOperand(OS, false);279OS << ")";280}281OS << " in ";282if (IVUse.getUser())283IVUse.getUser()->print(OS);284else285OS << "Printing <null> User";286OS << '\n';287}288}289290#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)291LLVM_DUMP_METHOD void IVUsers::dump() const { print(dbgs()); }292#endif293294void IVUsers::releaseMemory() {295Processed.clear();296IVUses.clear();297}298299IVUsersWrapperPass::IVUsersWrapperPass() : LoopPass(ID) {300initializeIVUsersWrapperPassPass(*PassRegistry::getPassRegistry());301}302303void IVUsersWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {304AU.addRequired<AssumptionCacheTracker>();305AU.addRequired<LoopInfoWrapperPass>();306AU.addRequired<DominatorTreeWrapperPass>();307AU.addRequired<ScalarEvolutionWrapperPass>();308AU.setPreservesAll();309}310311bool IVUsersWrapperPass::runOnLoop(Loop *L, LPPassManager &LPM) {312auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(313*L->getHeader()->getParent());314auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();315auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();316auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();317318IU.reset(new IVUsers(L, AC, LI, DT, SE));319return false;320}321322void IVUsersWrapperPass::print(raw_ostream &OS, const Module *M) const {323IU->print(OS, M);324}325326void IVUsersWrapperPass::releaseMemory() { IU->releaseMemory(); }327328/// getReplacementExpr - Return a SCEV expression which computes the329/// value of the OperandValToReplace.330const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &IU) const {331return SE->getSCEV(IU.getOperandValToReplace());332}333334/// getExpr - Return the expression for the use.335const SCEV *IVUsers::getExpr(const IVStrideUse &IU) const {336const SCEV *Replacement = getReplacementExpr(IU);337return normalizeForPostIncUse(Replacement, IU.getPostIncLoops(), *SE);338}339340static const SCEVAddRecExpr *findAddRecForLoop(const SCEV *S, const Loop *L) {341if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {342if (AR->getLoop() == L)343return AR;344return findAddRecForLoop(AR->getStart(), L);345}346347if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {348for (const auto *Op : Add->operands())349if (const SCEVAddRecExpr *AR = findAddRecForLoop(Op, L))350return AR;351return nullptr;352}353354return nullptr;355}356357const SCEV *IVUsers::getStride(const IVStrideUse &IU, const Loop *L) const {358const SCEV *Expr = getExpr(IU);359if (!Expr)360return nullptr;361if (const SCEVAddRecExpr *AR = findAddRecForLoop(Expr, L))362return AR->getStepRecurrence(*SE);363return nullptr;364}365366void IVStrideUse::transformToPostInc(const Loop *L) {367PostIncLoops.insert(L);368}369370void IVStrideUse::deleted() {371// Remove this user from the list.372Parent->Processed.erase(this->getUser());373Parent->IVUses.erase(this);374// this now dangles!375}376377378