Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/InstSimplifyPass.cpp
35269 views
//===- InstSimplifyPass.cpp -----------------------------------------------===//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//===----------------------------------------------------------------------===//78#include "llvm/Transforms/Scalar/InstSimplifyPass.h"9#include "llvm/ADT/SmallPtrSet.h"10#include "llvm/ADT/Statistic.h"11#include "llvm/Analysis/AssumptionCache.h"12#include "llvm/Analysis/InstructionSimplify.h"13#include "llvm/Analysis/TargetLibraryInfo.h"14#include "llvm/IR/Dominators.h"15#include "llvm/IR/Function.h"16#include "llvm/InitializePasses.h"17#include "llvm/Pass.h"18#include "llvm/Transforms/Scalar.h"19#include "llvm/Transforms/Utils/Local.h"2021using namespace llvm;2223#define DEBUG_TYPE "instsimplify"2425STATISTIC(NumSimplified, "Number of redundant instructions removed");2627static bool runImpl(Function &F, const SimplifyQuery &SQ) {28SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;29bool Changed = false;3031do {32for (BasicBlock &BB : F) {33// Unreachable code can take on strange forms that we are not prepared to34// handle. For example, an instruction may have itself as an operand.35if (!SQ.DT->isReachableFromEntry(&BB))36continue;3738SmallVector<WeakTrackingVH, 8> DeadInstsInBB;39for (Instruction &I : BB) {40// The first time through the loop, ToSimplify is empty and we try to41// simplify all instructions. On later iterations, ToSimplify is not42// empty and we only bother simplifying instructions that are in it.43if (!ToSimplify->empty() && !ToSimplify->count(&I))44continue;4546// Don't waste time simplifying dead/unused instructions.47if (isInstructionTriviallyDead(&I)) {48DeadInstsInBB.push_back(&I);49Changed = true;50} else if (!I.use_empty()) {51if (Value *V = simplifyInstruction(&I, SQ)) {52// Mark all uses for resimplification next time round the loop.53for (User *U : I.users())54Next->insert(cast<Instruction>(U));55I.replaceAllUsesWith(V);56++NumSimplified;57Changed = true;58// A call can get simplified, but it may not be trivially dead.59if (isInstructionTriviallyDead(&I))60DeadInstsInBB.push_back(&I);61}62}63}64RecursivelyDeleteTriviallyDeadInstructions(DeadInstsInBB, SQ.TLI);65}6667// Place the list of instructions to simplify on the next loop iteration68// into ToSimplify.69std::swap(ToSimplify, Next);70Next->clear();71} while (!ToSimplify->empty());7273return Changed;74}7576namespace {77struct InstSimplifyLegacyPass : public FunctionPass {78static char ID; // Pass identification, replacement for typeid79InstSimplifyLegacyPass() : FunctionPass(ID) {80initializeInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());81}8283void getAnalysisUsage(AnalysisUsage &AU) const override {84AU.setPreservesCFG();85AU.addRequired<DominatorTreeWrapperPass>();86AU.addRequired<AssumptionCacheTracker>();87AU.addRequired<TargetLibraryInfoWrapperPass>();88}8990/// Remove instructions that simplify.91bool runOnFunction(Function &F) override {92if (skipFunction(F))93return false;9495const DominatorTree *DT =96&getAnalysis<DominatorTreeWrapperPass>().getDomTree();97const TargetLibraryInfo *TLI =98&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);99AssumptionCache *AC =100&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);101const DataLayout &DL = F.getDataLayout();102const SimplifyQuery SQ(DL, TLI, DT, AC);103return runImpl(F, SQ);104}105};106} // namespace107108char InstSimplifyLegacyPass::ID = 0;109INITIALIZE_PASS_BEGIN(InstSimplifyLegacyPass, "instsimplify",110"Remove redundant instructions", false, false)111INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)112INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)113INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)114INITIALIZE_PASS_END(InstSimplifyLegacyPass, "instsimplify",115"Remove redundant instructions", false, false)116117// Public interface to the simplify instructions pass.118FunctionPass *llvm::createInstSimplifyLegacyPass() {119return new InstSimplifyLegacyPass();120}121122PreservedAnalyses InstSimplifyPass::run(Function &F,123FunctionAnalysisManager &AM) {124auto &DT = AM.getResult<DominatorTreeAnalysis>(F);125auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);126auto &AC = AM.getResult<AssumptionAnalysis>(F);127const DataLayout &DL = F.getDataLayout();128const SimplifyQuery SQ(DL, &TLI, &DT, &AC);129bool Changed = runImpl(F, SQ);130if (!Changed)131return PreservedAnalyses::all();132133PreservedAnalyses PA;134PA.preserveSet<CFGAnalyses>();135return PA;136}137138139