LLVM  16.0.0git
LowerGuardIntrinsic.cpp
Go to the documentation of this file.
1 //===- LowerGuardIntrinsic.cpp - Lower the guard intrinsic ---------------===//
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 the llvm.experimental.guard intrinsic to a conditional call
10 // to @llvm.experimental.deoptimize. Once this happens, the guard can no longer
11 // be widened.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/Intrinsics.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/InitializePasses.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Transforms/Scalar.h"
27 
28 using namespace llvm;
29 
30 namespace {
31 struct LowerGuardIntrinsicLegacyPass : public FunctionPass {
32  static char ID;
33  LowerGuardIntrinsicLegacyPass() : FunctionPass(ID) {
36  }
37 
38  bool runOnFunction(Function &F) override;
39 };
40 }
41 
43  // Check if we can cheaply rule out the possibility of not having any work to
44  // do.
45  auto *GuardDecl = F.getParent()->getFunction(
46  Intrinsic::getName(Intrinsic::experimental_guard));
47  if (!GuardDecl || GuardDecl->use_empty())
48  return false;
49 
51  // Traverse through the users of GuardDecl.
52  // This is presumably cheaper than traversing all instructions in the
53  // function.
54  for (auto *U : GuardDecl->users())
55  if (auto *CI = dyn_cast<CallInst>(U))
56  if (CI->getFunction() == &F)
57  ToLower.push_back(CI);
58 
59  if (ToLower.empty())
60  return false;
61 
62  auto *DeoptIntrinsic = Intrinsic::getDeclaration(
63  F.getParent(), Intrinsic::experimental_deoptimize, {F.getReturnType()});
64  DeoptIntrinsic->setCallingConv(GuardDecl->getCallingConv());
65 
66  for (auto *CI : ToLower) {
67  makeGuardControlFlowExplicit(DeoptIntrinsic, CI, false);
68  CI->eraseFromParent();
69  }
70 
71  return true;
72 }
73 
75  return lowerGuardIntrinsic(F);
76 }
77 
79 INITIALIZE_PASS(LowerGuardIntrinsicLegacyPass, "lower-guard-intrinsic",
80  "Lower the guard intrinsic to normal control flow", false,
81  false)
82 
84  return new LowerGuardIntrinsicLegacyPass();
85 }
86 
90  return PreservedAnalyses::none();
91 
92  return PreservedAnalyses::all();
93 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::makeGuardControlFlowExplicit
void makeGuardControlFlowExplicit(Function *DeoptIntrinsic, CallInst *Guard, bool UseWC)
Splits control flow at point of Guard, replacing it with explicit branch by the condition of guard's ...
Definition: GuardUtils.cpp:30
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
Scalar.h
InstIterator.h
llvm::Function
Definition: Function.h:60
Pass.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::Intrinsic::getName
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
Definition: Function.cpp:942
lowerGuardIntrinsic
static bool lowerGuardIntrinsic(Function &F)
Definition: LowerGuardIntrinsic.cpp:42
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
Module.h
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
Intrinsics.h
GuardUtils.h
llvm::initializeLowerGuardIntrinsicLegacyPassPass
void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry &)
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::LowerGuardIntrinsicPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: LowerGuardIntrinsic.cpp:87
INITIALIZE_PASS
INITIALIZE_PASS(LowerGuardIntrinsicLegacyPass, "lower-guard-intrinsic", "Lower the guard intrinsic to normal control flow", false, false) Pass *llvm
Definition: LowerGuardIntrinsic.cpp:79
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1481
llvm::createLowerGuardIntrinsicPass
Pass * createLowerGuardIntrinsicPass()
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:85
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
Function.h
LowerGuardIntrinsic.h
GuardUtils.h
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
Instructions.h
SmallVector.h
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
InitializePasses.h