blob: 6616364ab2034b57fa23159bf7b4adb4f3788d23 [file] [log] [blame]
Chandler Carruth7c557f82018-06-29 23:36:03 +00001//===- InstSimplifyPass.cpp -----------------------------------------------===//
Duncan Sandseaff5002010-12-20 21:07:42 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Duncan Sandseaff5002010-12-20 21:07:42 +00006//
7//===----------------------------------------------------------------------===//
Duncan Sandseaff5002010-12-20 21:07:42 +00008
Chandler Carruth7c557f82018-06-29 23:36:03 +00009#include "llvm/Transforms/Scalar/InstSimplifyPass.h"
Duncan Sands2c440fa2010-12-31 17:49:05 +000010#include "llvm/ADT/DepthFirstIterator.h"
Duncan Sands697de772011-01-03 10:50:04 +000011#include "llvm/ADT/SmallPtrSet.h"
Duncan Sandseaff5002010-12-20 21:07:42 +000012#include "llvm/ADT/Statistic.h"
Daniel Jasperaec2fa32016-12-19 08:22:17 +000013#include "llvm/Analysis/AssumptionCache.h"
Duncan Sandseaff5002010-12-20 21:07:42 +000014#include "llvm/Analysis/InstructionSimplify.h"
Adam Nemet0965da22017-10-09 23:19:02 +000015#include "llvm/Analysis/OptimizationRemarkEmitter.h"
Weiming Zhao45d4cb92015-11-24 18:57:06 +000016#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/DataLayout.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000018#include "llvm/IR/Dominators.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000019#include "llvm/IR/Function.h"
20#include "llvm/IR/Type.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000021#include "llvm/Pass.h"
David Blaikiea373d182018-03-28 17:44:36 +000022#include "llvm/Transforms/Utils.h"
Chandler Carruth7c557f82018-06-29 23:36:03 +000023#include "llvm/Transforms/Utils/Local.h"
Duncan Sandseaff5002010-12-20 21:07:42 +000024using namespace llvm;
25
Chandler Carruth964daaa2014-04-22 02:55:47 +000026#define DEBUG_TYPE "instsimplify"
27
Duncan Sandseaff5002010-12-20 21:07:42 +000028STATISTIC(NumSimplified, "Number of redundant instructions removed");
29
Daniel Berlin954006f2017-04-26 13:52:16 +000030static bool runImpl(Function &F, const SimplifyQuery &SQ,
Sanjay Patel54656ca2017-02-06 18:26:06 +000031 OptimizationRemarkEmitter *ORE) {
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000032 SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
Davide Italiano16284df2016-07-07 21:14:36 +000033 bool Changed = false;
34
35 do {
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000036 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
Davide Italiano16284df2016-07-07 21:14:36 +000037 // Here be subtlety: the iterator must be incremented before the loop
38 // body (not sure why), so a range-for loop won't work here.
39 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
40 Instruction *I = &*BI++;
41 // The first time through the loop ToSimplify is empty and we try to
42 // simplify all instructions. On later iterations ToSimplify is not
43 // empty and we only bother simplifying instructions that are in it.
44 if (!ToSimplify->empty() && !ToSimplify->count(I))
45 continue;
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000046
Davide Italiano16284df2016-07-07 21:14:36 +000047 // Don't waste time simplifying unused instructions.
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000048 if (!I->use_empty()) {
Daniel Berlin4d0fe642017-04-28 19:55:38 +000049 if (Value *V = SimplifyInstruction(I, SQ, ORE)) {
Davide Italiano16284df2016-07-07 21:14:36 +000050 // Mark all uses for resimplification next time round the loop.
51 for (User *U : I->users())
52 Next->insert(cast<Instruction>(U));
53 I->replaceAllUsesWith(V);
54 ++NumSimplified;
55 Changed = true;
56 }
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000057 }
Daniel Berlin954006f2017-04-26 13:52:16 +000058 if (RecursivelyDeleteTriviallyDeadInstructions(I, SQ.TLI)) {
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000059 // RecursivelyDeleteTriviallyDeadInstruction can remove more than one
60 // instruction, so simply incrementing the iterator does not work.
61 // When instructions get deleted re-iterate instead.
62 BI = BB->begin();
63 BE = BB->end();
64 Changed = true;
Davide Italiano16284df2016-07-07 21:14:36 +000065 }
66 }
Sanjay Patelda9f7bf2016-11-27 15:53:48 +000067 }
Davide Italiano16284df2016-07-07 21:14:36 +000068
69 // Place the list of instructions to simplify on the next loop iteration
70 // into ToSimplify.
71 std::swap(ToSimplify, Next);
72 Next->clear();
73 } while (!ToSimplify->empty());
74
75 return Changed;
76}
77
Duncan Sandseaff5002010-12-20 21:07:42 +000078namespace {
Chandler Carruth7c557f82018-06-29 23:36:03 +000079struct InstSimplifyLegacyPass : public FunctionPass {
80 static char ID; // Pass identification, replacement for typeid
81 InstSimplifyLegacyPass() : FunctionPass(ID) {
82 initializeInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());
83 }
Duncan Sandseaff5002010-12-20 21:07:42 +000084
Chandler Carruth7c557f82018-06-29 23:36:03 +000085 void getAnalysisUsage(AnalysisUsage &AU) const override {
86 AU.setPreservesCFG();
87 AU.addRequired<DominatorTreeWrapperPass>();
88 AU.addRequired<AssumptionCacheTracker>();
89 AU.addRequired<TargetLibraryInfoWrapperPass>();
90 AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
91 }
Duncan Sandseaff5002010-12-20 21:07:42 +000092
Chandler Carruth7c557f82018-06-29 23:36:03 +000093 /// runOnFunction - Remove instructions that simplify.
94 bool runOnFunction(Function &F) override {
95 if (skipFunction(F))
96 return false;
Andrew Kaylor50271f72016-05-03 22:32:30 +000097
Chandler Carruth7c557f82018-06-29 23:36:03 +000098 const DominatorTree *DT =
99 &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
100 const TargetLibraryInfo *TLI =
101 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
102 AssumptionCache *AC =
103 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
104 OptimizationRemarkEmitter *ORE =
105 &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
106 const DataLayout &DL = F.getParent()->getDataLayout();
107 const SimplifyQuery SQ(DL, TLI, DT, AC);
108 return runImpl(F, SQ, ORE);
109 }
110};
111} // namespace
Duncan Sandseaff5002010-12-20 21:07:42 +0000112
Chandler Carruth7c557f82018-06-29 23:36:03 +0000113char InstSimplifyLegacyPass::ID = 0;
114INITIALIZE_PASS_BEGIN(InstSimplifyLegacyPass, "instsimplify",
Chad Rosierc24b86f2011-12-01 03:08:23 +0000115 "Remove redundant instructions", false, false)
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000116INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
Dehao Chen3857f8f2016-09-06 22:17:16 +0000117INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
Chandler Carruthb98f63d2015-01-15 10:41:28 +0000118INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Sanjay Patel54656ca2017-02-06 18:26:06 +0000119INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
Chandler Carruth7c557f82018-06-29 23:36:03 +0000120INITIALIZE_PASS_END(InstSimplifyLegacyPass, "instsimplify",
Chad Rosierc24b86f2011-12-01 03:08:23 +0000121 "Remove redundant instructions", false, false)
Duncan Sandseaff5002010-12-20 21:07:42 +0000122
123// Public interface to the simplify instructions pass.
Chandler Carruth7c557f82018-06-29 23:36:03 +0000124FunctionPass *llvm::createInstSimplifyLegacyPass() {
125 return new InstSimplifyLegacyPass();
Duncan Sandseaff5002010-12-20 21:07:42 +0000126}
Davide Italiano16284df2016-07-07 21:14:36 +0000127
Chandler Carruth7c557f82018-06-29 23:36:03 +0000128PreservedAnalyses InstSimplifyPass::run(Function &F,
129 FunctionAnalysisManager &AM) {
Dehao Chen3857f8f2016-09-06 22:17:16 +0000130 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
Davide Italiano16284df2016-07-07 21:14:36 +0000131 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000132 auto &AC = AM.getResult<AssumptionAnalysis>(F);
Sanjay Patel54656ca2017-02-06 18:26:06 +0000133 auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
Daniel Berlin954006f2017-04-26 13:52:16 +0000134 const DataLayout &DL = F.getParent()->getDataLayout();
135 const SimplifyQuery SQ(DL, &TLI, &DT, &AC);
136 bool Changed = runImpl(F, SQ, &ORE);
Davide Italiano16284df2016-07-07 21:14:36 +0000137 if (!Changed)
138 return PreservedAnalyses::all();
Chandler Carruthca68a3e2017-01-15 06:32:49 +0000139
140 PreservedAnalyses PA;
141 PA.preserveSet<CFGAnalyses>();
142 return PA;
Davide Italiano16284df2016-07-07 21:14:36 +0000143}