LLVM 23.0.0git
ExpandVariadics.cpp
Go to the documentation of this file.
1//===-- ExpandVariadicsPass.cpp --------------------------------*- 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 is an optimization pass for variadic functions. If called from codegen,
10// it can serve as the implementation of variadic functions for a given target.
11//
12// The strategy is to turn the ... part of a variadic function into a va_list
13// and fix up the call sites. The majority of the pass is target independent.
14// The exceptions are the va_list type itself and the rules for where to store
15// variables in memory such that va_arg can iterate over them given a va_list.
16//
17// The majority of the plumbing is splitting the variadic function into a
18// single basic block that packs the variadic arguments into a va_list and
19// a second function that does the work of the original. That packing is
20// exactly what is done by va_start. Further, the transform from ... to va_list
21// replaced va_start with an operation to copy a va_list from the new argument,
22// which is exactly a va_copy. This is useful for reducing target-dependence.
23//
24// A va_list instance is a forward iterator, where the primary operation va_arg
25// is dereference-then-increment. This interface forces significant convergent
26// evolution between target specific implementations. The variation in runtime
27// data layout is limited to that representable by the iterator, parameterised
28// by the type passed to the va_arg instruction.
29//
30// Therefore the majority of the target specific subtlety is packing arguments
31// into a stack allocated buffer such that a va_list can be initialised with it
32// and the va_arg expansion for the target will find the arguments at runtime.
33//
34// The aggregate effect is to unblock other transforms, most critically the
35// general purpose inliner. Known calls to variadic functions become zero cost.
36//
37// Consistency with clang is primarily tested by emitting va_arg using clang
38// then expanding the variadic functions using this pass, followed by trying
39// to constant fold the functions to no-ops.
40//
41// Target specific behaviour is tested in IR - mainly checking that values are
42// put into positions in call frames that make sense for that particular target.
43//
44// There is one "clever" invariant in use. va_start intrinsics that are not
45// within a varidic functions are an error in the IR verifier. When this
46// transform moves blocks from a variadic function into a fixed arity one, it
47// moves va_start intrinsics along with everything else. That means that the
48// va_start intrinsics that need to be rewritten to use the trailing argument
49// are exactly those that are in non-variadic functions so no further state
50// is needed to distinguish those that need to be rewritten.
51//
52//===----------------------------------------------------------------------===//
53
55#include "llvm/ADT/Sequence.h"
58#include "llvm/IR/IRBuilder.h"
60#include "llvm/IR/Module.h"
61#include "llvm/IR/PassManager.h"
63#include "llvm/Pass.h"
68
69#define DEBUG_TYPE "expand-variadics"
70
71using namespace llvm;
72
73namespace {
74
75cl::opt<ExpandVariadicsMode> ExpandVariadicsModeOption(
76 DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
79 "Use the implementation defaults"),
81 "Disable the pass entirely"),
83 "Optimise without changing ABI"),
85 "Change variadic calling convention")));
86
87bool commandLineOverride() {
88 return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
89}
90
91// Instances of this class encapsulate the target-dependant behaviour as a
92// function of triple. Implementing a new ABI is adding a case to the switch
93// in create(llvm::Triple) at the end of this file.
94// This class may end up instantiated in TargetMachine instances, keeping it
95// here for now until enough targets are implemented for the API to evolve.
96class VariadicABIInfo {
97protected:
98 VariadicABIInfo() = default;
99
100public:
101 static std::unique_ptr<VariadicABIInfo> create(const Triple &T);
102
103 // Allow overriding whether the pass runs on a per-target basis
104 virtual bool enableForTarget() = 0;
105
106 // Whether a valist instance is passed by value or by address
107 // I.e. does it need to be alloca'ed and stored into, or can
108 // it be passed directly in a SSA register
109 virtual bool vaListPassedInSSARegister() = 0;
110
111 // The type of a va_list iterator object
112 virtual Type *vaListType(LLVMContext &Ctx) = 0;
113
114 // The type of a va_list as a function argument as lowered by C
115 virtual Type *vaListParameterType(Module &M) = 0;
116
117 // Initialize an allocated va_list object to point to an already
118 // initialized contiguous memory region.
119 // Return the value to pass as the va_list argument
120 virtual Value *initializeVaList(Module &M, LLVMContext &Ctx,
121 IRBuilder<> &Builder, AllocaInst *VaList,
122 Value *Buffer) = 0;
123
124 struct VAArgSlotInfo {
125 Align DataAlign; // With respect to the call frame
126 bool Indirect; // Passed via a pointer
127 };
128 virtual VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) = 0;
129
130 // Targets implemented so far all have the same trivial lowering for these
131 bool vaEndIsNop() { return true; }
132 bool vaCopyIsMemcpy() { return true; }
133
134 // Per-target overrides of special symbols.
135 virtual bool ignoreFunction(const Function *F) { return false; }
136
137 // Any additional address spaces used in va intrinsics that should be
138 // expanded.
139 virtual SmallVector<unsigned> getTargetSpecificVaIntrinAddrSpaces() const {
140 return {};
141 }
142
143 virtual ~VariadicABIInfo() = default;
144};
145
146class ExpandVariadics : public ModulePass {
147
148 // The pass construction sets the default to optimize when called from middle
149 // end and lowering when called from the backend. The command line variable
150 // overrides that. This is useful for testing and debugging. It also allows
151 // building an applications with variadic functions wholly removed if one
152 // has sufficient control over the dependencies, e.g. a statically linked
153 // clang that has no variadic function calls remaining in the binary.
154
155public:
156 static char ID;
158 std::unique_ptr<VariadicABIInfo> ABI;
159
160 ExpandVariadics(ExpandVariadicsMode Mode)
161 : ModulePass(ID),
162 Mode(commandLineOverride() ? ExpandVariadicsModeOption : Mode) {}
163
164 StringRef getPassName() const override { return "Expand variadic functions"; }
165
166 bool rewriteABI() { return Mode == ExpandVariadicsMode::Lowering; }
167
168 template <typename T> bool isValidCallingConv(T *F) {
169 return F->getCallingConv() == CallingConv::C ||
170 F->getCallingConv() == CallingConv::SPIR_FUNC;
171 }
172
173 bool runOnModule(Module &M) override;
174
175 bool runOnFunction(Module &M, IRBuilder<> &Builder, Function *F);
176
177 Function *replaceAllUsesWithNewDeclaration(Module &M,
178 Function *OriginalFunction);
179
180 Function *deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
181 Function *OriginalFunction);
182
183 Function *defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
184 Function *VariadicWrapper,
185 Function *FixedArityReplacement);
186
187 bool expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB, FunctionType *,
188 Function *NF);
189
190 // The intrinsic functions va_copy and va_end are removed unconditionally.
191 // They correspond to a memcpy and a no-op on all implemented targets.
192 // The va_start intrinsic is removed from basic blocks that were not created
193 // by this pass, some may remain if needed to maintain the external ABI.
194
195 template <Intrinsic::ID ID, typename InstructionType>
196 bool expandIntrinsicUsers(Module &M, IRBuilder<> &Builder,
197 PointerType *IntrinsicArgType) {
198 bool Changed = false;
199 const DataLayout &DL = M.getDataLayout();
200 if (Function *Intrinsic =
201 Intrinsic::getDeclarationIfExists(&M, ID, {IntrinsicArgType})) {
202 for (User *U : make_early_inc_range(Intrinsic->users()))
203 if (auto *I = dyn_cast<InstructionType>(U))
204 Changed |= expandVAIntrinsicCall(Builder, DL, I);
205
206 if (Intrinsic->use_empty())
207 Intrinsic->eraseFromParent();
208 }
209 return Changed;
210 }
211
212 bool expandVAIntrinsicUsersWithAddrspace(Module &M, IRBuilder<> &Builder,
213 unsigned Addrspace) {
214 auto &Ctx = M.getContext();
215 PointerType *IntrinsicArgType = PointerType::get(Ctx, Addrspace);
216 bool Changed = false;
217
218 // expand vastart before vacopy as vastart may introduce a vacopy
219 Changed |= expandIntrinsicUsers<Intrinsic::vastart, VAStartInst>(
220 M, Builder, IntrinsicArgType);
221 Changed |= expandIntrinsicUsers<Intrinsic::vaend, VAEndInst>(
222 M, Builder, IntrinsicArgType);
223 Changed |= expandIntrinsicUsers<Intrinsic::vacopy, VACopyInst>(
224 M, Builder, IntrinsicArgType);
225 return Changed;
226 }
227
228 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
229 VAStartInst *Inst);
230
231 bool expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
232 VAEndInst *Inst);
233
234 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
235 VACopyInst *Inst);
236
237 bool expandVAArgInst(IRBuilder<> &Builder, const DataLayout &DL,
238 VAArgInst *Inst);
239
240 FunctionType *inlinableVariadicFunctionType(Module &M, FunctionType *FTy,
241 Type *ReturnType) {
242 // The type of "FTy" with the ... removed and a va_list appended
243 SmallVector<Type *> ArgTypes(FTy->params());
244 ArgTypes.push_back(ABI->vaListParameterType(M));
245 return FunctionType::get(ReturnType, ArgTypes, /*IsVarArgs=*/false);
246 }
247
248 FunctionType *inlinableVariadicFunctionType(Module &M, FunctionType *FTy) {
249 return inlinableVariadicFunctionType(M, FTy, FTy->getReturnType());
250 }
251
252 bool expansionApplicableToFunction(Module &M, Function *F) {
253 if (F->isIntrinsic() || !F->isVarArg() ||
254 F->hasFnAttribute(Attribute::Naked))
255 return false;
256
257 if (ABI->ignoreFunction(F))
258 return false;
259
260 if (!isValidCallingConv(F))
261 return false;
262
263 if (rewriteABI())
264 return true;
265
266 if (!F->hasExactDefinition())
267 return false;
268
269 return true;
270 }
271
272 bool expansionApplicableToFunctionCall(CallBase *CB) {
273 if (CallInst *CI = dyn_cast<CallInst>(CB)) {
274 if (CI->isMustTailCall()) {
275 // Cannot expand musttail calls
276 return false;
277 }
278
279 if (!isValidCallingConv(CI))
280 return false;
281
282 return true;
283 }
284
285 if (isa<InvokeInst>(CB)) {
286 // Invoke not implemented in initial implementation of pass
287 return false;
288 }
289
290 // Other unimplemented derivative of CallBase
291 return false;
292 }
293
294 class ExpandedCallFrame {
295 // Helper for constructing an alloca instance containing the arguments bound
296 // to the variadic ... parameter, rearranged to allow indexing through a
297 // va_list iterator
298 enum { N = 4 };
299 SmallVector<Type *, N> FieldTypes;
300 enum Tag { Store, Memcpy, Padding };
302
303 template <Tag tag> void append(Type *FieldType, Value *V, uint64_t Bytes) {
304 FieldTypes.push_back(FieldType);
305 Source.push_back({V, Bytes, tag});
306 }
307
308 public:
309 void store(LLVMContext &Ctx, Type *T, Value *V) { append<Store>(T, V, 0); }
310
311 void memcpy(LLVMContext &Ctx, Type *T, Value *V, uint64_t Bytes) {
312 append<Memcpy>(T, V, Bytes);
313 }
314
315 void padding(LLVMContext &Ctx, uint64_t By) {
316 append<Padding>(ArrayType::get(Type::getInt8Ty(Ctx), By), nullptr, 0);
317 }
318
319 size_t size() const { return FieldTypes.size(); }
320 bool empty() const { return FieldTypes.empty(); }
321
322 StructType *asStruct(LLVMContext &Ctx, StringRef Name) {
323 const bool IsPacked = true;
324 return StructType::create(Ctx, FieldTypes,
325 (Twine(Name) + ".vararg").str(), IsPacked);
326 }
327
328 void initializeStructAlloca(const DataLayout &DL, IRBuilder<> &Builder,
329 AllocaInst *Alloced, StructType *VarargsTy) {
330
331 for (size_t I = 0; I < size(); I++) {
332
333 auto [V, bytes, tag] = Source[I];
334
335 if (tag == Padding) {
336 assert(V == nullptr);
337 continue;
338 }
339
340 auto Dst = Builder.CreateStructGEP(VarargsTy, Alloced, I);
341
342 assert(V != nullptr);
343
344 if (tag == Store)
345 Builder.CreateStore(V, Dst);
346
347 if (tag == Memcpy)
348 Builder.CreateMemCpy(Dst, {}, V, {}, bytes);
349 }
350 }
351 };
352};
353
354bool ExpandVariadics::runOnModule(Module &M) {
355 bool Changed = false;
357 return Changed;
358
359 Triple TT(M.getTargetTriple());
360 ABI = VariadicABIInfo::create(TT);
361 if (!ABI)
362 return Changed;
363
364 if (!ABI->enableForTarget())
365 return Changed;
366
367 auto &Ctx = M.getContext();
368 const DataLayout &DL = M.getDataLayout();
369 IRBuilder<> Builder(Ctx);
370
371 // Lowering needs to run on all functions exactly once.
372 // Optimize could run on functions containing va_start exactly once.
374 Changed |= runOnFunction(M, Builder, &F);
375
376 // After runOnFunction, all known calls to known variadic functions have been
377 // replaced. va_start intrinsics are presently (and invalidly!) only present
378 // in functions that used to be variadic and have now been replaced to take a
379 // va_list instead. If lowering as opposed to optimising, calls to unknown
380 // variadic functions have also been replaced.
381
382 {
383 unsigned Addrspace = 0;
384 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
385
386 Addrspace = DL.getAllocaAddrSpace();
387 if (Addrspace != 0)
388 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
389
390 // Process any addrspaces targets declare to be important.
391 const SmallVector<unsigned> &TargetASVec =
392 ABI->getTargetSpecificVaIntrinAddrSpaces();
393 for (unsigned TargetAS : TargetASVec) {
394 if (TargetAS == 0 || TargetAS == DL.getAllocaAddrSpace())
395 continue;
396 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, TargetAS);
397 }
398 }
399
401 return Changed;
402
403 for (Function &F : make_early_inc_range(M)) {
404 if (F.isDeclaration())
405 continue;
406
407 // Now need to track down indirect calls and va_arg instructions. Can't find
408 // those by walking uses of variadic functions, need to crawl the
409 // instruction stream. Fortunately this is only necessary for the ABI
410 // rewrite case.
411 for (BasicBlock &BB : F) {
412 for (Instruction &I : make_early_inc_range(BB)) {
413 if (auto *VA = dyn_cast<VAArgInst>(&I)) {
414 Changed |= expandVAArgInst(Builder, DL, VA);
415 } else if (CallBase *CB = dyn_cast<CallBase>(&I)) {
416 if (CB->isIndirectCall()) {
417 FunctionType *FTy = CB->getFunctionType();
418 if (FTy->isVarArg())
419 Changed |= expandCall(M, Builder, CB, FTy, /*NF=*/nullptr);
420 }
421 }
422 }
423 }
424 }
425
426 return Changed;
427}
428
429bool ExpandVariadics::runOnFunction(Module &M, IRBuilder<> &Builder,
430 Function *OriginalFunction) {
431 bool Changed = false;
432
433 if (!expansionApplicableToFunction(M, OriginalFunction))
434 return Changed;
435
436 [[maybe_unused]] const bool OriginalFunctionIsDeclaration =
437 OriginalFunction->isDeclaration();
438 assert(rewriteABI() || !OriginalFunctionIsDeclaration);
439
440 // Declare a new function and redirect every use to that new function
441 Function *VariadicWrapper =
442 replaceAllUsesWithNewDeclaration(M, OriginalFunction);
443 assert(VariadicWrapper->isDeclaration());
444 assert(OriginalFunction->use_empty());
445
446 // Create a new function taking va_list containing the implementation of the
447 // original
448 Function *FixedArityReplacement =
449 deriveFixedArityReplacement(M, Builder, OriginalFunction);
450 assert(OriginalFunction->isDeclaration());
451 assert(FixedArityReplacement->isDeclaration() ==
452 OriginalFunctionIsDeclaration);
453 assert(VariadicWrapper->isDeclaration());
454
455 // Create a single block forwarding wrapper that turns a ... into a va_list
456 [[maybe_unused]] Function *VariadicWrapperDefine =
457 defineVariadicWrapper(M, Builder, VariadicWrapper, FixedArityReplacement);
458 assert(VariadicWrapperDefine == VariadicWrapper);
459 assert(!VariadicWrapper->isDeclaration());
460
461 // Add the prof metadata from the original function to the wrapper. Because
462 // FixedArityReplacement is the owner of original function's prof metadata
463 // after the splice, we need to transfer it to VariadicWrapper.
464 VariadicWrapper->setMetadata(
465 LLVMContext::MD_prof,
466 FixedArityReplacement->getMetadata(LLVMContext::MD_prof));
467
468 // We now have:
469 // 1. the original function, now as a declaration with no uses
470 // 2. a variadic function that unconditionally calls a fixed arity replacement
471 // 3. a fixed arity function equivalent to the original function
472
473 // Replace known calls to the variadic with calls to the va_list equivalent
474 for (User *U : make_early_inc_range(VariadicWrapper->users())) {
475 if (CallBase *CB = dyn_cast<CallBase>(U)) {
476 Value *CalledOperand = CB->getCalledOperand();
477 if (VariadicWrapper == CalledOperand)
478 Changed |=
479 expandCall(M, Builder, CB, VariadicWrapper->getFunctionType(),
480 FixedArityReplacement);
481 }
482 }
483
484 // The original function will be erased.
485 // One of the two new functions will become a replacement for the original.
486 // When preserving the ABI, the other is an internal implementation detail.
487 // When rewriting the ABI, RAUW then the variadic one.
488 Function *const ExternallyAccessible =
489 rewriteABI() ? FixedArityReplacement : VariadicWrapper;
490 Function *const InternalOnly =
491 rewriteABI() ? VariadicWrapper : FixedArityReplacement;
492
493 // The external function is the replacement for the original
494 ExternallyAccessible->setLinkage(OriginalFunction->getLinkage());
495 ExternallyAccessible->setVisibility(OriginalFunction->getVisibility());
496 ExternallyAccessible->setComdat(OriginalFunction->getComdat());
497 ExternallyAccessible->takeName(OriginalFunction);
498
499 // Annotate the internal one as internal
502
503 // The original is unused and obsolete
504 OriginalFunction->eraseFromParent();
505
506 InternalOnly->removeDeadConstantUsers();
507
508 if (rewriteABI()) {
509 // All known calls to the function have been removed by expandCall
510 // Resolve everything else by replaceAllUsesWith
511 VariadicWrapper->replaceAllUsesWith(FixedArityReplacement);
512 VariadicWrapper->eraseFromParent();
513 }
514
515 return Changed;
516}
517
518Function *
519ExpandVariadics::replaceAllUsesWithNewDeclaration(Module &M,
520 Function *OriginalFunction) {
521 auto &Ctx = M.getContext();
522 Function &F = *OriginalFunction;
523 FunctionType *FTy = F.getFunctionType();
524 Function *NF = Function::Create(FTy, F.getLinkage(), F.getAddressSpace());
525
526 NF->setName(F.getName() + ".varargs");
527
528 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
529
530 AttrBuilder ParamAttrs(Ctx);
531 AttributeList Attrs = NF->getAttributes();
532 Attrs = Attrs.addParamAttributes(Ctx, FTy->getNumParams(), ParamAttrs);
533 NF->setAttributes(Attrs);
534
535 OriginalFunction->replaceAllUsesWith(NF);
536 return NF;
537}
538
539Function *
540ExpandVariadics::deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
541 Function *OriginalFunction) {
542 Function &F = *OriginalFunction;
543 // The purpose here is split the variadic function F into two functions
544 // One is a variadic function that bundles the passed argument into a va_list
545 // and passes it to the second function. The second function does whatever
546 // the original F does, except that it takes a va_list instead of the ...
547
548 assert(expansionApplicableToFunction(M, &F));
549
550 auto &Ctx = M.getContext();
551
552 // Returned value isDeclaration() is equal to F.isDeclaration()
553 // but that property is not invariant throughout this function
554 const bool FunctionIsDefinition = !F.isDeclaration();
555
556 FunctionType *FTy = F.getFunctionType();
557 SmallVector<Type *> ArgTypes(FTy->params());
558 ArgTypes.push_back(ABI->vaListParameterType(M));
559
560 FunctionType *NFTy = inlinableVariadicFunctionType(M, FTy);
561 Function *NF = Function::Create(NFTy, F.getLinkage(), F.getAddressSpace());
562
563 // Note - same attribute handling as DeadArgumentElimination
564 NF->copyAttributesFrom(&F);
565 NF->setComdat(F.getComdat());
566 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
567 NF->setName(F.getName() + ".valist");
568
569 AttrBuilder ParamAttrs(Ctx);
570
571 AttributeList Attrs = NF->getAttributes();
572 Attrs = Attrs.addParamAttributes(Ctx, NFTy->getNumParams() - 1, ParamAttrs);
573 NF->setAttributes(Attrs);
574
575 // Splice the implementation into the new function with minimal changes
576 if (FunctionIsDefinition) {
577 NF->splice(NF->begin(), &F);
578
579 auto NewArg = NF->arg_begin();
580 for (Argument &Arg : F.args()) {
581 Arg.replaceAllUsesWith(NewArg);
582 NewArg->setName(Arg.getName()); // takeName without killing the old one
583 ++NewArg;
584 }
585 NewArg->setName("varargs");
586 }
587
589 F.getAllMetadata(MDs);
590 for (auto [KindID, Node] : MDs)
591 NF->addMetadata(KindID, *Node);
592 F.clearMetadata();
593
594 return NF;
595}
596
597Function *
598ExpandVariadics::defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
599 Function *VariadicWrapper,
600 Function *FixedArityReplacement) {
601 auto &Ctx = Builder.getContext();
602 const DataLayout &DL = M.getDataLayout();
603 assert(VariadicWrapper->isDeclaration());
604 Function &F = *VariadicWrapper;
605
606 assert(F.isDeclaration());
607 Type *VaListTy = ABI->vaListType(Ctx);
608
609 auto *BB = BasicBlock::Create(Ctx, "entry", &F);
610 Builder.SetInsertPoint(BB);
611
612 AllocaInst *VaListInstance =
613 Builder.CreateAlloca(VaListTy, nullptr, "va_start");
614
615 Builder.CreateLifetimeStart(VaListInstance);
616
617 Builder.CreateIntrinsic(Intrinsic::vastart, {DL.getAllocaPtrType(Ctx)},
618 {VaListInstance});
619
621
622 Value *VaListValue = VaListInstance;
623 if (ABI->vaListPassedInSSARegister())
624 VaListValue = Builder.CreateLoad(VaListTy, VaListInstance);
625
626 Type *ParameterType = ABI->vaListParameterType(M);
627 Args.push_back(Builder.CreateAddrSpaceCast(VaListValue, ParameterType));
628
629 CallInst *Result = Builder.CreateCall(FixedArityReplacement, Args);
630
631 Builder.CreateIntrinsic(Intrinsic::vaend, {DL.getAllocaPtrType(Ctx)},
632 {VaListInstance});
633 Builder.CreateLifetimeEnd(VaListInstance);
634
635 if (Result->getType()->isVoidTy())
636 Builder.CreateRetVoid();
637 else
638 Builder.CreateRet(Result);
639
640 return VariadicWrapper;
641}
642
643bool ExpandVariadics::expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB,
644 FunctionType *VarargFunctionType,
645 Function *NF) {
646 bool Changed = false;
647 const DataLayout &DL = M.getDataLayout();
648
649 if (ABI->ignoreFunction(CB->getCalledFunction()))
650 return Changed;
651
652 if (!expansionApplicableToFunctionCall(CB)) {
653 if (rewriteABI())
654 report_fatal_error("Cannot lower callbase instruction");
655 return Changed;
656 }
657
658 // This is tricky. The call instruction's function type might not match
659 // the type of the caller. When optimising, can leave it unchanged.
660 // Webassembly detects that inconsistency and repairs it.
661 if (CB->getFunctionType() != VarargFunctionType)
662 if (!rewriteABI())
663 return Changed;
664
665 auto &Ctx = CB->getContext();
666
667 Align MaxFieldAlign(1);
668
669 // The strategy is to allocate a call frame containing the variadic
670 // arguments laid out such that a target specific va_list can be initialized
671 // with it, such that target specific va_arg instructions will correctly
672 // iterate over it. This means getting the alignment right and sometimes
673 // embedding a pointer to the value instead of embedding the value itself.
674
675 Function *CBF = CB->getParent()->getParent();
676
677 ExpandedCallFrame Frame;
678
679 uint64_t CurrentOffset = 0;
680
681 for (unsigned I : seq(VarargFunctionType->getNumParams(), CB->arg_size())) {
682 Value *ArgVal = CB->getArgOperand(I);
683 const bool IsByVal = CB->paramHasAttr(I, Attribute::ByVal);
684 const bool IsByRef = CB->paramHasAttr(I, Attribute::ByRef);
685
686 // The type of the value being passed, decoded from byval/byref metadata if
687 // required
688 Type *const UnderlyingType = IsByVal ? CB->getParamByValType(I)
689 : IsByRef ? CB->getParamByRefType(I)
690 : ArgVal->getType();
691 const uint64_t UnderlyingSize =
692 DL.getTypeAllocSize(UnderlyingType).getFixedValue();
693
694 // The type to be written into the call frame
695 Type *FrameFieldType = UnderlyingType;
696
697 // The value to copy from when initialising the frame alloca
698 Value *SourceValue = ArgVal;
699
700 VariadicABIInfo::VAArgSlotInfo SlotInfo = ABI->slotInfo(DL, UnderlyingType);
701
702 if (SlotInfo.Indirect) {
703 // The va_arg lowering loads through a pointer. Set up an alloca to aim
704 // that pointer at.
705 Builder.SetInsertPointPastAllocas(CBF);
706 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
707 Value *CallerCopy =
708 Builder.CreateAlloca(UnderlyingType, nullptr, "IndirectAlloca");
709
710 Builder.SetInsertPoint(CB);
711 if (IsByVal)
712 Builder.CreateMemCpy(CallerCopy, {}, ArgVal, {}, UnderlyingSize);
713 else
714 Builder.CreateStore(ArgVal, CallerCopy);
715
716 // Indirection now handled, pass the alloca ptr by value
717 FrameFieldType = DL.getAllocaPtrType(Ctx);
718 SourceValue = CallerCopy;
719 }
720
721 // Alignment of the value within the frame
722 // This probably needs to be controllable as a function of type
723 Align DataAlign = SlotInfo.DataAlign;
724
725 MaxFieldAlign = std::max(MaxFieldAlign, DataAlign);
726
727 uint64_t DataAlignV = DataAlign.value();
728 if (uint64_t Rem = CurrentOffset % DataAlignV) {
729 // Inject explicit padding to deal with alignment requirements
730 uint64_t Padding = DataAlignV - Rem;
731 Frame.padding(Ctx, Padding);
732 CurrentOffset += Padding;
733 }
734
735 if (SlotInfo.Indirect) {
736 Frame.store(Ctx, FrameFieldType, SourceValue);
737 } else {
738 if (IsByVal)
739 Frame.memcpy(Ctx, FrameFieldType, SourceValue, UnderlyingSize);
740 else
741 Frame.store(Ctx, FrameFieldType, SourceValue);
742 }
743
744 CurrentOffset += DL.getTypeAllocSize(FrameFieldType).getFixedValue();
745 }
746
747 if (Frame.empty()) {
748 // Not passing any arguments, hopefully va_arg won't try to read any
749 // Creating a single byte frame containing nothing to point the va_list
750 // instance as that is less special-casey in the compiler and probably
751 // easier to interpret in a debugger.
752 Frame.padding(Ctx, 1);
753 }
754
755 StructType *VarargsTy = Frame.asStruct(Ctx, CBF->getName());
756
757 // The struct instance needs to be at least MaxFieldAlign for the alignment of
758 // the fields to be correct at runtime. Use the native stack alignment instead
759 // if that's greater as that tends to give better codegen.
760 // This is an awkward way to guess whether there is a known stack alignment
761 // without hitting an assert in DL.getStackAlignment, 1024 is an arbitrary
762 // number likely to be greater than the natural stack alignment.
763 Align AllocaAlign = MaxFieldAlign;
764 if (MaybeAlign StackAlign = DL.getStackAlignment();
765 StackAlign && *StackAlign > AllocaAlign)
766 AllocaAlign = *StackAlign;
767
768 // Put the alloca to hold the variadic args in the entry basic block.
769 Builder.SetInsertPointPastAllocas(CBF);
770
771 // SetCurrentDebugLocation when the builder SetInsertPoint method does not
772 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
773
774 // The awkward construction here is to set the alignment on the instance
775 AllocaInst *Alloced = Builder.Insert(
776 new AllocaInst(VarargsTy, DL.getAllocaAddrSpace(), nullptr, AllocaAlign),
777 "vararg_buffer");
778 Changed = true;
779 assert(Alloced->getAllocatedType() == VarargsTy);
780
781 // Initialize the fields in the struct
782 Builder.SetInsertPoint(CB);
783 Builder.CreateLifetimeStart(Alloced);
784 Frame.initializeStructAlloca(DL, Builder, Alloced, VarargsTy);
785
786 const unsigned NumArgs = VarargFunctionType->getNumParams();
787 SmallVector<Value *> Args(CB->arg_begin(), CB->arg_begin() + NumArgs);
788
789 // Initialize a va_list pointing to that struct and pass it as the last
790 // argument
791 AllocaInst *VaList = nullptr;
792 {
793 if (!ABI->vaListPassedInSSARegister()) {
794 Type *VaListTy = ABI->vaListType(Ctx);
795 Builder.SetInsertPointPastAllocas(CBF);
796 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
797 VaList = Builder.CreateAlloca(VaListTy, nullptr, "va_argument");
798 Builder.SetInsertPoint(CB);
799 Builder.CreateLifetimeStart(VaList);
800 }
801 Builder.SetInsertPoint(CB);
802 Args.push_back(ABI->initializeVaList(M, Ctx, Builder, VaList, Alloced));
803 }
804
805 // Attributes excluding any on the vararg arguments
806 AttributeList PAL = CB->getAttributes();
807 if (!PAL.isEmpty()) {
809 for (unsigned ArgNo = 0; ArgNo < NumArgs; ArgNo++)
810 ArgAttrs.push_back(PAL.getParamAttrs(ArgNo));
811 PAL =
812 AttributeList::get(Ctx, PAL.getFnAttrs(), PAL.getRetAttrs(), ArgAttrs);
813 }
814
816 CB->getOperandBundlesAsDefs(OpBundles);
817
818 CallBase *NewCB = nullptr;
819
820 if (CallInst *CI = dyn_cast<CallInst>(CB)) {
821 Value *Dst = NF ? NF : CI->getCalledOperand();
822 // Use the type of the call site rather than the function type to ensure
823 // RAUW succeeds in the case of a mismatching return type.
824 FunctionType *NFTy =
825 inlinableVariadicFunctionType(M, VarargFunctionType, CB->getType());
826
827 NewCB = CallInst::Create(NFTy, Dst, Args, OpBundles, "", CI->getIterator());
828
829 CallInst::TailCallKind TCK = CI->getTailCallKind();
831
832 // Can't tail call a function that is being passed a pointer to an alloca
833 if (TCK == CallInst::TCK_Tail)
834 TCK = CallInst::TCK_None;
835 CI->setTailCallKind(TCK);
836
837 } else {
838 llvm_unreachable("Unreachable when !expansionApplicableToFunctionCall()");
839 }
840
841 if (VaList)
842 Builder.CreateLifetimeEnd(VaList);
843
844 Builder.CreateLifetimeEnd(Alloced);
845
846 NewCB->setAttributes(PAL);
847 NewCB->takeName(CB);
848 NewCB->setCallingConv(CB->getCallingConv());
849 NewCB->setDebugLoc(DebugLoc());
850
851 // DeadArgElim and ArgPromotion copy exactly this metadata
852 NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
853
854 CB->replaceAllUsesWith(NewCB);
855 CB->eraseFromParent();
856 return Changed;
857}
858
859bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
860 const DataLayout &DL,
861 VAStartInst *Inst) {
862 // Only removing va_start instructions that are not in variadic functions.
863 // Those would be rejected by the IR verifier before this pass.
864 // After splicing basic blocks from a variadic function into a fixed arity
865 // one the va_start that used to refer to the ... parameter still exist.
866 // There are also variadic functions that this pass did not change and
867 // va_start instances in the created single block wrapper functions.
868 // Replace exactly the instances in non-variadic functions as those are
869 // the ones to be fixed up to use the va_list passed as the final argument.
870
871 Function *ContainingFunction = Inst->getFunction();
872 if (ContainingFunction->isVarArg()) {
873 return false;
874 }
875
876 // The last argument is a vaListParameterType, either a va_list
877 // or a pointer to one depending on the target.
878 bool PassedByValue = ABI->vaListPassedInSSARegister();
879 Argument *PassedVaList =
880 ContainingFunction->getArg(ContainingFunction->arg_size() - 1);
881
882 // va_start takes a pointer to a va_list, e.g. one on the stack
883 Value *VaStartArg = Inst->getArgList();
884
885 Builder.SetInsertPoint(Inst);
886
887 if (PassedByValue) {
888 // The general thing to do is create an alloca, store the va_list argument
889 // to it, then create a va_copy. When vaCopyIsMemcpy(), this optimises to a
890 // store to the VaStartArg.
891 assert(ABI->vaCopyIsMemcpy());
892 // The va_list parameter may be passed in a different address space than
893 // the va_list object iterates in (e.g. NVPTX passes a local pointer but
894 // stores a generic cursor). Cast it to the type va_arg expects to load.
895 Value *Cursor = PassedVaList;
896 if (Cursor->getType() != VaStartArg->getType())
897 Cursor = Builder.CreateAddrSpaceCast(Cursor, VaStartArg->getType());
898 Builder.CreateStore(Cursor, VaStartArg);
899 } else {
900
901 // Otherwise emit a vacopy to pick up target-specific handling if any
902 auto &Ctx = Builder.getContext();
903
904 Builder.CreateIntrinsic(Intrinsic::vacopy, {DL.getAllocaPtrType(Ctx)},
905 {VaStartArg, PassedVaList});
906 }
907
908 Inst->eraseFromParent();
909 return true;
910}
911
912bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
913 VAEndInst *Inst) {
914 assert(ABI->vaEndIsNop());
915 Inst->eraseFromParent();
916 return true;
917}
918
919bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
920 const DataLayout &DL,
921 VACopyInst *Inst) {
922 assert(ABI->vaCopyIsMemcpy());
923 Builder.SetInsertPoint(Inst);
924
925 auto &Ctx = Builder.getContext();
926 Type *VaListTy = ABI->vaListType(Ctx);
927 uint64_t Size = DL.getTypeAllocSize(VaListTy).getFixedValue();
928
929 Builder.CreateMemCpy(Inst->getDest(), {}, Inst->getSrc(), {},
930 Builder.getInt32(Size));
931
932 Inst->eraseFromParent();
933 return true;
934}
935
936bool ExpandVariadics::expandVAArgInst(IRBuilder<> &Builder,
937 const DataLayout &DL, VAArgInst *Inst) {
938 Builder.SetInsertPoint(Inst);
939
940 auto &Ctx = Builder.getContext();
941 Type *ValTy = Inst->getType();
942 Value *VaListPtr = Inst->getPointerOperand();
943
944 const VariadicABIInfo::VAArgSlotInfo SlotInfo = ABI->slotInfo(DL, ValTy);
945 Type *FrameFieldType = SlotInfo.Indirect ? DL.getAllocaPtrType(Ctx) : ValTy;
946 const uint64_t SlotSize = DL.getTypeAllocSize(FrameFieldType).getFixedValue();
947 const Align SlotAlign = SlotInfo.DataAlign;
948
949 Type *PtrTy = VaListPtr->getType();
950 Type *IdxTy = DL.getIndexType(PtrTy);
951
952 Value *Cur = Builder.CreateLoad(PtrTy, VaListPtr);
953
954 // Round the cursor up to the slot alignment used by the caller.
955 Value *Aligned = Cur;
956 if (SlotAlign > Align(1)) {
957 Value *RoundUp = Builder.CreateInBoundsPtrAdd(
958 Cur, ConstantInt::get(IdxTy, SlotAlign.value() - 1));
959 Aligned = Builder.CreateIntrinsic(
960 Intrinsic::ptrmask, {PtrTy, IdxTy},
961 {RoundUp, ConstantInt::getSigned(IdxTy, -(int64_t)SlotAlign.value())});
962 }
963
964 // Advance past the slot and write the iterator back.
965 Value *Next =
966 Builder.CreateInBoundsPtrAdd(Aligned, ConstantInt::get(IdxTy, SlotSize));
967 Builder.CreateStore(Next, VaListPtr);
968
969 // Load the slot contents: the value itself for direct arguments, or a
970 // pointer to the value for indirect ones.
971 Value *Result = Builder.CreateAlignedLoad(FrameFieldType, Aligned, SlotAlign);
972
973 if (SlotInfo.Indirect)
974 Result = Builder.CreateLoad(ValTy, Result);
975
976 Result->takeName(Inst);
977 Inst->replaceAllUsesWith(Result);
978 Inst->eraseFromParent();
979 return true;
980}
981
982struct Amdgpu final : public VariadicABIInfo {
983
984 bool enableForTarget() override { return true; }
985
986 bool vaListPassedInSSARegister() override { return true; }
987
988 Type *vaListType(LLVMContext &Ctx) override {
989 return PointerType::getUnqual(Ctx);
990 }
991
992 Type *vaListParameterType(Module &M) override {
993 return PointerType::getUnqual(M.getContext());
994 }
995
996 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
997 AllocaInst * /*va_list*/, Value *Buffer) override {
998 // Given Buffer, which is an AllocInst of vararg_buffer
999 // need to return something usable as parameter type
1000 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
1001 }
1002
1003 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
1004 return {Align(4), false};
1005 }
1006};
1007
1008struct NVPTX final : public VariadicABIInfo {
1009
1010 bool enableForTarget() override { return true; }
1011
1012 bool vaListPassedInSSARegister() override { return true; }
1013
1014 Type *vaListType(LLVMContext &Ctx) override {
1015 return PointerType::getUnqual(Ctx);
1016 }
1017
1018 Type *vaListParameterType(Module &M) override {
1019 return PointerType::get(M.getContext(), NVPTXAS::ADDRESS_SPACE_LOCAL);
1020 }
1021
1022 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
1023 AllocaInst *, Value *Buffer) override {
1024 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
1025 }
1026
1027 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
1028 // NVPTX expects natural alignment in all cases. The variadic call ABI will
1029 // handle promoting types to their appropriate size and alignment.
1030 Align A = DL.getABITypeAlign(Parameter);
1031 return {A, false};
1032 }
1033};
1034
1035struct SPIRV final : public VariadicABIInfo {
1036
1037 bool enableForTarget() override { return true; }
1038
1039 bool vaListPassedInSSARegister() override { return true; }
1040
1041 Type *vaListType(LLVMContext &Ctx) override {
1042 return PointerType::getUnqual(Ctx);
1043 }
1044
1045 Type *vaListParameterType(Module &M) override {
1046 return PointerType::getUnqual(M.getContext());
1047 }
1048
1049 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
1050 AllocaInst *, Value *Buffer) override {
1051 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
1052 }
1053
1054 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
1055 // Expects natural alignment in all cases. The variadic call ABI will handle
1056 // promoting types to their appropriate size and alignment.
1057 Align A = DL.getABITypeAlign(Parameter);
1058 return {A, false};
1059 }
1060
1061 // The SPIR-V backend has special handling for builtins.
1062 bool ignoreFunction(const Function *F) override {
1063 if (!F->isDeclaration())
1064 return false;
1065
1066 std::string Demangled = llvm::demangle(F->getName());
1067 StringRef DemangledName(Demangled);
1068
1069 // Skip any SPIR-V builtins.
1070 if (DemangledName.starts_with("__spirv_") ||
1071 DemangledName.starts_with("printf("))
1072 return true;
1073
1074 return false;
1075 }
1076
1077 // We will likely see va intrinsics in the generic addrspace (4).
1078 SmallVector<unsigned> getTargetSpecificVaIntrinAddrSpaces() const override {
1079 return {4};
1080 }
1081};
1082
1083struct Wasm final : public VariadicABIInfo {
1084
1085 bool enableForTarget() override {
1086 // Currently wasm is only used for testing.
1087 return commandLineOverride();
1088 }
1089
1090 bool vaListPassedInSSARegister() override { return true; }
1091
1092 Type *vaListType(LLVMContext &Ctx) override {
1093 return PointerType::getUnqual(Ctx);
1094 }
1095
1096 Type *vaListParameterType(Module &M) override {
1097 return PointerType::getUnqual(M.getContext());
1098 }
1099
1100 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
1101 AllocaInst * /*va_list*/, Value *Buffer) override {
1102 return Buffer;
1103 }
1104
1105 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
1106 LLVMContext &Ctx = Parameter->getContext();
1107 const unsigned MinAlign = 4;
1108 Align A = DL.getABITypeAlign(Parameter);
1109 if (A < MinAlign)
1110 A = Align(MinAlign);
1111
1112 if (auto *S = dyn_cast<StructType>(Parameter)) {
1113 if (S->getNumElements() > 1) {
1114 return {DL.getABITypeAlign(PointerType::getUnqual(Ctx)), true};
1115 }
1116 }
1117
1118 return {A, false};
1119 }
1120};
1121
1122std::unique_ptr<VariadicABIInfo> VariadicABIInfo::create(const Triple &T) {
1123 switch (T.getArch()) {
1124 case Triple::r600:
1125 case Triple::amdgcn: {
1126 return std::make_unique<Amdgpu>();
1127 }
1128
1129 case Triple::wasm32: {
1130 return std::make_unique<Wasm>();
1131 }
1132
1133 case Triple::nvptx:
1134 case Triple::nvptx64: {
1135 return std::make_unique<NVPTX>();
1136 }
1137
1138 case Triple::spirv:
1139 case Triple::spirv32:
1140 case Triple::spirv64: {
1141 return std::make_unique<SPIRV>();
1142 }
1143
1144 default:
1145 return {};
1146 }
1147}
1148
1149} // namespace
1150
1151char ExpandVariadics::ID = 0;
1152
1153INITIALIZE_PASS(ExpandVariadics, DEBUG_TYPE, "Expand variadic functions", false,
1154 false)
1155
1157 return new ExpandVariadics(M);
1158}
1159
1161 return ExpandVariadics(Mode).runOnModule(M) ? PreservedAnalyses::none()
1163}
1164
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
NVPTX address space definition.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallVector class.
an instruction to allocate memory on the stack
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
Type * getParamByRefType(unsigned ArgNo) const
Extract the byref type for a call or parameter.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
FunctionType * getFunctionType() const
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI ExpandVariadicsPass(ExpandVariadicsMode Mode)
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:168
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
Definition Function.h:761
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:211
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:354
iterator begin()
Definition Function.h:853
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Function.cpp:449
arg_iterator arg_begin()
Definition Function.h:868
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:357
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:229
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:843
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:223
const Comdat * getComdat() const
LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
VisibilityTypes getVisibility() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
LinkageTypes getLinkage() const
void setLinkage(LinkageTypes LT)
@ DefaultVisibility
The GV is visible.
Definition GlobalValue.h:68
void setVisibility(VisibilityTypes V)
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2868
LLVM_ABI const DebugLoc & getStableDebugLoc() const
Fetch the debug location for this node, unless this is a debug intrinsic, in which case fetch the deb...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
Class to represent struct types.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:685
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
Value * getPointerOperand()
This represents the llvm.va_copy intrinsic.
Value * getSrc() const
Value * getDest() const
This represents the llvm.va_end intrinsic.
This represents the llvm.va_start intrinsic.
Value * getArgList() const
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:393
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:552
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
bool use_empty() const
Definition Value.h:346
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:399
const ParentTy * getParent() const
Definition ilist_node.h:34
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1668
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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:633
ExpandVariadicsMode
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
Definition MathExtras.h:357
LLVM_ABI ModulePass * createExpandVariadicsPass(ExpandVariadicsMode)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition Demangle.cpp:21
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106