xref: /openbsd-src/gnu/llvm/llvm/lib/Transforms/Scalar/InstSimplifyPass.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- InstSimplifyPass.cpp -----------------------------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "llvm/Transforms/Scalar/InstSimplifyPass.h"
1009467b48Spatrick #include "llvm/ADT/SmallPtrSet.h"
1109467b48Spatrick #include "llvm/ADT/Statistic.h"
1209467b48Spatrick #include "llvm/Analysis/AssumptionCache.h"
1309467b48Spatrick #include "llvm/Analysis/InstructionSimplify.h"
1409467b48Spatrick #include "llvm/Analysis/OptimizationRemarkEmitter.h"
1509467b48Spatrick #include "llvm/Analysis/TargetLibraryInfo.h"
1609467b48Spatrick #include "llvm/IR/Dominators.h"
1709467b48Spatrick #include "llvm/IR/Function.h"
1809467b48Spatrick #include "llvm/InitializePasses.h"
1909467b48Spatrick #include "llvm/Pass.h"
2073471bf0Spatrick #include "llvm/Transforms/Scalar.h"
2109467b48Spatrick #include "llvm/Transforms/Utils/Local.h"
2273471bf0Spatrick 
2309467b48Spatrick using namespace llvm;
2409467b48Spatrick 
2509467b48Spatrick #define DEBUG_TYPE "instsimplify"
2609467b48Spatrick 
2709467b48Spatrick STATISTIC(NumSimplified, "Number of redundant instructions removed");
2809467b48Spatrick 
runImpl(Function & F,const SimplifyQuery & SQ,OptimizationRemarkEmitter * ORE)2909467b48Spatrick static bool runImpl(Function &F, const SimplifyQuery &SQ,
3009467b48Spatrick                     OptimizationRemarkEmitter *ORE) {
3109467b48Spatrick   SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
3209467b48Spatrick   bool Changed = false;
3309467b48Spatrick 
3409467b48Spatrick   do {
3509467b48Spatrick     for (BasicBlock &BB : F) {
3609467b48Spatrick       // Unreachable code can take on strange forms that we are not prepared to
3709467b48Spatrick       // handle. For example, an instruction may have itself as an operand.
3809467b48Spatrick       if (!SQ.DT->isReachableFromEntry(&BB))
3909467b48Spatrick         continue;
4009467b48Spatrick 
41097a140dSpatrick       SmallVector<WeakTrackingVH, 8> DeadInstsInBB;
4209467b48Spatrick       for (Instruction &I : BB) {
4309467b48Spatrick         // The first time through the loop, ToSimplify is empty and we try to
4409467b48Spatrick         // simplify all instructions. On later iterations, ToSimplify is not
4509467b48Spatrick         // empty and we only bother simplifying instructions that are in it.
4609467b48Spatrick         if (!ToSimplify->empty() && !ToSimplify->count(&I))
4709467b48Spatrick           continue;
4809467b48Spatrick 
4909467b48Spatrick         // Don't waste time simplifying dead/unused instructions.
5009467b48Spatrick         if (isInstructionTriviallyDead(&I)) {
5109467b48Spatrick           DeadInstsInBB.push_back(&I);
5209467b48Spatrick           Changed = true;
5309467b48Spatrick         } else if (!I.use_empty()) {
54*d415bd75Srobert           if (Value *V = simplifyInstruction(&I, SQ, ORE)) {
5509467b48Spatrick             // Mark all uses for resimplification next time round the loop.
5609467b48Spatrick             for (User *U : I.users())
5709467b48Spatrick               Next->insert(cast<Instruction>(U));
5809467b48Spatrick             I.replaceAllUsesWith(V);
5909467b48Spatrick             ++NumSimplified;
6009467b48Spatrick             Changed = true;
6109467b48Spatrick             // A call can get simplified, but it may not be trivially dead.
6209467b48Spatrick             if (isInstructionTriviallyDead(&I))
6309467b48Spatrick               DeadInstsInBB.push_back(&I);
6409467b48Spatrick           }
6509467b48Spatrick         }
6609467b48Spatrick       }
6709467b48Spatrick       RecursivelyDeleteTriviallyDeadInstructions(DeadInstsInBB, SQ.TLI);
6809467b48Spatrick     }
6909467b48Spatrick 
7009467b48Spatrick     // Place the list of instructions to simplify on the next loop iteration
7109467b48Spatrick     // into ToSimplify.
7209467b48Spatrick     std::swap(ToSimplify, Next);
7309467b48Spatrick     Next->clear();
7409467b48Spatrick   } while (!ToSimplify->empty());
7509467b48Spatrick 
7609467b48Spatrick   return Changed;
7709467b48Spatrick }
7809467b48Spatrick 
7909467b48Spatrick namespace {
8009467b48Spatrick struct InstSimplifyLegacyPass : public FunctionPass {
8109467b48Spatrick   static char ID; // Pass identification, replacement for typeid
InstSimplifyLegacyPass__anonf2f0630c0111::InstSimplifyLegacyPass8209467b48Spatrick   InstSimplifyLegacyPass() : FunctionPass(ID) {
8309467b48Spatrick     initializeInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());
8409467b48Spatrick   }
8509467b48Spatrick 
getAnalysisUsage__anonf2f0630c0111::InstSimplifyLegacyPass8609467b48Spatrick   void getAnalysisUsage(AnalysisUsage &AU) const override {
8709467b48Spatrick     AU.setPreservesCFG();
8809467b48Spatrick     AU.addRequired<DominatorTreeWrapperPass>();
8909467b48Spatrick     AU.addRequired<AssumptionCacheTracker>();
9009467b48Spatrick     AU.addRequired<TargetLibraryInfoWrapperPass>();
9109467b48Spatrick     AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
9209467b48Spatrick   }
9309467b48Spatrick 
9409467b48Spatrick   /// Remove instructions that simplify.
runOnFunction__anonf2f0630c0111::InstSimplifyLegacyPass9509467b48Spatrick   bool runOnFunction(Function &F) override {
9609467b48Spatrick     if (skipFunction(F))
9709467b48Spatrick       return false;
9809467b48Spatrick 
9909467b48Spatrick     const DominatorTree *DT =
10009467b48Spatrick         &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
10109467b48Spatrick     const TargetLibraryInfo *TLI =
10209467b48Spatrick         &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
10309467b48Spatrick     AssumptionCache *AC =
10409467b48Spatrick         &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
10509467b48Spatrick     OptimizationRemarkEmitter *ORE =
10609467b48Spatrick         &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
10709467b48Spatrick     const DataLayout &DL = F.getParent()->getDataLayout();
10809467b48Spatrick     const SimplifyQuery SQ(DL, TLI, DT, AC);
10909467b48Spatrick     return runImpl(F, SQ, ORE);
11009467b48Spatrick   }
11109467b48Spatrick };
11209467b48Spatrick } // namespace
11309467b48Spatrick 
11409467b48Spatrick char InstSimplifyLegacyPass::ID = 0;
11509467b48Spatrick INITIALIZE_PASS_BEGIN(InstSimplifyLegacyPass, "instsimplify",
11609467b48Spatrick                       "Remove redundant instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)11709467b48Spatrick INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
11809467b48Spatrick INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
11909467b48Spatrick INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
12009467b48Spatrick INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
12109467b48Spatrick INITIALIZE_PASS_END(InstSimplifyLegacyPass, "instsimplify",
12209467b48Spatrick                     "Remove redundant instructions", false, false)
12309467b48Spatrick 
12409467b48Spatrick // Public interface to the simplify instructions pass.
12509467b48Spatrick FunctionPass *llvm::createInstSimplifyLegacyPass() {
12609467b48Spatrick   return new InstSimplifyLegacyPass();
12709467b48Spatrick }
12809467b48Spatrick 
run(Function & F,FunctionAnalysisManager & AM)12909467b48Spatrick PreservedAnalyses InstSimplifyPass::run(Function &F,
13009467b48Spatrick                                         FunctionAnalysisManager &AM) {
13109467b48Spatrick   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
13209467b48Spatrick   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
13309467b48Spatrick   auto &AC = AM.getResult<AssumptionAnalysis>(F);
13409467b48Spatrick   auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
13509467b48Spatrick   const DataLayout &DL = F.getParent()->getDataLayout();
13609467b48Spatrick   const SimplifyQuery SQ(DL, &TLI, &DT, &AC);
13709467b48Spatrick   bool Changed = runImpl(F, SQ, &ORE);
13809467b48Spatrick   if (!Changed)
13909467b48Spatrick     return PreservedAnalyses::all();
14009467b48Spatrick 
14109467b48Spatrick   PreservedAnalyses PA;
14209467b48Spatrick   PA.preserveSet<CFGAnalyses>();
14309467b48Spatrick   return PA;
14409467b48Spatrick }
145