Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp
35266 views
//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===//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 pass performs lightweight instruction simplification on loop bodies.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Transforms/Scalar/LoopInstSimplify.h"13#include "llvm/ADT/STLExtras.h"14#include "llvm/ADT/SmallPtrSet.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/Statistic.h"17#include "llvm/Analysis/AssumptionCache.h"18#include "llvm/Analysis/InstructionSimplify.h"19#include "llvm/Analysis/LoopInfo.h"20#include "llvm/Analysis/LoopIterator.h"21#include "llvm/Analysis/LoopPass.h"22#include "llvm/Analysis/MemorySSA.h"23#include "llvm/Analysis/MemorySSAUpdater.h"24#include "llvm/Analysis/TargetLibraryInfo.h"25#include "llvm/IR/BasicBlock.h"26#include "llvm/IR/Dominators.h"27#include "llvm/IR/Instruction.h"28#include "llvm/IR/Instructions.h"29#include "llvm/IR/Module.h"30#include "llvm/IR/PassManager.h"31#include "llvm/Support/Casting.h"32#include "llvm/Transforms/Scalar.h"33#include "llvm/Transforms/Utils/Local.h"34#include "llvm/Transforms/Utils/LoopUtils.h"35#include <optional>36#include <utility>3738using namespace llvm;3940#define DEBUG_TYPE "loop-instsimplify"4142STATISTIC(NumSimplified, "Number of redundant instructions simplified");4344static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI,45AssumptionCache &AC, const TargetLibraryInfo &TLI,46MemorySSAUpdater *MSSAU) {47const DataLayout &DL = L.getHeader()->getDataLayout();48SimplifyQuery SQ(DL, &TLI, &DT, &AC);4950// On the first pass over the loop body we try to simplify every instruction.51// On subsequent passes, we can restrict this to only simplifying instructions52// where the inputs have been updated. We end up needing two sets: one53// containing the instructions we are simplifying in *this* pass, and one for54// the instructions we will want to simplify in the *next* pass. We use55// pointers so we can swap between two stably allocated sets.56SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;5758// Track the PHI nodes that have already been visited during each iteration so59// that we can identify when it is necessary to iterate.60SmallPtrSet<PHINode *, 4> VisitedPHIs;6162// While simplifying we may discover dead code or cause code to become dead.63// Keep track of all such instructions and we will delete them at the end.64SmallVector<WeakTrackingVH, 8> DeadInsts;6566// First we want to create an RPO traversal of the loop body. By processing in67// RPO we can ensure that definitions are processed prior to uses (for non PHI68// uses) in all cases. This ensures we maximize the simplifications in each69// iteration over the loop and minimizes the possible causes for continuing to70// iterate.71LoopBlocksRPO RPOT(&L);72RPOT.perform(&LI);73MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr;7475bool Changed = false;76for (;;) {77if (MSSAU && VerifyMemorySSA)78MSSA->verifyMemorySSA();79for (BasicBlock *BB : RPOT) {80for (Instruction &I : *BB) {81if (auto *PI = dyn_cast<PHINode>(&I))82VisitedPHIs.insert(PI);8384if (I.use_empty()) {85if (isInstructionTriviallyDead(&I, &TLI))86DeadInsts.push_back(&I);87continue;88}8990// We special case the first iteration which we can detect due to the91// empty `ToSimplify` set.92bool IsFirstIteration = ToSimplify->empty();9394if (!IsFirstIteration && !ToSimplify->count(&I))95continue;9697Value *V = simplifyInstruction(&I, SQ.getWithInstruction(&I));98if (!V || !LI.replacementPreservesLCSSAForm(&I, V))99continue;100101for (Use &U : llvm::make_early_inc_range(I.uses())) {102auto *UserI = cast<Instruction>(U.getUser());103U.set(V);104105// Do not bother dealing with unreachable code.106if (!DT.isReachableFromEntry(UserI->getParent()))107continue;108109// If the instruction is used by a PHI node we have already processed110// we'll need to iterate on the loop body to converge, so add it to111// the next set.112if (auto *UserPI = dyn_cast<PHINode>(UserI))113if (VisitedPHIs.count(UserPI)) {114Next->insert(UserPI);115continue;116}117118// If we are only simplifying targeted instructions and the user is an119// instruction in the loop body, add it to our set of targeted120// instructions. Because we process defs before uses (outside of PHIs)121// we won't have visited it yet.122//123// We also skip any uses outside of the loop being simplified. Those124// should always be PHI nodes due to LCSSA form, and we don't want to125// try to simplify those away.126assert((L.contains(UserI) || isa<PHINode>(UserI)) &&127"Uses outside the loop should be PHI nodes due to LCSSA!");128if (!IsFirstIteration && L.contains(UserI))129ToSimplify->insert(UserI);130}131132if (MSSAU)133if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V))134if (MemoryAccess *MA = MSSA->getMemoryAccess(&I))135if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI))136MA->replaceAllUsesWith(ReplacementMA);137138assert(I.use_empty() && "Should always have replaced all uses!");139if (isInstructionTriviallyDead(&I, &TLI))140DeadInsts.push_back(&I);141++NumSimplified;142Changed = true;143}144}145146// Delete any dead instructions found thus far now that we've finished an147// iteration over all instructions in all the loop blocks.148if (!DeadInsts.empty()) {149Changed = true;150RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU);151}152153if (MSSAU && VerifyMemorySSA)154MSSA->verifyMemorySSA();155156// If we never found a PHI that needs to be simplified in the next157// iteration, we're done.158if (Next->empty())159break;160161// Otherwise, put the next set in place for the next iteration and reset it162// and the visited PHIs for that iteration.163std::swap(Next, ToSimplify);164Next->clear();165VisitedPHIs.clear();166DeadInsts.clear();167}168169return Changed;170}171172PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,173LoopStandardAnalysisResults &AR,174LPMUpdater &) {175std::optional<MemorySSAUpdater> MSSAU;176if (AR.MSSA) {177MSSAU = MemorySSAUpdater(AR.MSSA);178if (VerifyMemorySSA)179AR.MSSA->verifyMemorySSA();180}181if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI,182MSSAU ? &*MSSAU : nullptr))183return PreservedAnalyses::all();184185auto PA = getLoopPassPreservedAnalyses();186PA.preserveSet<CFGAnalyses>();187if (AR.MSSA)188PA.preserve<MemorySSAAnalysis>();189return PA;190}191192193