LLVM  10.0.0svn
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/Statistic.h"
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/IntrinsicInst.h"
25 #include "llvm/IR/Intrinsics.h"
26 #include "llvm/IR/PatternMatch.h"
27 #include "llvm/Pass.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Transforms/Scalar.h"
31 
32 using namespace llvm;
33 using namespace llvm::PatternMatch;
34 
35 #define DEBUG_TYPE "lower-is-constant-intrinsic"
36 
37 STATISTIC(IsConstantIntrinsicsHandled,
38  "Number of 'is.constant' intrinsic calls handled");
39 STATISTIC(ObjectSizeIntrinsicsHandled,
40  "Number of 'objectsize' intrinsic calls handled");
41 
43  Value *Op = II->getOperand(0);
44 
45  return isa<Constant>(Op) ? ConstantInt::getTrue(II->getType())
47 }
48 
50  Value *NewValue) {
51  bool HasDeadBlocks = false;
53  replaceAndRecursivelySimplify(II, NewValue, nullptr, nullptr, nullptr,
54  &Worklist);
55  for (auto I : Worklist) {
57  if (!BI)
58  continue;
59  if (BI->isUnconditional())
60  continue;
61 
63  if (match(BI->getOperand(0), m_Zero())) {
64  Target = BI->getSuccessor(1);
65  Other = BI->getSuccessor(0);
66  } else if (match(BI->getOperand(0), m_One())) {
67  Target = BI->getSuccessor(0);
68  Other = BI->getSuccessor(1);
69  } else {
70  Target = nullptr;
71  Other = nullptr;
72  }
73  if (Target && Target != Other) {
74  BasicBlock *Source = BI->getParent();
75  Other->removePredecessor(Source);
76  BI->eraseFromParent();
77  BranchInst::Create(Target, Source);
78  if (pred_begin(Other) == pred_end(Other))
79  HasDeadBlocks = true;
80  }
81  }
82  return HasDeadBlocks;
83 }
84 
86  bool HasDeadBlocks = false;
87  const auto &DL = F.getParent()->getDataLayout();
89 
91  for (BasicBlock *BB : RPOT) {
92  for (Instruction &I: *BB) {
94  if (!II)
95  continue;
96  switch (II->getIntrinsicID()) {
97  default:
98  break;
99  case Intrinsic::is_constant:
100  case Intrinsic::objectsize:
101  Worklist.push_back(WeakTrackingVH(&I));
102  break;
103  }
104  }
105  }
106  for (WeakTrackingVH &VH: Worklist) {
107  // Items on the worklist can be mutated by earlier recursive replaces.
108  // This can remove the intrinsic as dead (VH == null), but also replace
109  // the intrinsic in place.
110  if (!VH)
111  continue;
112  IntrinsicInst *II = dyn_cast<IntrinsicInst>(&*VH);
113  if (!II)
114  continue;
115  Value *NewValue;
116  switch (II->getIntrinsicID()) {
117  default:
118  continue;
119  case Intrinsic::is_constant:
120  NewValue = lowerIsConstantIntrinsic(II);
121  IsConstantIntrinsicsHandled++;
122  break;
123  case Intrinsic::objectsize:
124  NewValue = lowerObjectSizeCall(II, DL, TLI, true);
125  ObjectSizeIntrinsicsHandled++;
126  break;
127  }
128  HasDeadBlocks |= replaceConditionalBranchesOnConstant(II, NewValue);
129  }
130  if (HasDeadBlocks)
132  return !Worklist.empty();
133 }
134 
138  return PreservedAnalyses::none();
139 
140  return PreservedAnalyses::all();
141 }
142 
143 namespace {
144 /// Legacy pass for lowering is.constant intrinsics out of the IR.
145 ///
146 /// When this pass is run over a function it converts is.constant intrinsics
147 /// into 'true' or 'false'. This is completements the normal constand folding
148 /// to 'true' as part of Instruction Simplify passes.
149 class LowerConstantIntrinsics : public FunctionPass {
150 public:
151  static char ID;
152  LowerConstantIntrinsics() : FunctionPass(ID) {
154  }
155 
156  bool runOnFunction(Function &F) override {
157  auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
158  const TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI(F) : nullptr;
159  return lowerConstantIntrinsics(F, TLI);
160  }
161 };
162 } // namespace
163 
165 INITIALIZE_PASS(LowerConstantIntrinsics, "lower-constant-intrinsics",
166  "Lower constant intrinsics", false, false)
167 
169  return new LowerConstantIntrinsics();
170 }
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:67
static ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:616
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
Definition: PatternMatch.h:403
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Notify the BasicBlock that the predecessor Pred is no longer able to reach it.
Definition: BasicBlock.cpp:308
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:953
BasicBlock * getSuccessor(unsigned i) const
STATISTIC(NumFunctions, "Total number of functions")
F(f)
void initializeLowerConstantIntrinsicsPass(PassRegistry &)
static Value * lowerIsConstantIntrinsic(IntrinsicInst *II)
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:47
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 &#39;I&#39; with &#39;SimpleV&#39; and simplify the uses recursively.
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
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.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:246
Value handle that is nullable, but tries to track the Value.
Definition: ValueHandle.h:181
Value * getOperand(unsigned i) const
Definition: User.h:169
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:157
static bool runOnFunction(Function &F, bool PostInlining)
static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo *TLI)
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
Conditional or Unconditional Branch instruction.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Definition: Interval.h:112
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
Interval::pred_iterator pred_end(Interval *I)
Definition: Interval.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:160
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:50
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:297
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Provides information about what library functions are available for the current target.
FunctionPass * createLowerConstantIntrinsicsPass()
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:609
Target - Wrapper for Target specific information.
static bool replaceConditionalBranchesOnConstant(Instruction *II, Value *NewValue)
#define I(x, y, z)
Definition: MD5.cpp:58
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:796
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function&#39;s entry.
Definition: Local.cpp:2214
bool isUnconditional() const
Analysis pass providing the TargetLibraryInfo.
INITIALIZE_PASS(LowerConstantIntrinsics, "lower-constant-intrinsics", "Lower constant intrinsics", false, false) FunctionPass *llvm
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
LLVM Value Representation.
Definition: Value.h:74
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
Definition: PatternMatch.h:382
A container for analyses that lazily runs them and caches their results.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:43
const BasicBlock * getParent() const
Definition: Instruction.h:66