LLVM  16.0.0git
LowerConstantIntrinsics.cpp
Go to the documentation of this file.
1 //===- LowerConstantIntrinsics.cpp - Lower constant intrinsic calls -------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass lowers all remaining 'objectsize' 'is.constant' intrinsic calls
10 // and provides constant propagation and basic CFG cleanup on the result.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "llvm/ADT/SetVector.h"
17 #include "llvm/ADT/Statistic.h"
23 #include "llvm/IR/BasicBlock.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/IR/Dominators.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Instructions.h"
28 #include "llvm/IR/IntrinsicInst.h"
29 #include "llvm/IR/PatternMatch.h"
30 #include "llvm/InitializePasses.h"
31 #include "llvm/Pass.h"
32 #include "llvm/Transforms/Scalar.h"
34 
35 using namespace llvm;
36 using namespace llvm::PatternMatch;
37 
38 #define DEBUG_TYPE "lower-is-constant-intrinsic"
39 
40 STATISTIC(IsConstantIntrinsicsHandled,
41  "Number of 'is.constant' intrinsic calls handled");
42 STATISTIC(ObjectSizeIntrinsicsHandled,
43  "Number of 'objectsize' intrinsic calls handled");
44 
46  if (auto *C = dyn_cast<Constant>(II->getOperand(0)))
47  if (C->isManifestConstant())
48  return ConstantInt::getTrue(II->getType());
49  return ConstantInt::getFalse(II->getType());
50 }
51 
53  Value *NewValue,
54  DomTreeUpdater *DTU) {
55  bool HasDeadBlocks = false;
56  SmallSetVector<Instruction *, 8> UnsimplifiedUsers;
57  replaceAndRecursivelySimplify(II, NewValue, nullptr, nullptr, nullptr,
58  &UnsimplifiedUsers);
59  // UnsimplifiedUsers can contain PHI nodes that may be removed when
60  // replacing the branch instructions, so use a value handle worklist
61  // to handle those possibly removed instructions.
62  SmallVector<WeakVH, 8> Worklist(UnsimplifiedUsers.begin(),
63  UnsimplifiedUsers.end());
64 
65  for (auto &VH : Worklist) {
66  BranchInst *BI = dyn_cast_or_null<BranchInst>(VH);
67  if (!BI)
68  continue;
69  if (BI->isUnconditional())
70  continue;
71 
73  if (match(BI->getOperand(0), m_Zero())) {
74  Target = BI->getSuccessor(1);
75  Other = BI->getSuccessor(0);
76  } else if (match(BI->getOperand(0), m_One())) {
77  Target = BI->getSuccessor(0);
78  Other = BI->getSuccessor(1);
79  } else {
80  Target = nullptr;
81  Other = nullptr;
82  }
83  if (Target && Target != Other) {
84  BasicBlock *Source = BI->getParent();
85  Other->removePredecessor(Source);
86  BI->eraseFromParent();
88  if (DTU)
90  if (pred_empty(Other))
91  HasDeadBlocks = true;
92  }
93  }
94  return HasDeadBlocks;
95 }
96 
98  DominatorTree *DT) {
100  if (DT)
102 
103  bool HasDeadBlocks = false;
104  const auto &DL = F.getParent()->getDataLayout();
106 
108  for (BasicBlock *BB : RPOT) {
109  for (Instruction &I: *BB) {
110  IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
111  if (!II)
112  continue;
113  switch (II->getIntrinsicID()) {
114  default:
115  break;
116  case Intrinsic::is_constant:
117  case Intrinsic::objectsize:
118  Worklist.push_back(WeakTrackingVH(&I));
119  break;
120  }
121  }
122  }
123  for (WeakTrackingVH &VH: Worklist) {
124  // Items on the worklist can be mutated by earlier recursive replaces.
125  // This can remove the intrinsic as dead (VH == null), but also replace
126  // the intrinsic in place.
127  if (!VH)
128  continue;
129  IntrinsicInst *II = dyn_cast<IntrinsicInst>(&*VH);
130  if (!II)
131  continue;
132  Value *NewValue;
133  switch (II->getIntrinsicID()) {
134  default:
135  continue;
136  case Intrinsic::is_constant:
137  NewValue = lowerIsConstantIntrinsic(II);
138  IsConstantIntrinsicsHandled++;
139  break;
140  case Intrinsic::objectsize:
141  NewValue = lowerObjectSizeCall(II, DL, &TLI, true);
142  ObjectSizeIntrinsicsHandled++;
143  break;
144  }
145  HasDeadBlocks |= replaceConditionalBranchesOnConstant(
146  II, NewValue, DTU ? DTU.getPointer() : nullptr);
147  }
148  if (HasDeadBlocks)
149  removeUnreachableBlocks(F, DTU ? DTU.getPointer() : nullptr);
150  return !Worklist.empty();
151 }
152 
159  return PA;
160  }
161 
162  return PreservedAnalyses::all();
163 }
164 
165 namespace {
166 /// Legacy pass for lowering is.constant intrinsics out of the IR.
167 ///
168 /// When this pass is run over a function it converts is.constant intrinsics
169 /// into 'true' or 'false'. This complements the normal constant folding
170 /// to 'true' as part of Instruction Simplify passes.
171 class LowerConstantIntrinsics : public FunctionPass {
172 public:
173  static char ID;
174  LowerConstantIntrinsics() : FunctionPass(ID) {
176  }
177 
178  bool runOnFunction(Function &F) override {
179  const TargetLibraryInfo &TLI =
180  getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
181  DominatorTree *DT = nullptr;
182  if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
183  DT = &DTWP->getDomTree();
184  return lowerConstantIntrinsics(F, TLI, DT);
185  }
186 
187  void getAnalysisUsage(AnalysisUsage &AU) const override {
191  }
192 };
193 } // namespace
194 
196 INITIALIZE_PASS_BEGIN(LowerConstantIntrinsics, "lower-constant-intrinsics",
197  "Lower constant intrinsics", false, false)
200 INITIALIZE_PASS_END(LowerConstantIntrinsics, "lower-constant-intrinsics",
202 
204  return new LowerConstantIntrinsics();
205 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
constant
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same constant
Definition: README.txt:91
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::WeakTrackingVH
Value handle that is nullable, but tries to track the Value.
Definition: ValueHandle.h:204
IntrinsicInst.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:774
Scalar.h
llvm::DomTreeUpdater::applyUpdates
void applyUpdates(ArrayRef< DominatorTree::UpdateType > Updates)
Submit updates to all available trees.
Definition: DomTreeUpdater.cpp:231
llvm::Function
Definition: Function.h:60
Pass.h
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:53
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:145
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1181
Statistic.h
DomTreeUpdater.h
Local.h
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:166
GlobalsModRef.h
llvm::removeUnreachableBlocks
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:2548
MemoryBuiltins.h
llvm::Optional
Definition: APInt.h:33
lowerConstantIntrinsics
static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
Definition: LowerConstantIntrinsics.cpp:97
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::DomTreeUpdater::UpdateStrategy::Lazy
@ Lazy
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::Optional::getPointer
constexpr const T * getPointer() const
Definition: Optional.h:311
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::begin
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:82
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
Constants.h
llvm::PatternMatch::match
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
lowerIsConstantIntrinsic
static Value * lowerIsConstantIntrinsic(IntrinsicInst *II)
Definition: LowerConstantIntrinsics.cpp:45
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TargetLibraryInfo.h
false
Definition: StackSlotColoring.cpp:141
llvm::Instruction
Definition: Instruction.h:42
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:302
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::LowerConstantIntrinsicsPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.
Definition: LowerConstantIntrinsics.cpp:154
llvm::DomTreeUpdater
Definition: DomTreeUpdater.h:28
PatternMatch.h
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::PatternMatch::m_One
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
Definition: PatternMatch.h:517
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
BasicBlock.h
llvm::PatternMatch::m_Zero
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
Definition: PatternMatch.h:537
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:77
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(LowerConstantIntrinsics, "lower-constant-intrinsics", "Lower constant intrinsics", false, false) INITIALIZE_PASS_END(LowerConstantIntrinsics
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:474
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::PreservedAnalyses::preserve
void preserve()
Mark an analysis as preserved.
Definition: PassManager.h:173
intrinsics
lower constant intrinsics
Definition: LowerConstantIntrinsics.cpp:200
llvm::Optional::emplace
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:295
llvm::BranchInst::Create
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
Definition: Instructions.h:3190
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::lowerObjectSizeCall
Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)
Try to turn a call to @llvm.objectsize into an integer value of the given Type.
Definition: MemoryBuiltins.cpp:625
llvm::replaceAndRecursivelySimplify
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)
Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
Definition: InstructionSimplify.cpp:6614
replaceConditionalBranchesOnConstant
static bool replaceConditionalBranchesOnConstant(Instruction *II, Value *NewValue, DomTreeUpdater *DTU)
Definition: LowerConstantIntrinsics.cpp:52
llvm::BranchInst::isUnconditional
bool isUnconditional() const
Definition: Instructions.h:3212
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:98
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::pred_empty
bool pred_empty(const BasicBlock *BB)
Definition: CFG.h:118
llvm::ConstantInt::getFalse
static ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:834
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::ConstantInt::getTrue
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:827
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::initializeLowerConstantIntrinsicsPass
void initializeLowerConstantIntrinsicsPass(PassRegistry &)
llvm::AnalysisManager::getCachedResult
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:793
Function.h
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:225
LowerConstantIntrinsics.h
llvm::ReversePostOrderTraversal
Definition: PostOrderIterator.h:291
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:267
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::end
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:92
Instructions.h
PostOrderIterator.h
llvm::createLowerConstantIntrinsicsPass
FunctionPass * createLowerConstantIntrinsicsPass()
Definition: LowerConstantIntrinsics.cpp:203
Dominators.h
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:91
InstructionSimplify.h
llvm::GlobalsAAWrapperPass
Legacy wrapper pass to provide the GlobalsAAResult object.
Definition: GlobalsModRef.h:144
llvm::PatternMatch
Definition: PatternMatch.h:47
llvm::SmallSetVector
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::BranchInst
Conditional or Unconditional Branch instruction.
Definition: Instructions.h:3134
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:449
llvm::BranchInst::getSuccessor
BasicBlock * getSuccessor(unsigned i) const
Definition: Instructions.h:3227
SetVector.h
llvm::DominatorTreeBase< BasicBlock, false >::Delete
static constexpr UpdateKind Delete
Definition: GenericDomTree.h:243
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1247
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38