LLVM  13.0.0git
WebAssemblyFixFunctionBitcasts.cpp
Go to the documentation of this file.
1 //===-- WebAssemblyFixFunctionBitcasts.cpp - Fix function bitcasts --------===//
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 /// \file
10 /// Fix bitcasted functions.
11 ///
12 /// WebAssembly requires caller and callee signatures to match, however in LLVM,
13 /// some amount of slop is vaguely permitted. Detect mismatch by looking for
14 /// bitcasts of functions and rewrite them to use wrapper functions instead.
15 ///
16 /// This doesn't catch all cases, such as when a function's address is taken in
17 /// one place and casted in another, but it works for many common cases.
18 ///
19 /// Note that LLVM already optimizes away function bitcasts in common cases by
20 /// dropping arguments as needed, so this pass only ends up getting used in less
21 /// common cases.
22 ///
23 //===----------------------------------------------------------------------===//
24 
25 #include "WebAssembly.h"
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/Instructions.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/Operator.h"
30 #include "llvm/Pass.h"
31 #include "llvm/Support/Debug.h"
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "wasm-fix-function-bitcasts"
36 
37 namespace {
38 class FixFunctionBitcasts final : public ModulePass {
39  StringRef getPassName() const override {
40  return "WebAssembly Fix Function Bitcasts";
41  }
42 
43  void getAnalysisUsage(AnalysisUsage &AU) const override {
44  AU.setPreservesCFG();
46  }
47 
48  bool runOnModule(Module &M) override;
49 
50 public:
51  static char ID;
52  FixFunctionBitcasts() : ModulePass(ID) {}
53 };
54 } // End anonymous namespace
55 
57 INITIALIZE_PASS(FixFunctionBitcasts, DEBUG_TYPE,
58  "Fix mismatching bitcasts for WebAssembly", false, false)
59 
61  return new FixFunctionBitcasts();
62 }
63 
64 // Recursively descend the def-use lists from V to find non-bitcast users of
65 // bitcasts of V.
66 static void findUses(Value *V, Function &F,
67  SmallVectorImpl<std::pair<Use *, Function *>> &Uses,
68  SmallPtrSetImpl<Constant *> &ConstantBCs) {
69  for (Use &U : V->uses()) {
70  if (auto *BC = dyn_cast<BitCastOperator>(U.getUser()))
71  findUses(BC, F, Uses, ConstantBCs);
72  else if (auto *A = dyn_cast<GlobalAlias>(U.getUser()))
73  findUses(A, F, Uses, ConstantBCs);
74  else if (U.get()->getType() != F.getType()) {
75  CallBase *CB = dyn_cast<CallBase>(U.getUser());
76  if (!CB)
77  // Skip uses that aren't immediately called
78  continue;
79  Value *Callee = CB->getCalledOperand();
80  if (Callee != V)
81  // Skip calls where the function isn't the callee
82  continue;
83  if (isa<Constant>(U.get())) {
84  // Only add constant bitcasts to the list once; they get RAUW'd
85  auto C = ConstantBCs.insert(cast<Constant>(U.get()));
86  if (!C.second)
87  continue;
88  }
89  Uses.push_back(std::make_pair(&U, &F));
90  }
91  }
92 }
93 
94 // Create a wrapper function with type Ty that calls F (which may have a
95 // different type). Attempt to support common bitcasted function idioms:
96 // - Call with more arguments than needed: arguments are dropped
97 // - Call with fewer arguments than needed: arguments are filled in with undef
98 // - Return value is not needed: drop it
99 // - Return value needed but not present: supply an undef
100 //
101 // If the all the argument types of trivially castable to one another (i.e.
102 // I32 vs pointer type) then we don't create a wrapper at all (return nullptr
103 // instead).
104 //
105 // If there is a type mismatch that we know would result in an invalid wasm
106 // module then generate wrapper that contains unreachable (i.e. abort at
107 // runtime). Such programs are deep into undefined behaviour territory,
108 // but we choose to fail at runtime rather than generate and invalid module
109 // or fail at compiler time. The reason we delay the error is that we want
110 // to support the CMake which expects to be able to compile and link programs
111 // that refer to functions with entirely incorrect signatures (this is how
112 // CMake detects the existence of a function in a toolchain).
113 //
114 // For bitcasts that involve struct types we don't know at this stage if they
115 // would be equivalent at the wasm level and so we can't know if we need to
116 // generate a wrapper.
118  Module *M = F->getParent();
119 
121  F->getName() + "_bitcast", M);
122  BasicBlock *BB = BasicBlock::Create(M->getContext(), "body", Wrapper);
123  const DataLayout &DL = BB->getModule()->getDataLayout();
124 
125  // Determine what arguments to pass.
127  Function::arg_iterator AI = Wrapper->arg_begin();
128  Function::arg_iterator AE = Wrapper->arg_end();
129  FunctionType::param_iterator PI = F->getFunctionType()->param_begin();
130  FunctionType::param_iterator PE = F->getFunctionType()->param_end();
131  bool TypeMismatch = false;
132  bool WrapperNeeded = false;
133 
134  Type *ExpectedRtnType = F->getFunctionType()->getReturnType();
135  Type *RtnType = Ty->getReturnType();
136 
137  if ((F->getFunctionType()->getNumParams() != Ty->getNumParams()) ||
138  (F->getFunctionType()->isVarArg() != Ty->isVarArg()) ||
139  (ExpectedRtnType != RtnType))
140  WrapperNeeded = true;
141 
142  for (; AI != AE && PI != PE; ++AI, ++PI) {
143  Type *ArgType = AI->getType();
144  Type *ParamType = *PI;
145 
146  if (ArgType == ParamType) {
147  Args.push_back(&*AI);
148  } else {
149  if (CastInst::isBitOrNoopPointerCastable(ArgType, ParamType, DL)) {
150  Instruction *PtrCast =
151  CastInst::CreateBitOrPointerCast(AI, ParamType, "cast");
152  BB->getInstList().push_back(PtrCast);
153  Args.push_back(PtrCast);
154  } else if (ArgType->isStructTy() || ParamType->isStructTy()) {
155  LLVM_DEBUG(dbgs() << "createWrapper: struct param type in bitcast: "
156  << F->getName() << "\n");
157  WrapperNeeded = false;
158  } else {
159  LLVM_DEBUG(dbgs() << "createWrapper: arg type mismatch calling: "
160  << F->getName() << "\n");
161  LLVM_DEBUG(dbgs() << "Arg[" << Args.size() << "] Expected: "
162  << *ParamType << " Got: " << *ArgType << "\n");
163  TypeMismatch = true;
164  break;
165  }
166  }
167  }
168 
169  if (WrapperNeeded && !TypeMismatch) {
170  for (; PI != PE; ++PI)
171  Args.push_back(UndefValue::get(*PI));
172  if (F->isVarArg())
173  for (; AI != AE; ++AI)
174  Args.push_back(&*AI);
175 
176  CallInst *Call = CallInst::Create(F, Args, "", BB);
177 
178  Type *ExpectedRtnType = F->getFunctionType()->getReturnType();
179  Type *RtnType = Ty->getReturnType();
180  // Determine what value to return.
181  if (RtnType->isVoidTy()) {
182  ReturnInst::Create(M->getContext(), BB);
183  } else if (ExpectedRtnType->isVoidTy()) {
184  LLVM_DEBUG(dbgs() << "Creating dummy return: " << *RtnType << "\n");
185  ReturnInst::Create(M->getContext(), UndefValue::get(RtnType), BB);
186  } else if (RtnType == ExpectedRtnType) {
187  ReturnInst::Create(M->getContext(), Call, BB);
188  } else if (CastInst::isBitOrNoopPointerCastable(ExpectedRtnType, RtnType,
189  DL)) {
190  Instruction *Cast =
191  CastInst::CreateBitOrPointerCast(Call, RtnType, "cast");
192  BB->getInstList().push_back(Cast);
193  ReturnInst::Create(M->getContext(), Cast, BB);
194  } else if (RtnType->isStructTy() || ExpectedRtnType->isStructTy()) {
195  LLVM_DEBUG(dbgs() << "createWrapper: struct return type in bitcast: "
196  << F->getName() << "\n");
197  WrapperNeeded = false;
198  } else {
199  LLVM_DEBUG(dbgs() << "createWrapper: return type mismatch calling: "
200  << F->getName() << "\n");
201  LLVM_DEBUG(dbgs() << "Expected: " << *ExpectedRtnType
202  << " Got: " << *RtnType << "\n");
203  TypeMismatch = true;
204  }
205  }
206 
207  if (TypeMismatch) {
208  // Create a new wrapper that simply contains `unreachable`.
209  Wrapper->eraseFromParent();
211  F->getName() + "_bitcast_invalid", M);
212  BasicBlock *BB = BasicBlock::Create(M->getContext(), "body", Wrapper);
213  new UnreachableInst(M->getContext(), BB);
214  Wrapper->setName(F->getName() + "_bitcast_invalid");
215  } else if (!WrapperNeeded) {
216  LLVM_DEBUG(dbgs() << "createWrapper: no wrapper needed: " << F->getName()
217  << "\n");
218  Wrapper->eraseFromParent();
219  return nullptr;
220  }
221  LLVM_DEBUG(dbgs() << "createWrapper: " << F->getName() << "\n");
222  return Wrapper;
223 }
224 
225 // Test whether a main function with type FuncTy should be rewritten to have
226 // type MainTy.
227 static bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy) {
228  // Only fix the main function if it's the standard zero-arg form. That way,
229  // the standard cases will work as expected, and users will see signature
230  // mismatches from the linker for non-standard cases.
231  return FuncTy->getReturnType() == MainTy->getReturnType() &&
232  FuncTy->getNumParams() == 0 &&
233  !FuncTy->isVarArg();
234 }
235 
236 bool FixFunctionBitcasts::runOnModule(Module &M) {
237  LLVM_DEBUG(dbgs() << "********** Fix Function Bitcasts **********\n");
238 
239  Function *Main = nullptr;
240  CallInst *CallMain = nullptr;
242  SmallPtrSet<Constant *, 2> ConstantBCs;
243 
244  // Collect all the places that need wrappers.
245  for (Function &F : M) {
246  // Skip to fix when the function is swiftcc because swiftcc allows
247  // bitcast type difference for swiftself and swifterror.
248  if (F.getCallingConv() == CallingConv::Swift)
249  continue;
250  findUses(&F, F, Uses, ConstantBCs);
251 
252  // If we have a "main" function, and its type isn't
253  // "int main(int argc, char *argv[])", create an artificial call with it
254  // bitcasted to that type so that we generate a wrapper for it, so that
255  // the C runtime can call it.
256  if (F.getName() == "main") {
257  Main = &F;
258  LLVMContext &C = M.getContext();
259  Type *MainArgTys[] = {Type::getInt32Ty(C),
261  FunctionType *MainTy = FunctionType::get(Type::getInt32Ty(C), MainArgTys,
262  /*isVarArg=*/false);
263  if (shouldFixMainFunction(F.getFunctionType(), MainTy)) {
264  LLVM_DEBUG(dbgs() << "Found `main` function with incorrect type: "
265  << *F.getFunctionType() << "\n");
266  Value *Args[] = {UndefValue::get(MainArgTys[0]),
267  UndefValue::get(MainArgTys[1])};
268  Value *Casted =
269  ConstantExpr::getBitCast(Main, PointerType::get(MainTy, 0));
270  CallMain = CallInst::Create(MainTy, Casted, Args, "call_main");
271  Use *UseMain = &CallMain->getOperandUse(2);
272  Uses.push_back(std::make_pair(UseMain, &F));
273  }
274  }
275  }
276 
278 
279  for (auto &UseFunc : Uses) {
280  Use *U = UseFunc.first;
281  Function *F = UseFunc.second;
282  auto *PTy = cast<PointerType>(U->get()->getType());
283  auto *Ty = dyn_cast<FunctionType>(PTy->getElementType());
284 
285  // If the function is casted to something like i8* as a "generic pointer"
286  // to be later casted to something else, we can't generate a wrapper for it.
287  // Just ignore such casts for now.
288  if (!Ty)
289  continue;
290 
291  auto Pair = Wrappers.insert(std::make_pair(std::make_pair(F, Ty), nullptr));
292  if (Pair.second)
293  Pair.first->second = createWrapper(F, Ty);
294 
295  Function *Wrapper = Pair.first->second;
296  if (!Wrapper)
297  continue;
298 
299  if (isa<Constant>(U->get()))
300  U->get()->replaceAllUsesWith(Wrapper);
301  else
302  U->set(Wrapper);
303  }
304 
305  // If we created a wrapper for main, rename the wrapper so that it's the
306  // one that gets called from startup.
307  if (CallMain) {
308  Main->setName("__original_main");
309  auto *MainWrapper =
310  cast<Function>(CallMain->getCalledOperand()->stripPointerCasts());
311  delete CallMain;
312  if (Main->isDeclaration()) {
313  // The wrapper is not needed in this case as we don't need to export
314  // it to anyone else.
315  MainWrapper->eraseFromParent();
316  } else {
317  // Otherwise give the wrapper the same linkage as the original main
318  // function, so that it can be called from the same places.
319  MainWrapper->setName("main");
320  MainWrapper->setLinkage(Main->getLinkage());
321  MainWrapper->setVisibility(Main->getVisibility());
322  }
323  }
324 
325  return true;
326 }
shouldFixMainFunction
static bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy)
Definition: WebAssemblyFixFunctionBitcasts.cpp:227
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
llvm
Definition: AllocatorList.h:23
WebAssembly.h
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:256
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
findUses
static void findUses(Value *V, Function &F, SmallVectorImpl< std::pair< Use *, Function * >> &Uses, SmallPtrSetImpl< Constant * > &ConstantBCs)
Definition: WebAssemblyFixFunctionBitcasts.cpp:66
llvm::GlobalValue::getLinkage
LinkageTypes getLinkage() const
Definition: GlobalValue.h:461
llvm::Function
Definition: Function.h:61
Pass.h
llvm::PointerType::get
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Definition: Type.cpp:693
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Wrapper
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
Definition: AMDGPUAliasAnalysis.cpp:30
llvm::ConstantExpr::getBitCast
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2207
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:328
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
Module.h
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:449
Operator.h
llvm::FunctionType::getNumParams
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:138
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:204
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::FunctionType::isVarArg
bool isVarArg() const
Definition: DerivedTypes.h:122
Uses
SmallPtrSet< MachineInstr *, 2 > Uses
Definition: ARMLowOverheadLoops.cpp:583
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
llvm::User::getOperandUse
const Use & getOperandUse(unsigned i) const
Definition: User.h:182
llvm::GlobalValue::isDeclaration
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:228
Constants.h
createWrapper
static Function * createWrapper(Function *F, FunctionType *Ty)
Definition: WebAssemblyFixFunctionBitcasts.cpp:117
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1493
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::Value::uses
iterator_range< use_iterator > uses()
Definition: Value.h:389
llvm::Instruction
Definition: Instruction.h:45
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:370
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1770
llvm::CallingConv::Swift
@ Swift
Definition: CallingConv.h:73
DEBUG_TYPE
#define DEBUG_TYPE
Definition: WebAssemblyFixFunctionBitcasts.cpp:35
llvm::FunctionType::param_iterator
Type::subtype_iterator param_iterator
Definition: DerivedTypes.h:125
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:78
llvm::GlobalValue::getVisibility
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:229
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::DenseMap
Definition: DenseMap.h:714
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
INITIALIZE_PASS
INITIALIZE_PASS(FixFunctionBitcasts, DEBUG_TYPE, "Fix mismatching bitcasts for WebAssembly", false, false) ModulePass *llvm
Definition: WebAssemblyFixFunctionBitcasts.cpp:57
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:526
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::CastInst::isBitOrNoopPointerCastable
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
Definition: Instructions.cpp:3205
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:636
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:205
llvm::CastInst::CreateBitOrPointerCast
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
Definition: Instructions.cpp:3100
llvm::ReturnInst::Create
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Definition: Instructions.h:2950
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1389
llvm::GlobalValue::PrivateLinkage
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
Instructions.h
llvm::Type::isStructTy
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:223
llvm::createWebAssemblyFixFunctionBitcasts
ModulePass * createWebAssemblyFixFunctionBitcasts()
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:93
llvm::SmallPtrSetImpl
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:343
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1450
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::UnreachableInst
This function has undefined behavior.
Definition: Instructions.h:4650
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
raw_ostream.h
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition: DerivedTypes.h:123
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:102
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:364
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38