LLVM 20.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
56#include "llvm/IR/Constants.h"
57#include "llvm/IR/IRBuilder.h"
59#include "llvm/IR/Module.h"
60#include "llvm/IR/PassManager.h"
62#include "llvm/Pass.h"
66
67#define DEBUG_TYPE "expand-variadics"
68
69using namespace llvm;
70
71namespace {
72
73cl::opt<ExpandVariadicsMode> ExpandVariadicsModeOption(
74 DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
75 cl::init(ExpandVariadicsMode::Unspecified),
76 cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
77 "Use the implementation defaults"),
78 clEnumValN(ExpandVariadicsMode::Disable, "disable",
79 "Disable the pass entirely"),
80 clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
81 "Optimise without changing ABI"),
82 clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
83 "Change variadic calling convention")));
84
85bool commandLineOverride() {
86 return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
87}
88
89// Instances of this class encapsulate the target-dependant behaviour as a
90// function of triple. Implementing a new ABI is adding a case to the switch
91// in create(llvm::Triple) at the end of this file.
92// This class may end up instantiated in TargetMachine instances, keeping it
93// here for now until enough targets are implemented for the API to evolve.
94class VariadicABIInfo {
95protected:
96 VariadicABIInfo() = default;
97
98public:
99 static std::unique_ptr<VariadicABIInfo> create(const Triple &T);
100
101 // Allow overriding whether the pass runs on a per-target basis
102 virtual bool enableForTarget() = 0;
103
104 // Whether a valist instance is passed by value or by address
105 // I.e. does it need to be alloca'ed and stored into, or can
106 // it be passed directly in a SSA register
107 virtual bool vaListPassedInSSARegister() = 0;
108
109 // The type of a va_list iterator object
110 virtual Type *vaListType(LLVMContext &Ctx) = 0;
111
112 // The type of a va_list as a function argument as lowered by C
113 virtual Type *vaListParameterType(Module &M) = 0;
114
115 // Initialize an allocated va_list object to point to an already
116 // initialized contiguous memory region.
117 // Return the value to pass as the va_list argument
118 virtual Value *initializeVaList(Module &M, LLVMContext &Ctx,
119 IRBuilder<> &Builder, AllocaInst *VaList,
120 Value *Buffer) = 0;
121
122 struct VAArgSlotInfo {
123 Align DataAlign; // With respect to the call frame
124 bool Indirect; // Passed via a pointer
125 };
126 virtual VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) = 0;
127
128 // Targets implemented so far all have the same trivial lowering for these
129 bool vaEndIsNop() { return true; }
130 bool vaCopyIsMemcpy() { return true; }
131
132 virtual ~VariadicABIInfo() = default;
133};
134
135// Module implements getFunction() which returns nullptr on missing declaration
136// and getOrInsertFunction which creates one when absent. Intrinsics.h only
137// implements getDeclaration which creates one when missing. Checking whether
138// an intrinsic exists thus inserts it in the module and it then needs to be
139// deleted again to clean up.
140// The right name for the two functions on intrinsics would match Module::,
141// but doing that in a single change would introduce nullptr dereferences
142// where currently there are none. The minimal collateral damage approach
143// would split the change over a release to help downstream branches. As it
144// is unclear what approach will be preferred, implementing the trivial
145// function here in the meantime to decouple from that discussion.
146Function *getPreexistingDeclaration(Module *M, Intrinsic::ID Id,
147 ArrayRef<Type *> Tys = {}) {
148 if (Tys.empty())
150 auto *FT = Intrinsic::getType(M->getContext(), Id, Tys);
151 return Intrinsic::getDeclarationIfExists(M, Id, Tys, FT);
152}
153
154class ExpandVariadics : public ModulePass {
155
156 // The pass construction sets the default to optimize when called from middle
157 // end and lowering when called from the backend. The command line variable
158 // overrides that. This is useful for testing and debugging. It also allows
159 // building an applications with variadic functions wholly removed if one
160 // has sufficient control over the dependencies, e.g. a statically linked
161 // clang that has no variadic function calls remaining in the binary.
162
163public:
164 static char ID;
165 const ExpandVariadicsMode Mode;
166 std::unique_ptr<VariadicABIInfo> ABI;
167
168 ExpandVariadics(ExpandVariadicsMode Mode)
169 : ModulePass(ID),
170 Mode(commandLineOverride() ? ExpandVariadicsModeOption : Mode) {}
171
172 StringRef getPassName() const override { return "Expand variadic functions"; }
173
174 bool rewriteABI() { return Mode == ExpandVariadicsMode::Lowering; }
175
176 bool runOnModule(Module &M) override;
177
178 bool runOnFunction(Module &M, IRBuilder<> &Builder, Function *F);
179
180 Function *replaceAllUsesWithNewDeclaration(Module &M,
181 Function *OriginalFunction);
182
183 Function *deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
184 Function *OriginalFunction);
185
186 Function *defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
187 Function *VariadicWrapper,
188 Function *FixedArityReplacement);
189
190 bool expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB, FunctionType *,
191 Function *NF);
192
193 // The intrinsic functions va_copy and va_end are removed unconditionally.
194 // They correspond to a memcpy and a no-op on all implemented targets.
195 // The va_start intrinsic is removed from basic blocks that were not created
196 // by this pass, some may remain if needed to maintain the external ABI.
197
198 template <Intrinsic::ID ID, typename InstructionType>
199 bool expandIntrinsicUsers(Module &M, IRBuilder<> &Builder,
200 PointerType *IntrinsicArgType) {
201 bool Changed = false;
202 const DataLayout &DL = M.getDataLayout();
203 if (Function *Intrinsic =
204 getPreexistingDeclaration(&M, ID, {IntrinsicArgType})) {
205 for (User *U : make_early_inc_range(Intrinsic->users()))
206 if (auto *I = dyn_cast<InstructionType>(U))
207 Changed |= expandVAIntrinsicCall(Builder, DL, I);
208
209 if (Intrinsic->use_empty())
210 Intrinsic->eraseFromParent();
211 }
212 return Changed;
213 }
214
215 bool expandVAIntrinsicUsersWithAddrspace(Module &M, IRBuilder<> &Builder,
216 unsigned Addrspace) {
217 auto &Ctx = M.getContext();
218 PointerType *IntrinsicArgType = PointerType::get(Ctx, Addrspace);
219 bool Changed = false;
220
221 // expand vastart before vacopy as vastart may introduce a vacopy
222 Changed |= expandIntrinsicUsers<Intrinsic::vastart, VAStartInst>(
223 M, Builder, IntrinsicArgType);
224 Changed |= expandIntrinsicUsers<Intrinsic::vaend, VAEndInst>(
225 M, Builder, IntrinsicArgType);
226 Changed |= expandIntrinsicUsers<Intrinsic::vacopy, VACopyInst>(
227 M, Builder, IntrinsicArgType);
228 return Changed;
229 }
230
231 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
232 VAStartInst *Inst);
233
234 bool expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
235 VAEndInst *Inst);
236
237 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
238 VACopyInst *Inst);
239
240 FunctionType *inlinableVariadicFunctionType(Module &M, FunctionType *FTy) {
241 // The type of "FTy" with the ... removed and a va_list appended
242 SmallVector<Type *> ArgTypes(FTy->params());
243 ArgTypes.push_back(ABI->vaListParameterType(M));
244 return FunctionType::get(FTy->getReturnType(), ArgTypes,
245 /*IsVarArgs=*/false);
246 }
247
248 static ConstantInt *sizeOfAlloca(LLVMContext &Ctx, const DataLayout &DL,
249 AllocaInst *Alloced) {
250 std::optional<TypeSize> AllocaTypeSize = Alloced->getAllocationSize(DL);
251 uint64_t AsInt = AllocaTypeSize ? AllocaTypeSize->getFixedValue() : 0;
252 return ConstantInt::get(Type::getInt64Ty(Ctx), AsInt);
253 }
254
255 bool expansionApplicableToFunction(Module &M, Function *F) {
256 if (F->isIntrinsic() || !F->isVarArg() ||
257 F->hasFnAttribute(Attribute::Naked))
258 return false;
259
260 if (F->getCallingConv() != CallingConv::C)
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 (CI->getCallingConv() != CallingConv::C)
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) {
330
331 StructType *VarargsTy = cast<StructType>(Alloced->getAllocatedType());
332
333 for (size_t I = 0; I < size(); I++) {
334
335 auto [V, bytes, tag] = Source[I];
336
337 if (tag == Padding) {
338 assert(V == nullptr);
339 continue;
340 }
341
342 auto Dst = Builder.CreateStructGEP(VarargsTy, Alloced, I);
343
344 assert(V != nullptr);
345
346 if (tag == Store)
347 Builder.CreateStore(V, Dst);
348
349 if (tag == Memcpy)
350 Builder.CreateMemCpy(Dst, {}, V, {}, bytes);
351 }
352 }
353 };
354};
355
356bool ExpandVariadics::runOnModule(Module &M) {
357 bool Changed = false;
358 if (Mode == ExpandVariadicsMode::Disable)
359 return Changed;
360
361 Triple TT(M.getTargetTriple());
362 ABI = VariadicABIInfo::create(TT);
363 if (!ABI)
364 return Changed;
365
366 if (!ABI->enableForTarget())
367 return Changed;
368
369 auto &Ctx = M.getContext();
370 const DataLayout &DL = M.getDataLayout();
371 IRBuilder<> Builder(Ctx);
372
373 // Lowering needs to run on all functions exactly once.
374 // Optimize could run on functions containing va_start exactly once.
376 Changed |= runOnFunction(M, Builder, &F);
377
378 // After runOnFunction, all known calls to known variadic functions have been
379 // replaced. va_start intrinsics are presently (and invalidly!) only present
380 // in functions that used to be variadic and have now been replaced to take a
381 // va_list instead. If lowering as opposed to optimising, calls to unknown
382 // variadic functions have also been replaced.
383
384 {
385 // 0 and AllocaAddrSpace are sufficient for the targets implemented so far
386 unsigned Addrspace = 0;
387 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
388
389 Addrspace = DL.getAllocaAddrSpace();
390 if (Addrspace != 0)
391 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
392 }
393
394 if (Mode != ExpandVariadicsMode::Lowering)
395 return Changed;
396
397 for (Function &F : make_early_inc_range(M)) {
398 if (F.isDeclaration())
399 continue;
400
401 // Now need to track down indirect calls. Can't find those
402 // by walking uses of variadic functions, need to crawl the instruction
403 // stream. Fortunately this is only necessary for the ABI rewrite case.
404 for (BasicBlock &BB : F) {
405 for (Instruction &I : make_early_inc_range(BB)) {
406 if (CallBase *CB = dyn_cast<CallBase>(&I)) {
407 if (CB->isIndirectCall()) {
408 FunctionType *FTy = CB->getFunctionType();
409 if (FTy->isVarArg())
410 Changed |= expandCall(M, Builder, CB, FTy, 0);
411 }
412 }
413 }
414 }
415 }
416
417 return Changed;
418}
419
420bool ExpandVariadics::runOnFunction(Module &M, IRBuilder<> &Builder,
421 Function *OriginalFunction) {
422 bool Changed = false;
423
424 if (!expansionApplicableToFunction(M, OriginalFunction))
425 return Changed;
426
427 [[maybe_unused]] const bool OriginalFunctionIsDeclaration =
428 OriginalFunction->isDeclaration();
429 assert(rewriteABI() || !OriginalFunctionIsDeclaration);
430
431 // Declare a new function and redirect every use to that new function
432 Function *VariadicWrapper =
433 replaceAllUsesWithNewDeclaration(M, OriginalFunction);
434 assert(VariadicWrapper->isDeclaration());
435 assert(OriginalFunction->use_empty());
436
437 // Create a new function taking va_list containing the implementation of the
438 // original
439 Function *FixedArityReplacement =
440 deriveFixedArityReplacement(M, Builder, OriginalFunction);
441 assert(OriginalFunction->isDeclaration());
442 assert(FixedArityReplacement->isDeclaration() ==
443 OriginalFunctionIsDeclaration);
444 assert(VariadicWrapper->isDeclaration());
445
446 // Create a single block forwarding wrapper that turns a ... into a va_list
447 [[maybe_unused]] Function *VariadicWrapperDefine =
448 defineVariadicWrapper(M, Builder, VariadicWrapper, FixedArityReplacement);
449 assert(VariadicWrapperDefine == VariadicWrapper);
450 assert(!VariadicWrapper->isDeclaration());
451
452 // We now have:
453 // 1. the original function, now as a declaration with no uses
454 // 2. a variadic function that unconditionally calls a fixed arity replacement
455 // 3. a fixed arity function equivalent to the original function
456
457 // Replace known calls to the variadic with calls to the va_list equivalent
458 for (User *U : make_early_inc_range(VariadicWrapper->users())) {
459 if (CallBase *CB = dyn_cast<CallBase>(U)) {
460 Value *CalledOperand = CB->getCalledOperand();
461 if (VariadicWrapper == CalledOperand)
462 Changed |=
463 expandCall(M, Builder, CB, VariadicWrapper->getFunctionType(),
464 FixedArityReplacement);
465 }
466 }
467
468 // The original function will be erased.
469 // One of the two new functions will become a replacement for the original.
470 // When preserving the ABI, the other is an internal implementation detail.
471 // When rewriting the ABI, RAUW then the variadic one.
472 Function *const ExternallyAccessible =
473 rewriteABI() ? FixedArityReplacement : VariadicWrapper;
474 Function *const InternalOnly =
475 rewriteABI() ? VariadicWrapper : FixedArityReplacement;
476
477 // The external function is the replacement for the original
478 ExternallyAccessible->setLinkage(OriginalFunction->getLinkage());
479 ExternallyAccessible->setVisibility(OriginalFunction->getVisibility());
480 ExternallyAccessible->setComdat(OriginalFunction->getComdat());
481 ExternallyAccessible->takeName(OriginalFunction);
482
483 // Annotate the internal one as internal
486
487 // The original is unused and obsolete
488 OriginalFunction->eraseFromParent();
489
490 InternalOnly->removeDeadConstantUsers();
491
492 if (rewriteABI()) {
493 // All known calls to the function have been removed by expandCall
494 // Resolve everything else by replaceAllUsesWith
495 VariadicWrapper->replaceAllUsesWith(FixedArityReplacement);
496 VariadicWrapper->eraseFromParent();
497 }
498
499 return Changed;
500}
501
502Function *
503ExpandVariadics::replaceAllUsesWithNewDeclaration(Module &M,
504 Function *OriginalFunction) {
505 auto &Ctx = M.getContext();
506 Function &F = *OriginalFunction;
507 FunctionType *FTy = F.getFunctionType();
508 Function *NF = Function::Create(FTy, F.getLinkage(), F.getAddressSpace());
509
510 NF->setName(F.getName() + ".varargs");
511 NF->IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
512
513 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
514
515 AttrBuilder ParamAttrs(Ctx);
516 AttributeList Attrs = NF->getAttributes();
517 Attrs = Attrs.addParamAttributes(Ctx, FTy->getNumParams(), ParamAttrs);
518 NF->setAttributes(Attrs);
519
520 OriginalFunction->replaceAllUsesWith(NF);
521 return NF;
522}
523
524Function *
525ExpandVariadics::deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
526 Function *OriginalFunction) {
527 Function &F = *OriginalFunction;
528 // The purpose here is split the variadic function F into two functions
529 // One is a variadic function that bundles the passed argument into a va_list
530 // and passes it to the second function. The second function does whatever
531 // the original F does, except that it takes a va_list instead of the ...
532
533 assert(expansionApplicableToFunction(M, &F));
534
535 auto &Ctx = M.getContext();
536
537 // Returned value isDeclaration() is equal to F.isDeclaration()
538 // but that property is not invariant throughout this function
539 const bool FunctionIsDefinition = !F.isDeclaration();
540
541 FunctionType *FTy = F.getFunctionType();
542 SmallVector<Type *> ArgTypes(FTy->params());
543 ArgTypes.push_back(ABI->vaListParameterType(M));
544
545 FunctionType *NFTy = inlinableVariadicFunctionType(M, FTy);
546 Function *NF = Function::Create(NFTy, F.getLinkage(), F.getAddressSpace());
547
548 // Note - same attribute handling as DeadArgumentElimination
549 NF->copyAttributesFrom(&F);
550 NF->setComdat(F.getComdat());
551 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
552 NF->setName(F.getName() + ".valist");
553 NF->IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
554
555 AttrBuilder ParamAttrs(Ctx);
556
557 AttributeList Attrs = NF->getAttributes();
558 Attrs = Attrs.addParamAttributes(Ctx, NFTy->getNumParams() - 1, ParamAttrs);
559 NF->setAttributes(Attrs);
560
561 // Splice the implementation into the new function with minimal changes
562 if (FunctionIsDefinition) {
563 NF->splice(NF->begin(), &F);
564
565 auto NewArg = NF->arg_begin();
566 for (Argument &Arg : F.args()) {
567 Arg.replaceAllUsesWith(NewArg);
568 NewArg->setName(Arg.getName()); // takeName without killing the old one
569 ++NewArg;
570 }
571 NewArg->setName("varargs");
572 }
573
575 F.getAllMetadata(MDs);
576 for (auto [KindID, Node] : MDs)
577 NF->addMetadata(KindID, *Node);
578 F.clearMetadata();
579
580 return NF;
581}
582
583Function *
584ExpandVariadics::defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
585 Function *VariadicWrapper,
586 Function *FixedArityReplacement) {
587 auto &Ctx = Builder.getContext();
588 const DataLayout &DL = M.getDataLayout();
589 assert(VariadicWrapper->isDeclaration());
590 Function &F = *VariadicWrapper;
591
592 assert(F.isDeclaration());
593 Type *VaListTy = ABI->vaListType(Ctx);
594
595 auto *BB = BasicBlock::Create(Ctx, "entry", &F);
596 Builder.SetInsertPoint(BB);
597
598 AllocaInst *VaListInstance =
599 Builder.CreateAlloca(VaListTy, nullptr, "va_start");
600
601 Builder.CreateLifetimeStart(VaListInstance,
602 sizeOfAlloca(Ctx, DL, VaListInstance));
603
604 Builder.CreateIntrinsic(Intrinsic::vastart, {DL.getAllocaPtrType(Ctx)},
605 {VaListInstance});
606
608 for (Argument &A : F.args())
609 Args.push_back(&A);
610
611 Type *ParameterType = ABI->vaListParameterType(M);
612 if (ABI->vaListPassedInSSARegister())
613 Args.push_back(Builder.CreateLoad(ParameterType, VaListInstance));
614 else
615 Args.push_back(Builder.CreateAddrSpaceCast(VaListInstance, ParameterType));
616
617 CallInst *Result = Builder.CreateCall(FixedArityReplacement, Args);
618
619 Builder.CreateIntrinsic(Intrinsic::vaend, {DL.getAllocaPtrType(Ctx)},
620 {VaListInstance});
621 Builder.CreateLifetimeEnd(VaListInstance,
622 sizeOfAlloca(Ctx, DL, VaListInstance));
623
624 if (Result->getType()->isVoidTy())
625 Builder.CreateRetVoid();
626 else
627 Builder.CreateRet(Result);
628
629 return VariadicWrapper;
630}
631
632bool ExpandVariadics::expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB,
633 FunctionType *VarargFunctionType,
634 Function *NF) {
635 bool Changed = false;
636 const DataLayout &DL = M.getDataLayout();
637
638 if (!expansionApplicableToFunctionCall(CB)) {
639 if (rewriteABI())
640 report_fatal_error("Cannot lower callbase instruction");
641 return Changed;
642 }
643
644 // This is tricky. The call instruction's function type might not match
645 // the type of the caller. When optimising, can leave it unchanged.
646 // Webassembly detects that inconsistency and repairs it.
647 FunctionType *FuncType = CB->getFunctionType();
648 if (FuncType != VarargFunctionType) {
649 if (!rewriteABI())
650 return Changed;
651 FuncType = VarargFunctionType;
652 }
653
654 auto &Ctx = CB->getContext();
655
656 Align MaxFieldAlign(1);
657
658 // The strategy is to allocate a call frame containing the variadic
659 // arguments laid out such that a target specific va_list can be initialized
660 // with it, such that target specific va_arg instructions will correctly
661 // iterate over it. This means getting the alignment right and sometimes
662 // embedding a pointer to the value instead of embedding the value itself.
663
664 Function *CBF = CB->getParent()->getParent();
665
666 ExpandedCallFrame Frame;
667
668 uint64_t CurrentOffset = 0;
669
670 for (unsigned I = FuncType->getNumParams(), E = CB->arg_size(); I < E; ++I) {
671 Value *ArgVal = CB->getArgOperand(I);
672 const bool IsByVal = CB->paramHasAttr(I, Attribute::ByVal);
673 const bool IsByRef = CB->paramHasAttr(I, Attribute::ByRef);
674
675 // The type of the value being passed, decoded from byval/byref metadata if
676 // required
677 Type *const UnderlyingType = IsByVal ? CB->getParamByValType(I)
678 : IsByRef ? CB->getParamByRefType(I)
679 : ArgVal->getType();
680 const uint64_t UnderlyingSize =
681 DL.getTypeAllocSize(UnderlyingType).getFixedValue();
682
683 // The type to be written into the call frame
684 Type *FrameFieldType = UnderlyingType;
685
686 // The value to copy from when initialising the frame alloca
687 Value *SourceValue = ArgVal;
688
689 VariadicABIInfo::VAArgSlotInfo SlotInfo = ABI->slotInfo(DL, UnderlyingType);
690
691 if (SlotInfo.Indirect) {
692 // The va_arg lowering loads through a pointer. Set up an alloca to aim
693 // that pointer at.
694 Builder.SetInsertPointPastAllocas(CBF);
696 Value *CallerCopy =
697 Builder.CreateAlloca(UnderlyingType, nullptr, "IndirectAlloca");
698
699 Builder.SetInsertPoint(CB);
700 if (IsByVal)
701 Builder.CreateMemCpy(CallerCopy, {}, ArgVal, {}, UnderlyingSize);
702 else
703 Builder.CreateStore(ArgVal, CallerCopy);
704
705 // Indirection now handled, pass the alloca ptr by value
706 FrameFieldType = DL.getAllocaPtrType(Ctx);
707 SourceValue = CallerCopy;
708 }
709
710 // Alignment of the value within the frame
711 // This probably needs to be controllable as a function of type
712 Align DataAlign = SlotInfo.DataAlign;
713
714 MaxFieldAlign = std::max(MaxFieldAlign, DataAlign);
715
716 uint64_t DataAlignV = DataAlign.value();
717 if (uint64_t Rem = CurrentOffset % DataAlignV) {
718 // Inject explicit padding to deal with alignment requirements
719 uint64_t Padding = DataAlignV - Rem;
720 Frame.padding(Ctx, Padding);
721 CurrentOffset += Padding;
722 }
723
724 if (SlotInfo.Indirect) {
725 Frame.store(Ctx, FrameFieldType, SourceValue);
726 } else {
727 if (IsByVal)
728 Frame.memcpy(Ctx, FrameFieldType, SourceValue, UnderlyingSize);
729 else
730 Frame.store(Ctx, FrameFieldType, SourceValue);
731 }
732
733 CurrentOffset += DL.getTypeAllocSize(FrameFieldType).getFixedValue();
734 }
735
736 if (Frame.empty()) {
737 // Not passing any arguments, hopefully va_arg won't try to read any
738 // Creating a single byte frame containing nothing to point the va_list
739 // instance as that is less special-casey in the compiler and probably
740 // easier to interpret in a debugger.
741 Frame.padding(Ctx, 1);
742 }
743
744 StructType *VarargsTy = Frame.asStruct(Ctx, CBF->getName());
745
746 // The struct instance needs to be at least MaxFieldAlign for the alignment of
747 // the fields to be correct at runtime. Use the native stack alignment instead
748 // if that's greater as that tends to give better codegen.
749 // This is an awkward way to guess whether there is a known stack alignment
750 // without hitting an assert in DL.getStackAlignment, 1024 is an arbitrary
751 // number likely to be greater than the natural stack alignment.
752 Align AllocaAlign = MaxFieldAlign;
753 if (MaybeAlign StackAlign = DL.getStackAlignment();
754 StackAlign && *StackAlign > AllocaAlign)
755 AllocaAlign = *StackAlign;
756
757 // Put the alloca to hold the variadic args in the entry basic block.
758 Builder.SetInsertPointPastAllocas(CBF);
759
760 // SetCurrentDebugLocation when the builder SetInsertPoint method does not
762
763 // The awkward construction here is to set the alignment on the instance
764 AllocaInst *Alloced = Builder.Insert(
765 new AllocaInst(VarargsTy, DL.getAllocaAddrSpace(), nullptr, AllocaAlign),
766 "vararg_buffer");
767 Changed = true;
768 assert(Alloced->getAllocatedType() == VarargsTy);
769
770 // Initialize the fields in the struct
771 Builder.SetInsertPoint(CB);
772 Builder.CreateLifetimeStart(Alloced, sizeOfAlloca(Ctx, DL, Alloced));
773 Frame.initializeStructAlloca(DL, Builder, Alloced);
774
775 const unsigned NumArgs = FuncType->getNumParams();
776 SmallVector<Value *> Args(CB->arg_begin(), CB->arg_begin() + NumArgs);
777
778 // Initialize a va_list pointing to that struct and pass it as the last
779 // argument
780 AllocaInst *VaList = nullptr;
781 {
782 if (!ABI->vaListPassedInSSARegister()) {
783 Type *VaListTy = ABI->vaListType(Ctx);
784 Builder.SetInsertPointPastAllocas(CBF);
786 VaList = Builder.CreateAlloca(VaListTy, nullptr, "va_argument");
787 Builder.SetInsertPoint(CB);
788 Builder.CreateLifetimeStart(VaList, sizeOfAlloca(Ctx, DL, VaList));
789 }
790 Builder.SetInsertPoint(CB);
791 Args.push_back(ABI->initializeVaList(M, Ctx, Builder, VaList, Alloced));
792 }
793
794 // Attributes excluding any on the vararg arguments
795 AttributeList PAL = CB->getAttributes();
796 if (!PAL.isEmpty()) {
798 for (unsigned ArgNo = 0; ArgNo < NumArgs; ArgNo++)
799 ArgAttrs.push_back(PAL.getParamAttrs(ArgNo));
800 PAL =
801 AttributeList::get(Ctx, PAL.getFnAttrs(), PAL.getRetAttrs(), ArgAttrs);
802 }
803
805 CB->getOperandBundlesAsDefs(OpBundles);
806
807 CallBase *NewCB = nullptr;
808
809 if (CallInst *CI = dyn_cast<CallInst>(CB)) {
810 Value *Dst = NF ? NF : CI->getCalledOperand();
811 FunctionType *NFTy = inlinableVariadicFunctionType(M, VarargFunctionType);
812
813 NewCB = CallInst::Create(NFTy, Dst, Args, OpBundles, "", CI->getIterator());
814
815 CallInst::TailCallKind TCK = CI->getTailCallKind();
817
818 // Can't tail call a function that is being passed a pointer to an alloca
819 if (TCK == CallInst::TCK_Tail)
820 TCK = CallInst::TCK_None;
821 CI->setTailCallKind(TCK);
822
823 } else {
824 llvm_unreachable("Unreachable when !expansionApplicableToFunctionCall()");
825 }
826
827 if (VaList)
828 Builder.CreateLifetimeEnd(VaList, sizeOfAlloca(Ctx, DL, VaList));
829
830 Builder.CreateLifetimeEnd(Alloced, sizeOfAlloca(Ctx, DL, Alloced));
831
832 NewCB->setAttributes(PAL);
833 NewCB->takeName(CB);
834 NewCB->setCallingConv(CB->getCallingConv());
835 NewCB->setDebugLoc(DebugLoc());
836
837 // DeadArgElim and ArgPromotion copy exactly this metadata
838 NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
839
840 CB->replaceAllUsesWith(NewCB);
841 CB->eraseFromParent();
842 return Changed;
843}
844
845bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
846 const DataLayout &DL,
847 VAStartInst *Inst) {
848 // Only removing va_start instructions that are not in variadic functions.
849 // Those would be rejected by the IR verifier before this pass.
850 // After splicing basic blocks from a variadic function into a fixed arity
851 // one the va_start that used to refer to the ... parameter still exist.
852 // There are also variadic functions that this pass did not change and
853 // va_start instances in the created single block wrapper functions.
854 // Replace exactly the instances in non-variadic functions as those are
855 // the ones to be fixed up to use the va_list passed as the final argument.
856
857 Function *ContainingFunction = Inst->getFunction();
858 if (ContainingFunction->isVarArg()) {
859 return false;
860 }
861
862 // The last argument is a vaListParameterType, either a va_list
863 // or a pointer to one depending on the target.
864 bool PassedByValue = ABI->vaListPassedInSSARegister();
865 Argument *PassedVaList =
866 ContainingFunction->getArg(ContainingFunction->arg_size() - 1);
867
868 // va_start takes a pointer to a va_list, e.g. one on the stack
869 Value *VaStartArg = Inst->getArgList();
870
871 Builder.SetInsertPoint(Inst);
872
873 if (PassedByValue) {
874 // The general thing to do is create an alloca, store the va_list argument
875 // to it, then create a va_copy. When vaCopyIsMemcpy(), this optimises to a
876 // store to the VaStartArg.
877 assert(ABI->vaCopyIsMemcpy());
878 Builder.CreateStore(PassedVaList, VaStartArg);
879 } else {
880
881 // Otherwise emit a vacopy to pick up target-specific handling if any
882 auto &Ctx = Builder.getContext();
883
884 Builder.CreateIntrinsic(Intrinsic::vacopy, {DL.getAllocaPtrType(Ctx)},
885 {VaStartArg, PassedVaList});
886 }
887
888 Inst->eraseFromParent();
889 return true;
890}
891
892bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
893 VAEndInst *Inst) {
894 assert(ABI->vaEndIsNop());
895 Inst->eraseFromParent();
896 return true;
897}
898
899bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
900 const DataLayout &DL,
901 VACopyInst *Inst) {
902 assert(ABI->vaCopyIsMemcpy());
903 Builder.SetInsertPoint(Inst);
904
905 auto &Ctx = Builder.getContext();
906 Type *VaListTy = ABI->vaListType(Ctx);
907 uint64_t Size = DL.getTypeAllocSize(VaListTy).getFixedValue();
908
909 Builder.CreateMemCpy(Inst->getDest(), {}, Inst->getSrc(), {},
910 Builder.getInt32(Size));
911
912 Inst->eraseFromParent();
913 return true;
914}
915
916struct Amdgpu final : public VariadicABIInfo {
917
918 bool enableForTarget() override { return true; }
919
920 bool vaListPassedInSSARegister() override { return true; }
921
922 Type *vaListType(LLVMContext &Ctx) override {
923 return PointerType::getUnqual(Ctx);
924 }
925
926 Type *vaListParameterType(Module &M) override {
927 return PointerType::getUnqual(M.getContext());
928 }
929
930 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
931 AllocaInst * /*va_list*/, Value *Buffer) override {
932 // Given Buffer, which is an AllocInst of vararg_buffer
933 // need to return something usable as parameter type
934 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
935 }
936
937 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
938 return {Align(4), false};
939 }
940};
941
942struct NVPTX final : public VariadicABIInfo {
943
944 bool enableForTarget() override { return true; }
945
946 bool vaListPassedInSSARegister() override { return true; }
947
948 Type *vaListType(LLVMContext &Ctx) override {
949 return PointerType::getUnqual(Ctx);
950 }
951
952 Type *vaListParameterType(Module &M) override {
953 return PointerType::getUnqual(M.getContext());
954 }
955
956 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
957 AllocaInst *, Value *Buffer) override {
958 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
959 }
960
961 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
962 // NVPTX expects natural alignment in all cases. The variadic call ABI will
963 // handle promoting types to their appropriate size and alignment.
964 Align A = DL.getABITypeAlign(Parameter);
965 return {A, false};
966 }
967};
968
969struct Wasm final : public VariadicABIInfo {
970
971 bool enableForTarget() override {
972 // Currently wasm is only used for testing.
973 return commandLineOverride();
974 }
975
976 bool vaListPassedInSSARegister() override { return true; }
977
978 Type *vaListType(LLVMContext &Ctx) override {
979 return PointerType::getUnqual(Ctx);
980 }
981
982 Type *vaListParameterType(Module &M) override {
983 return PointerType::getUnqual(M.getContext());
984 }
985
986 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
987 AllocaInst * /*va_list*/, Value *Buffer) override {
988 return Buffer;
989 }
990
991 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
992 LLVMContext &Ctx = Parameter->getContext();
993 const unsigned MinAlign = 4;
994 Align A = DL.getABITypeAlign(Parameter);
995 if (A < MinAlign)
996 A = Align(MinAlign);
997
998 if (auto *S = dyn_cast<StructType>(Parameter)) {
999 if (S->getNumElements() > 1) {
1000 return {DL.getABITypeAlign(PointerType::getUnqual(Ctx)), true};
1001 }
1002 }
1003
1004 return {A, false};
1005 }
1006};
1007
1008std::unique_ptr<VariadicABIInfo> VariadicABIInfo::create(const Triple &T) {
1009 switch (T.getArch()) {
1010 case Triple::r600:
1011 case Triple::amdgcn: {
1012 return std::make_unique<Amdgpu>();
1013 }
1014
1015 case Triple::wasm32: {
1016 return std::make_unique<Wasm>();
1017 }
1018
1019 case Triple::nvptx:
1020 case Triple::nvptx64: {
1021 return std::make_unique<NVPTX>();
1022 }
1023
1024 default:
1025 return {};
1026 }
1027}
1028
1029} // namespace
1030
1031char ExpandVariadics::ID = 0;
1032
1033INITIALIZE_PASS(ExpandVariadics, DEBUG_TYPE, "Expand variadic functions", false,
1034 false)
1035
1037 return new ExpandVariadics(M);
1038}
1039
1041 return ExpandVariadics(Mode).runOnModule(M) ? PreservedAnalyses::none()
1043}
1044
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:686
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::string Name
uint64_t Size
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:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
an instruction to allocate memory on the stack
Definition: Instructions.h:63
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: Instructions.h:117
std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
AttributeSet getFnAttrs() const
The function attributes are returned.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
bool isEmpty() const
Return true if there are no attributes.
Definition: Attributes.h:1021
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:212
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1120
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1411
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.
Definition: InstrTypes.h:1755
CallingConv::ID getCallingConv() const
Definition: InstrTypes.h:1407
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.
Definition: InstrTypes.h:1269
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Definition: InstrTypes.h:1764
void setAttributes(AttributeList A)
Set the attributes for this call.
Definition: InstrTypes.h:1428
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1294
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1207
unsigned arg_size() const
Definition: InstrTypes.h:1292
AttributeList getAttributes() const
Return the attributes for this call.
Definition: InstrTypes.h:1425
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)
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
Definition: Constants.cpp:739
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:33
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
ExpandVariadicsPass(ExpandVariadicsMode Mode)
static 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:173
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:216
bool IsNewDbgInfoFormat
Is this function using intrinsics to record the position of debugging information,...
Definition: Function.h:116
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:353
iterator begin()
Definition: Function.h:853
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Function.cpp:458
arg_iterator arg_begin()
Definition: Function.h:868
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition: Function.h:356
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:234
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:860
void setComdat(Comdat *C)
Definition: Globals.cpp:212
const Comdat * getComdat() const
Definition: GlobalObject.h:128
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
Definition: Metadata.cpp:1565
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:248
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:296
LinkageTypes getLinkage() const
Definition: GlobalValue.h:546
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:537
@ DefaultVisibility
The GV is visible.
Definition: GlobalValue.h:67
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:254
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1796
CallInst * CreateLifetimeStart(Value *Ptr, ConstantInt *Size=nullptr)
Create a lifetime.start intrinsic.
Definition: IRBuilder.cpp:460
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:890
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Definition: IRBuilder.h:1995
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1119
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Definition: IRBuilder.h:217
void SetInsertPointPastAllocas(Function *F)
This specifies that created instructions should inserted at the beginning end of the specified functi...
Definition: IRBuilder.h:211
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:483
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition: IRBuilder.h:142
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition: IRBuilder.h:1813
LLVMContext & getContext() const
Definition: IRBuilder.h:173
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1114
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1826
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2444
CallInst * CreateLifetimeEnd(Value *Ptr, ConstantInt *Size=nullptr)
Create a lifetime.end intrinsic.
Definition: IRBuilder.cpp:472
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:177
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
Definition: IRBuilder.h:655
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2160
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2697
const DebugLoc & getStableDebugLoc() const
Fetch the debug location for this node, unless this is a debug intrinsic, in which case fetch the deb...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:92
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:70
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:468
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:67
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:686
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Class to represent struct types.
Definition: DerivedTypes.h:218
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:612
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
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:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
iterator_range< user_iterator > users()
Definition: Value.h:421
bool use_empty() const
Definition: Value.h:344
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1075
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:383
const ParentTy * getParent() const
Definition: ilist_node.h:32
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
Definition: Intrinsics.cpp:746
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys={})
Return the function type for an intrinsic.
Definition: Intrinsics.cpp:584
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:711
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:1697
ModulePass * createExpandVariadicsPass(ExpandVariadicsMode)
@ Wasm
WebAssembly Exception Handling.
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:657
ExpandVariadicsMode
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
Definition: MathExtras.h:366
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117