LLVM  16.0.0git
SPIRVPrepareFunctions.cpp
Go to the documentation of this file.
1 //===-- SPIRVPrepareFunctions.cpp - modify function signatures --*- C++ -*-===//
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 modifies function signatures containing aggregate arguments
10 // and/or return value. Also it substitutes some llvm intrinsic calls by
11 // function calls, generating these functions as the translator does.
12 //
13 // NOTE: this pass is a module-level one due to the necessity to modify
14 // GVs/functions.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #include "SPIRV.h"
19 #include "SPIRVTargetMachine.h"
20 #include "SPIRVUtils.h"
22 #include "llvm/IR/IRBuilder.h"
23 #include "llvm/IR/IntrinsicInst.h"
26 
27 using namespace llvm;
28 
29 namespace llvm {
31 }
32 
33 namespace {
34 
35 class SPIRVPrepareFunctions : public ModulePass {
36  Function *processFunctionSignature(Function *F);
37 
38 public:
39  static char ID;
40  SPIRVPrepareFunctions() : ModulePass(ID) {
42  }
43 
44  bool runOnModule(Module &M) override;
45 
46  StringRef getPassName() const override { return "SPIRV prepare functions"; }
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
50  }
51 };
52 
53 } // namespace
54 
56 
57 INITIALIZE_PASS(SPIRVPrepareFunctions, "prepare-functions",
58  "SPIRV prepare functions", false, false)
59 
60 Function *SPIRVPrepareFunctions::processFunctionSignature(Function *F) {
61  IRBuilder<> B(F->getContext());
62 
63  bool IsRetAggr = F->getReturnType()->isAggregateType();
64  bool HasAggrArg =
65  std::any_of(F->arg_begin(), F->arg_end(), [](Argument &Arg) {
66  return Arg.getType()->isAggregateType();
67  });
68  bool DoClone = IsRetAggr || HasAggrArg;
69  if (!DoClone)
70  return F;
71  SmallVector<std::pair<int, Type *>, 4> ChangedTypes;
72  Type *RetType = IsRetAggr ? B.getInt32Ty() : F->getReturnType();
73  if (IsRetAggr)
74  ChangedTypes.push_back(std::pair<int, Type *>(-1, F->getReturnType()));
75  SmallVector<Type *, 4> ArgTypes;
76  for (const auto &Arg : F->args()) {
77  if (Arg.getType()->isAggregateType()) {
78  ArgTypes.push_back(B.getInt32Ty());
79  ChangedTypes.push_back(
80  std::pair<int, Type *>(Arg.getArgNo(), Arg.getType()));
81  } else
82  ArgTypes.push_back(Arg.getType());
83  }
84  FunctionType *NewFTy =
85  FunctionType::get(RetType, ArgTypes, F->getFunctionType()->isVarArg());
86  Function *NewF =
87  Function::Create(NewFTy, F->getLinkage(), F->getName(), *F->getParent());
88 
89  ValueToValueMapTy VMap;
90  auto NewFArgIt = NewF->arg_begin();
91  for (auto &Arg : F->args()) {
92  StringRef ArgName = Arg.getName();
93  NewFArgIt->setName(ArgName);
94  VMap[&Arg] = &(*NewFArgIt++);
95  }
97 
99  Returns);
100  NewF->takeName(F);
101 
102  NamedMDNode *FuncMD =
103  F->getParent()->getOrInsertNamedMetadata("spv.cloned_funcs");
105  MDArgs.push_back(MDString::get(B.getContext(), NewF->getName()));
106  for (auto &ChangedTyP : ChangedTypes)
107  MDArgs.push_back(MDNode::get(
108  B.getContext(),
109  {ConstantAsMetadata::get(B.getInt32(ChangedTyP.first)),
110  ValueAsMetadata::get(Constant::getNullValue(ChangedTyP.second))}));
111  MDNode *ThisFuncMD = MDNode::get(B.getContext(), MDArgs);
112  FuncMD->addOperand(ThisFuncMD);
113 
114  for (auto *U : make_early_inc_range(F->users())) {
115  if (auto *CI = dyn_cast<CallInst>(U))
116  CI->mutateFunctionType(NewF->getFunctionType());
117  U->replaceUsesOfWith(F, NewF);
118  }
119  return NewF;
120 }
121 
123  Function *IntrinsicFunc = II->getCalledFunction();
124  assert(IntrinsicFunc && "Missing function");
125  std::string FuncName = IntrinsicFunc->getName().str();
126  std::replace(FuncName.begin(), FuncName.end(), '.', '_');
127  FuncName = "spirv." + FuncName;
128  return FuncName;
129 }
130 
132  ArrayRef<Type *> ArgTypes,
133  StringRef Name) {
134  FunctionType *FT = FunctionType::get(RetTy, ArgTypes, false);
135  Function *F = M->getFunction(Name);
136  if (F && F->getFunctionType() == FT)
137  return F;
139  if (F)
140  NewF->setDSOLocal(F->isDSOLocal());
142  return NewF;
143 }
144 
145 static void lowerIntrinsicToFunction(Module *M, IntrinsicInst *Intrinsic) {
146  // For @llvm.memset.* intrinsic cases with constant value and length arguments
147  // are emulated via "storing" a constant array to the destination. For other
148  // cases we wrap the intrinsic in @spirv.llvm_memset_* function and expand the
149  // intrinsic to a loop via expandMemSetAsLoop().
150  if (auto *MSI = dyn_cast<MemSetInst>(Intrinsic))
151  if (isa<Constant>(MSI->getValue()) && isa<ConstantInt>(MSI->getLength()))
152  return; // It is handled later using OpCopyMemorySized.
153 
154  std::string FuncName = lowerLLVMIntrinsicName(Intrinsic);
155  if (Intrinsic->isVolatile())
156  FuncName += ".volatile";
157  // Redirect @llvm.intrinsic.* call to @spirv.llvm_intrinsic_*
158  Function *F = M->getFunction(FuncName);
159  if (F) {
160  Intrinsic->setCalledFunction(F);
161  return;
162  }
163  // TODO copy arguments attributes: nocapture writeonly.
165  M->getOrInsertFunction(FuncName, Intrinsic->getFunctionType());
166  auto IntrinsicID = Intrinsic->getIntrinsicID();
167  Intrinsic->setCalledFunction(FC);
168 
169  F = dyn_cast<Function>(FC.getCallee());
170  assert(F && "Callee must be a function");
171 
172  switch (IntrinsicID) {
173  case Intrinsic::memset: {
174  auto *MSI = static_cast<MemSetInst *>(Intrinsic);
175  Argument *Dest = F->getArg(0);
176  Argument *Val = F->getArg(1);
177  Argument *Len = F->getArg(2);
178  Argument *IsVolatile = F->getArg(3);
179  Dest->setName("dest");
180  Val->setName("val");
181  Len->setName("len");
182  IsVolatile->setName("isvolatile");
183  BasicBlock *EntryBB = BasicBlock::Create(M->getContext(), "entry", F);
184  IRBuilder<> IRB(EntryBB);
185  auto *MemSet = IRB.CreateMemSet(Dest, Val, Len, MSI->getDestAlign(),
186  MSI->isVolatile());
187  IRB.CreateRetVoid();
188  expandMemSetAsLoop(cast<MemSetInst>(MemSet));
189  MemSet->eraseFromParent();
190  break;
191  }
192  case Intrinsic::bswap: {
193  BasicBlock *EntryBB = BasicBlock::Create(M->getContext(), "entry", F);
194  IRBuilder<> IRB(EntryBB);
195  auto *BSwap = IRB.CreateIntrinsic(Intrinsic::bswap, Intrinsic->getType(),
196  F->getArg(0));
197  IRB.CreateRet(BSwap);
198  IntrinsicLowering IL(M->getDataLayout());
199  IL.LowerIntrinsicCall(BSwap);
200  break;
201  }
202  default:
203  break;
204  }
205  return;
206 }
207 
208 static void lowerFunnelShifts(Module *M, IntrinsicInst *FSHIntrinsic) {
209  // Get a separate function - otherwise, we'd have to rework the CFG of the
210  // current one. Then simply replace the intrinsic uses with a call to the new
211  // function.
212  // Generate LLVM IR for i* @spirv.llvm_fsh?_i* (i* %a, i* %b, i* %c)
213  FunctionType *FSHFuncTy = FSHIntrinsic->getFunctionType();
214  Type *FSHRetTy = FSHFuncTy->getReturnType();
215  const std::string FuncName = lowerLLVMIntrinsicName(FSHIntrinsic);
216  Function *FSHFunc =
217  getOrCreateFunction(M, FSHRetTy, FSHFuncTy->params(), FuncName);
218 
219  if (!FSHFunc->empty()) {
220  FSHIntrinsic->setCalledFunction(FSHFunc);
221  return;
222  }
223  BasicBlock *RotateBB = BasicBlock::Create(M->getContext(), "rotate", FSHFunc);
224  IRBuilder<> IRB(RotateBB);
225  Type *Ty = FSHFunc->getReturnType();
226  // Build the actual funnel shift rotate logic.
227  // In the comments, "int" is used interchangeably with "vector of int
228  // elements".
229  FixedVectorType *VectorTy = dyn_cast<FixedVectorType>(Ty);
230  Type *IntTy = VectorTy ? VectorTy->getElementType() : Ty;
231  unsigned BitWidth = IntTy->getIntegerBitWidth();
232  ConstantInt *BitWidthConstant = IRB.getInt({BitWidth, BitWidth});
233  Value *BitWidthForInsts =
234  VectorTy
235  ? IRB.CreateVectorSplat(VectorTy->getNumElements(), BitWidthConstant)
236  : BitWidthConstant;
237  Value *RotateModVal =
238  IRB.CreateURem(/*Rotate*/ FSHFunc->getArg(2), BitWidthForInsts);
239  Value *FirstShift = nullptr, *SecShift = nullptr;
240  if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
241  // Shift the less significant number right, the "rotate" number of bits
242  // will be 0-filled on the left as a result of this regular shift.
243  FirstShift = IRB.CreateLShr(FSHFunc->getArg(1), RotateModVal);
244  } else {
245  // Shift the more significant number left, the "rotate" number of bits
246  // will be 0-filled on the right as a result of this regular shift.
247  FirstShift = IRB.CreateShl(FSHFunc->getArg(0), RotateModVal);
248  }
249  // We want the "rotate" number of the more significant int's LSBs (MSBs) to
250  // occupy the leftmost (rightmost) "0 space" left by the previous operation.
251  // Therefore, subtract the "rotate" number from the integer bitsize...
252  Value *SubRotateVal = IRB.CreateSub(BitWidthForInsts, RotateModVal);
253  if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
254  // ...and left-shift the more significant int by this number, zero-filling
255  // the LSBs.
256  SecShift = IRB.CreateShl(FSHFunc->getArg(0), SubRotateVal);
257  } else {
258  // ...and right-shift the less significant int by this number, zero-filling
259  // the MSBs.
260  SecShift = IRB.CreateLShr(FSHFunc->getArg(1), SubRotateVal);
261  }
262  // A simple binary addition of the shifted ints yields the final result.
263  IRB.CreateRet(IRB.CreateOr(FirstShift, SecShift));
264 
265  FSHIntrinsic->setCalledFunction(FSHFunc);
266 }
267 
268 static void buildUMulWithOverflowFunc(Module *M, Function *UMulFunc) {
269  // The function body is already created.
270  if (!UMulFunc->empty())
271  return;
272 
273  BasicBlock *EntryBB = BasicBlock::Create(M->getContext(), "entry", UMulFunc);
274  IRBuilder<> IRB(EntryBB);
275  // Build the actual unsigned multiplication logic with the overflow
276  // indication. Do unsigned multiplication Mul = A * B. Then check
277  // if unsigned division Div = Mul / A is not equal to B. If so,
278  // then overflow has happened.
279  Value *Mul = IRB.CreateNUWMul(UMulFunc->getArg(0), UMulFunc->getArg(1));
280  Value *Div = IRB.CreateUDiv(Mul, UMulFunc->getArg(0));
281  Value *Overflow = IRB.CreateICmpNE(UMulFunc->getArg(0), Div);
282 
283  // umul.with.overflow intrinsic return a structure, where the first element
284  // is the multiplication result, and the second is an overflow bit.
285  Type *StructTy = UMulFunc->getReturnType();
286  Value *Agg = IRB.CreateInsertValue(UndefValue::get(StructTy), Mul, {0});
287  Value *Res = IRB.CreateInsertValue(Agg, Overflow, {1});
288  IRB.CreateRet(Res);
289 }
290 
291 static void lowerUMulWithOverflow(Module *M, IntrinsicInst *UMulIntrinsic) {
292  // Get a separate function - otherwise, we'd have to rework the CFG of the
293  // current one. Then simply replace the intrinsic uses with a call to the new
294  // function.
295  FunctionType *UMulFuncTy = UMulIntrinsic->getFunctionType();
296  Type *FSHLRetTy = UMulFuncTy->getReturnType();
297  const std::string FuncName = lowerLLVMIntrinsicName(UMulIntrinsic);
298  Function *UMulFunc =
299  getOrCreateFunction(M, FSHLRetTy, UMulFuncTy->params(), FuncName);
300  buildUMulWithOverflowFunc(M, UMulFunc);
301  UMulIntrinsic->setCalledFunction(UMulFunc);
302 }
303 
305  for (BasicBlock &BB : *F) {
306  for (Instruction &I : BB) {
307  auto Call = dyn_cast<CallInst>(&I);
308  if (!Call)
309  continue;
310  Call->setTailCall(false);
311  Function *CF = Call->getCalledFunction();
312  if (!CF || !CF->isIntrinsic())
313  continue;
314  auto *II = cast<IntrinsicInst>(Call);
315  if (II->getIntrinsicID() == Intrinsic::memset ||
316  II->getIntrinsicID() == Intrinsic::bswap)
318  else if (II->getIntrinsicID() == Intrinsic::fshl ||
319  II->getIntrinsicID() == Intrinsic::fshr)
320  lowerFunnelShifts(M, II);
321  else if (II->getIntrinsicID() == Intrinsic::umul_with_overflow)
323  }
324  }
325 }
326 
327 bool SPIRVPrepareFunctions::runOnModule(Module &M) {
328  for (Function &F : M)
330 
331  std::vector<Function *> FuncsWorklist;
332  bool Changed = false;
333  for (auto &F : M)
334  FuncsWorklist.push_back(&F);
335 
336  for (auto *Func : FuncsWorklist) {
337  Function *F = processFunctionSignature(Func);
338 
339  bool CreatedNewF = F != Func;
340 
341  if (Func->isDeclaration()) {
342  Changed |= CreatedNewF;
343  continue;
344  }
345 
346  if (CreatedNewF)
347  Func->eraseFromParent();
348  }
349 
350  return Changed;
351 }
352 
354  return new SPIRVPrepareFunctions();
355 }
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm::Function::isIntrinsic
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition: Function.h:210
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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::NamedMDNode
A tuple of MDNodes.
Definition: Metadata.h:1588
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
IntrinsicInst.h
llvm::Function::empty
bool empty() const
Definition: Function.h:713
llvm::Function
Definition: Function.h:60
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:53
llvm::CallBase::setCalledFunction
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1436
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::IRBuilder<>
llvm::IntrinsicLowering
Definition: IntrinsicLowering.h:22
R600_InstFlag::FC
@ FC
Definition: R600Defines.h:32
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:361
llvm::IRBuilderBase::CreateOr
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1403
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::CallBase::getFunctionType
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1255
IntrinsicLowering.h
llvm::CloneFunctionChangeType::LocalChangesOnly
@ LocalChangesOnly
llvm::VectorType::getElementType
Type * getElementType() const
Definition: DerivedTypes.h:422
replace
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
Definition: ConstantMerge.cpp:116
lowerUMulWithOverflow
static void lowerUMulWithOverflow(Module *M, IntrinsicInst *UMulIntrinsic)
Definition: SPIRVPrepareFunctions.cpp:291
llvm::FixedVectorType
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:525
llvm::GlobalValue::setDSOLocal
void setDSOLocal(bool Local)
Definition: GlobalValue.h:299
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1400
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::NamedMDNode::addOperand
void addOperand(MDNode *M)
Definition: Metadata.cpp:1222
llvm::IRBuilderBase::CreateInsertValue
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2379
llvm::FixedVectorType::getNumElements
unsigned getNumElements() const
Definition: DerivedTypes.h:568
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
getOrCreateFunction
static Function * getOrCreateFunction(Module *M, Type *RetTy, ArrayRef< Type * > ArgTypes, StringRef Name)
Definition: SPIRVPrepareFunctions.cpp:131
llvm::createSPIRVPrepareFunctionsPass
ModulePass * createSPIRVPrepareFunctionsPass()
Definition: SPIRVPrepareFunctions.cpp:353
llvm::IRBuilderBase::CreateMemSet
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
Definition: IRBuilder.h:577
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1397
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Instruction
Definition: Instruction.h:42
SPIRVUtils.h
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:375
llvm::CallingConv::SPIR_FUNC
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
Definition: CallingConv.h:135
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1713
llvm::FunctionType::params
ArrayRef< Type * > params() const
Definition: DerivedTypes.h:130
llvm::Type::getIntegerBitWidth
unsigned getIntegerBitWidth() const
Definition: DerivedTypes.h:97
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::IRBuilderBase::CreateRet
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:998
llvm::MemSetInst
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
Definition: IntrinsicInst.h:1073
llvm::IRBuilderBase::CreateURem
Value * CreateURem(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1310
SPIRVTargetMachine.h
llvm::Function::getReturnType
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:180
I
#define I(x, y, z)
Definition: MD5.cpp:58
Cloning.h
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:716
llvm::MDString::get
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:498
llvm::IRBuilderBase::getInt
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Definition: IRBuilder.h:485
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
SPIRV.h
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INITIALIZE_PASS
INITIALIZE_PASS(SPIRVPrepareFunctions, "prepare-functions", "SPIRV prepare functions", false, false) Function *SPIRVPrepareFunctions
Definition: SPIRVPrepareFunctions.cpp:57
llvm::IRBuilderBase::CreateIntrinsic
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:962
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:944
llvm::expandMemSetAsLoop
void expandMemSetAsLoop(MemSetInst *MemSet)
Expand MemSet as a loop. MemSet is not deleted.
Definition: LowerMemIntrinsics.cpp:569
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
Mul
BinaryOperator * Mul
Definition: X86PartialReduction.cpp:70
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1741
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::Function::setCallingConv
void setCallingConv(CallingConv::ID CC)
Definition: Function.h:242
lowerIntrinsicToFunction
static void lowerIntrinsicToFunction(Module *M, IntrinsicInst *Intrinsic)
Definition: SPIRVPrepareFunctions.cpp:145
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
llvm::initializeSPIRVPrepareFunctionsPass
void initializeSPIRVPrepareFunctionsPass(PassRegistry &)
substituteIntrinsicCalls
static void substituteIntrinsicCalls(Module *M, Function *F)
Definition: SPIRVPrepareFunctions.cpp:304
llvm::ifs::IFSSymbolType::Func
@ Func
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
llvm::ValueMap< const Value *, WeakTrackingVH >
lowerFunnelShifts
static void lowerFunnelShifts(Module *M, IntrinsicInst *FSHIntrinsic)
Definition: SPIRVPrepareFunctions.cpp:208
lowerLLVMIntrinsicName
std::string lowerLLVMIntrinsicName(IntrinsicInst *II)
Definition: SPIRVPrepareFunctions.cpp:122
llvm::Function::getArg
Argument * getArg(unsigned i) const
Definition: Function.h:740
llvm::BitWidth
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:147
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:175
llvm::IRBuilderBase::CreateNUWMul
Value * CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1280
llvm::Function::arg_begin
arg_iterator arg_begin()
Definition: Function.h:722
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1343
llvm::IRBuilderBase::CreateShl
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1322
llvm::IRBuilderBase::CreateRetVoid
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:993
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
buildUMulWithOverflowFunc
static void buildUMulWithOverflowFunc(Module *M, Function *UMulFunc)
Definition: SPIRVPrepareFunctions.cpp:268
llvm::IRBuilderBase::CreateVectorSplat
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Definition: IRBuilder.cpp:1246
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:98
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
llvm::CloneFunctionInto
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
Definition: CloneFunction.cpp:86
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::IRBuilderBase::CreateUDiv
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1284
llvm::IRBuilderBase::CreateICmpNE
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2103
llvm::IRBuilderBase::CreateSub
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1250
llvm::Value::takeName
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:381
llvm::IntrinsicLowering::LowerIntrinsicCall
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
Definition: IntrinsicLowering.cpp:224
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition: DerivedTypes.h:124
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
LowerMemIntrinsics.h
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103