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
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),
77 "Use the implementation defaults"),
79 "Disable the pass entirely"),
81 "Optimise without changing ABI"),
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 // Per-target overrides of special symbols.
133 virtual bool ignoreFunction(const Function *F) { return false; }
134
135 // Any additional address spaces used in va intrinsics that should be
136 // expanded.
137 virtual SmallVector<unsigned> getTargetSpecificVaIntrinAddrSpaces() const {
138 return {};
139 }
140
141 virtual ~VariadicABIInfo() = default;
142};
143
144class ExpandVariadics : public ModulePass {
145
146 // The pass construction sets the default to optimize when called from middle
147 // end and lowering when called from the backend. The command line variable
148 // overrides that. This is useful for testing and debugging. It also allows
149 // building an applications with variadic functions wholly removed if one
150 // has sufficient control over the dependencies, e.g. a statically linked
151 // clang that has no variadic function calls remaining in the binary.
152
153public:
154 static char ID;
156 std::unique_ptr<VariadicABIInfo> ABI;
157
158 ExpandVariadics(ExpandVariadicsMode Mode)
159 : ModulePass(ID),
160 Mode(commandLineOverride() ? ExpandVariadicsModeOption : Mode) {}
161
162 StringRef getPassName() const override { return "Expand variadic functions"; }
163
164 bool rewriteABI() { return Mode == ExpandVariadicsMode::Lowering; }
165
166 template <typename T> bool isValidCallingConv(T *F) {
167 return F->getCallingConv() == CallingConv::C ||
168 F->getCallingConv() == CallingConv::SPIR_FUNC;
169 }
170
171 bool runOnModule(Module &M) override;
172
173 bool runOnFunction(Module &M, IRBuilder<> &Builder, Function *F);
174
175 Function *replaceAllUsesWithNewDeclaration(Module &M,
176 Function *OriginalFunction);
177
178 Function *deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
179 Function *OriginalFunction);
180
181 Function *defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
182 Function *VariadicWrapper,
183 Function *FixedArityReplacement);
184
185 bool expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB, FunctionType *,
186 Function *NF);
187
188 // The intrinsic functions va_copy and va_end are removed unconditionally.
189 // They correspond to a memcpy and a no-op on all implemented targets.
190 // The va_start intrinsic is removed from basic blocks that were not created
191 // by this pass, some may remain if needed to maintain the external ABI.
192
193 template <Intrinsic::ID ID, typename InstructionType>
194 bool expandIntrinsicUsers(Module &M, IRBuilder<> &Builder,
195 PointerType *IntrinsicArgType) {
196 bool Changed = false;
197 const DataLayout &DL = M.getDataLayout();
198 if (Function *Intrinsic =
199 Intrinsic::getDeclarationIfExists(&M, ID, {IntrinsicArgType})) {
200 for (User *U : make_early_inc_range(Intrinsic->users()))
201 if (auto *I = dyn_cast<InstructionType>(U))
202 Changed |= expandVAIntrinsicCall(Builder, DL, I);
203
204 if (Intrinsic->use_empty())
205 Intrinsic->eraseFromParent();
206 }
207 return Changed;
208 }
209
210 bool expandVAIntrinsicUsersWithAddrspace(Module &M, IRBuilder<> &Builder,
211 unsigned Addrspace) {
212 auto &Ctx = M.getContext();
213 PointerType *IntrinsicArgType = PointerType::get(Ctx, Addrspace);
214 bool Changed = false;
215
216 // expand vastart before vacopy as vastart may introduce a vacopy
217 Changed |= expandIntrinsicUsers<Intrinsic::vastart, VAStartInst>(
218 M, Builder, IntrinsicArgType);
219 Changed |= expandIntrinsicUsers<Intrinsic::vaend, VAEndInst>(
220 M, Builder, IntrinsicArgType);
221 Changed |= expandIntrinsicUsers<Intrinsic::vacopy, VACopyInst>(
222 M, Builder, IntrinsicArgType);
223 return Changed;
224 }
225
226 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
227 VAStartInst *Inst);
228
229 bool expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
230 VAEndInst *Inst);
231
232 bool expandVAIntrinsicCall(IRBuilder<> &Builder, const DataLayout &DL,
233 VACopyInst *Inst);
234
235 FunctionType *inlinableVariadicFunctionType(Module &M, FunctionType *FTy) {
236 // The type of "FTy" with the ... removed and a va_list appended
237 SmallVector<Type *> ArgTypes(FTy->params());
238 ArgTypes.push_back(ABI->vaListParameterType(M));
239 return FunctionType::get(FTy->getReturnType(), ArgTypes,
240 /*IsVarArgs=*/false);
241 }
242
243 bool expansionApplicableToFunction(Module &M, Function *F) {
244 if (F->isIntrinsic() || !F->isVarArg() ||
245 F->hasFnAttribute(Attribute::Naked))
246 return false;
247
248 if (ABI->ignoreFunction(F))
249 return false;
250
251 if (!isValidCallingConv(F))
252 return false;
253
254 if (rewriteABI())
255 return true;
256
257 if (!F->hasExactDefinition())
258 return false;
259
260 return true;
261 }
262
263 bool expansionApplicableToFunctionCall(CallBase *CB) {
264 if (CallInst *CI = dyn_cast<CallInst>(CB)) {
265 if (CI->isMustTailCall()) {
266 // Cannot expand musttail calls
267 return false;
268 }
269
270 if (!isValidCallingConv(CI))
271 return false;
272
273 return true;
274 }
275
276 if (isa<InvokeInst>(CB)) {
277 // Invoke not implemented in initial implementation of pass
278 return false;
279 }
280
281 // Other unimplemented derivative of CallBase
282 return false;
283 }
284
285 class ExpandedCallFrame {
286 // Helper for constructing an alloca instance containing the arguments bound
287 // to the variadic ... parameter, rearranged to allow indexing through a
288 // va_list iterator
289 enum { N = 4 };
290 SmallVector<Type *, N> FieldTypes;
291 enum Tag { Store, Memcpy, Padding };
293
294 template <Tag tag> void append(Type *FieldType, Value *V, uint64_t Bytes) {
295 FieldTypes.push_back(FieldType);
296 Source.push_back({V, Bytes, tag});
297 }
298
299 public:
300 void store(LLVMContext &Ctx, Type *T, Value *V) { append<Store>(T, V, 0); }
301
302 void memcpy(LLVMContext &Ctx, Type *T, Value *V, uint64_t Bytes) {
303 append<Memcpy>(T, V, Bytes);
304 }
305
306 void padding(LLVMContext &Ctx, uint64_t By) {
307 append<Padding>(ArrayType::get(Type::getInt8Ty(Ctx), By), nullptr, 0);
308 }
309
310 size_t size() const { return FieldTypes.size(); }
311 bool empty() const { return FieldTypes.empty(); }
312
313 StructType *asStruct(LLVMContext &Ctx, StringRef Name) {
314 const bool IsPacked = true;
315 return StructType::create(Ctx, FieldTypes,
316 (Twine(Name) + ".vararg").str(), IsPacked);
317 }
318
319 void initializeStructAlloca(const DataLayout &DL, IRBuilder<> &Builder,
320 AllocaInst *Alloced, StructType *VarargsTy) {
321
322 for (size_t I = 0; I < size(); I++) {
323
324 auto [V, bytes, tag] = Source[I];
325
326 if (tag == Padding) {
327 assert(V == nullptr);
328 continue;
329 }
330
331 auto Dst = Builder.CreateStructGEP(VarargsTy, Alloced, I);
332
333 assert(V != nullptr);
334
335 if (tag == Store)
336 Builder.CreateStore(V, Dst);
337
338 if (tag == Memcpy)
339 Builder.CreateMemCpy(Dst, {}, V, {}, bytes);
340 }
341 }
342 };
343};
344
345bool ExpandVariadics::runOnModule(Module &M) {
346 bool Changed = false;
348 return Changed;
349
350 Triple TT(M.getTargetTriple());
351 ABI = VariadicABIInfo::create(TT);
352 if (!ABI)
353 return Changed;
354
355 if (!ABI->enableForTarget())
356 return Changed;
357
358 auto &Ctx = M.getContext();
359 const DataLayout &DL = M.getDataLayout();
360 IRBuilder<> Builder(Ctx);
361
362 // Lowering needs to run on all functions exactly once.
363 // Optimize could run on functions containing va_start exactly once.
365 Changed |= runOnFunction(M, Builder, &F);
366
367 // After runOnFunction, all known calls to known variadic functions have been
368 // replaced. va_start intrinsics are presently (and invalidly!) only present
369 // in functions that used to be variadic and have now been replaced to take a
370 // va_list instead. If lowering as opposed to optimising, calls to unknown
371 // variadic functions have also been replaced.
372
373 {
374 unsigned Addrspace = 0;
375 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
376
377 Addrspace = DL.getAllocaAddrSpace();
378 if (Addrspace != 0)
379 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, Addrspace);
380
381 // Process any addrspaces targets declare to be important.
382 const SmallVector<unsigned> &TargetASVec =
383 ABI->getTargetSpecificVaIntrinAddrSpaces();
384 for (unsigned TargetAS : TargetASVec) {
385 if (TargetAS == 0 || TargetAS == DL.getAllocaAddrSpace())
386 continue;
387 Changed |= expandVAIntrinsicUsersWithAddrspace(M, Builder, TargetAS);
388 }
389 }
390
392 return Changed;
393
394 for (Function &F : make_early_inc_range(M)) {
395 if (F.isDeclaration())
396 continue;
397
398 // Now need to track down indirect calls. Can't find those
399 // by walking uses of variadic functions, need to crawl the instruction
400 // stream. Fortunately this is only necessary for the ABI rewrite case.
401 for (BasicBlock &BB : F) {
402 for (Instruction &I : make_early_inc_range(BB)) {
403 if (CallBase *CB = dyn_cast<CallBase>(&I)) {
404 if (CB->isIndirectCall()) {
405 FunctionType *FTy = CB->getFunctionType();
406 if (FTy->isVarArg())
407 Changed |= expandCall(M, Builder, CB, FTy, /*NF=*/nullptr);
408 }
409 }
410 }
411 }
412 }
413
414 return Changed;
415}
416
417bool ExpandVariadics::runOnFunction(Module &M, IRBuilder<> &Builder,
418 Function *OriginalFunction) {
419 bool Changed = false;
420
421 if (!expansionApplicableToFunction(M, OriginalFunction))
422 return Changed;
423
424 [[maybe_unused]] const bool OriginalFunctionIsDeclaration =
425 OriginalFunction->isDeclaration();
426 assert(rewriteABI() || !OriginalFunctionIsDeclaration);
427
428 // Declare a new function and redirect every use to that new function
429 Function *VariadicWrapper =
430 replaceAllUsesWithNewDeclaration(M, OriginalFunction);
431 assert(VariadicWrapper->isDeclaration());
432 assert(OriginalFunction->use_empty());
433
434 // Create a new function taking va_list containing the implementation of the
435 // original
436 Function *FixedArityReplacement =
437 deriveFixedArityReplacement(M, Builder, OriginalFunction);
438 assert(OriginalFunction->isDeclaration());
439 assert(FixedArityReplacement->isDeclaration() ==
440 OriginalFunctionIsDeclaration);
441 assert(VariadicWrapper->isDeclaration());
442
443 // Create a single block forwarding wrapper that turns a ... into a va_list
444 [[maybe_unused]] Function *VariadicWrapperDefine =
445 defineVariadicWrapper(M, Builder, VariadicWrapper, FixedArityReplacement);
446 assert(VariadicWrapperDefine == VariadicWrapper);
447 assert(!VariadicWrapper->isDeclaration());
448
449 // Add the prof metadata from the original function to the wrapper. Because
450 // FixedArityReplacement is the owner of original function's prof metadata
451 // after the splice, we need to transfer it to VariadicWrapper.
452 VariadicWrapper->setMetadata(
453 LLVMContext::MD_prof,
454 FixedArityReplacement->getMetadata(LLVMContext::MD_prof));
455
456 // We now have:
457 // 1. the original function, now as a declaration with no uses
458 // 2. a variadic function that unconditionally calls a fixed arity replacement
459 // 3. a fixed arity function equivalent to the original function
460
461 // Replace known calls to the variadic with calls to the va_list equivalent
462 for (User *U : make_early_inc_range(VariadicWrapper->users())) {
463 if (CallBase *CB = dyn_cast<CallBase>(U)) {
464 Value *CalledOperand = CB->getCalledOperand();
465 if (VariadicWrapper == CalledOperand)
466 Changed |=
467 expandCall(M, Builder, CB, VariadicWrapper->getFunctionType(),
468 FixedArityReplacement);
469 }
470 }
471
472 // The original function will be erased.
473 // One of the two new functions will become a replacement for the original.
474 // When preserving the ABI, the other is an internal implementation detail.
475 // When rewriting the ABI, RAUW then the variadic one.
476 Function *const ExternallyAccessible =
477 rewriteABI() ? FixedArityReplacement : VariadicWrapper;
478 Function *const InternalOnly =
479 rewriteABI() ? VariadicWrapper : FixedArityReplacement;
480
481 // The external function is the replacement for the original
482 ExternallyAccessible->setLinkage(OriginalFunction->getLinkage());
483 ExternallyAccessible->setVisibility(OriginalFunction->getVisibility());
484 ExternallyAccessible->setComdat(OriginalFunction->getComdat());
485 ExternallyAccessible->takeName(OriginalFunction);
486
487 // Annotate the internal one as internal
490
491 // The original is unused and obsolete
492 OriginalFunction->eraseFromParent();
493
494 InternalOnly->removeDeadConstantUsers();
495
496 if (rewriteABI()) {
497 // All known calls to the function have been removed by expandCall
498 // Resolve everything else by replaceAllUsesWith
499 VariadicWrapper->replaceAllUsesWith(FixedArityReplacement);
500 VariadicWrapper->eraseFromParent();
501 }
502
503 return Changed;
504}
505
506Function *
507ExpandVariadics::replaceAllUsesWithNewDeclaration(Module &M,
508 Function *OriginalFunction) {
509 auto &Ctx = M.getContext();
510 Function &F = *OriginalFunction;
511 FunctionType *FTy = F.getFunctionType();
512 Function *NF = Function::Create(FTy, F.getLinkage(), F.getAddressSpace());
513
514 NF->setName(F.getName() + ".varargs");
515
516 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
517
518 AttrBuilder ParamAttrs(Ctx);
519 AttributeList Attrs = NF->getAttributes();
520 Attrs = Attrs.addParamAttributes(Ctx, FTy->getNumParams(), ParamAttrs);
521 NF->setAttributes(Attrs);
522
523 OriginalFunction->replaceAllUsesWith(NF);
524 return NF;
525}
526
527Function *
528ExpandVariadics::deriveFixedArityReplacement(Module &M, IRBuilder<> &Builder,
529 Function *OriginalFunction) {
530 Function &F = *OriginalFunction;
531 // The purpose here is split the variadic function F into two functions
532 // One is a variadic function that bundles the passed argument into a va_list
533 // and passes it to the second function. The second function does whatever
534 // the original F does, except that it takes a va_list instead of the ...
535
536 assert(expansionApplicableToFunction(M, &F));
537
538 auto &Ctx = M.getContext();
539
540 // Returned value isDeclaration() is equal to F.isDeclaration()
541 // but that property is not invariant throughout this function
542 const bool FunctionIsDefinition = !F.isDeclaration();
543
544 FunctionType *FTy = F.getFunctionType();
545 SmallVector<Type *> ArgTypes(FTy->params());
546 ArgTypes.push_back(ABI->vaListParameterType(M));
547
548 FunctionType *NFTy = inlinableVariadicFunctionType(M, FTy);
549 Function *NF = Function::Create(NFTy, F.getLinkage(), F.getAddressSpace());
550
551 // Note - same attribute handling as DeadArgumentElimination
552 NF->copyAttributesFrom(&F);
553 NF->setComdat(F.getComdat());
554 F.getParent()->getFunctionList().insert(F.getIterator(), NF);
555 NF->setName(F.getName() + ".valist");
556
557 AttrBuilder ParamAttrs(Ctx);
558
559 AttributeList Attrs = NF->getAttributes();
560 Attrs = Attrs.addParamAttributes(Ctx, NFTy->getNumParams() - 1, ParamAttrs);
561 NF->setAttributes(Attrs);
562
563 // Splice the implementation into the new function with minimal changes
564 if (FunctionIsDefinition) {
565 NF->splice(NF->begin(), &F);
566
567 auto NewArg = NF->arg_begin();
568 for (Argument &Arg : F.args()) {
569 Arg.replaceAllUsesWith(NewArg);
570 NewArg->setName(Arg.getName()); // takeName without killing the old one
571 ++NewArg;
572 }
573 NewArg->setName("varargs");
574 }
575
577 F.getAllMetadata(MDs);
578 for (auto [KindID, Node] : MDs)
579 NF->addMetadata(KindID, *Node);
580 F.clearMetadata();
581
582 return NF;
583}
584
585Function *
586ExpandVariadics::defineVariadicWrapper(Module &M, IRBuilder<> &Builder,
587 Function *VariadicWrapper,
588 Function *FixedArityReplacement) {
589 auto &Ctx = Builder.getContext();
590 const DataLayout &DL = M.getDataLayout();
591 assert(VariadicWrapper->isDeclaration());
592 Function &F = *VariadicWrapper;
593
594 assert(F.isDeclaration());
595 Type *VaListTy = ABI->vaListType(Ctx);
596
597 auto *BB = BasicBlock::Create(Ctx, "entry", &F);
598 Builder.SetInsertPoint(BB);
599
600 AllocaInst *VaListInstance =
601 Builder.CreateAlloca(VaListTy, nullptr, "va_start");
602
603 Builder.CreateLifetimeStart(VaListInstance);
604
605 Builder.CreateIntrinsic(Intrinsic::vastart, {DL.getAllocaPtrType(Ctx)},
606 {VaListInstance});
607
609
610 Type *ParameterType = ABI->vaListParameterType(M);
611 if (ABI->vaListPassedInSSARegister())
612 Args.push_back(Builder.CreateLoad(ParameterType, VaListInstance));
613 else
614 Args.push_back(Builder.CreateAddrSpaceCast(VaListInstance, ParameterType));
615
616 CallInst *Result = Builder.CreateCall(FixedArityReplacement, Args);
617
618 Builder.CreateIntrinsic(Intrinsic::vaend, {DL.getAllocaPtrType(Ctx)},
619 {VaListInstance});
620 Builder.CreateLifetimeEnd(VaListInstance);
621
622 if (Result->getType()->isVoidTy())
623 Builder.CreateRetVoid();
624 else
625 Builder.CreateRet(Result);
626
627 return VariadicWrapper;
628}
629
630bool ExpandVariadics::expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB,
631 FunctionType *VarargFunctionType,
632 Function *NF) {
633 bool Changed = false;
634 const DataLayout &DL = M.getDataLayout();
635
636 if (ABI->ignoreFunction(CB->getCalledFunction()))
637 return Changed;
638
639 if (!expansionApplicableToFunctionCall(CB)) {
640 if (rewriteABI())
641 report_fatal_error("Cannot lower callbase instruction");
642 return Changed;
643 }
644
645 // This is tricky. The call instruction's function type might not match
646 // the type of the caller. When optimising, can leave it unchanged.
647 // Webassembly detects that inconsistency and repairs it.
648 FunctionType *FuncType = CB->getFunctionType();
649 if (FuncType != VarargFunctionType) {
650 if (!rewriteABI())
651 return Changed;
652 FuncType = VarargFunctionType;
653 }
654
655 auto &Ctx = CB->getContext();
656
657 Align MaxFieldAlign(1);
658
659 // The strategy is to allocate a call frame containing the variadic
660 // arguments laid out such that a target specific va_list can be initialized
661 // with it, such that target specific va_arg instructions will correctly
662 // iterate over it. This means getting the alignment right and sometimes
663 // embedding a pointer to the value instead of embedding the value itself.
664
665 Function *CBF = CB->getParent()->getParent();
666
667 ExpandedCallFrame Frame;
668
669 uint64_t CurrentOffset = 0;
670
671 for (unsigned I = FuncType->getNumParams(), E = CB->arg_size(); I < E; ++I) {
672 Value *ArgVal = CB->getArgOperand(I);
673 const bool IsByVal = CB->paramHasAttr(I, Attribute::ByVal);
674 const bool IsByRef = CB->paramHasAttr(I, Attribute::ByRef);
675
676 // The type of the value being passed, decoded from byval/byref metadata if
677 // required
678 Type *const UnderlyingType = IsByVal ? CB->getParamByValType(I)
679 : IsByRef ? CB->getParamByRefType(I)
680 : ArgVal->getType();
681 const uint64_t UnderlyingSize =
682 DL.getTypeAllocSize(UnderlyingType).getFixedValue();
683
684 // The type to be written into the call frame
685 Type *FrameFieldType = UnderlyingType;
686
687 // The value to copy from when initialising the frame alloca
688 Value *SourceValue = ArgVal;
689
690 VariadicABIInfo::VAArgSlotInfo SlotInfo = ABI->slotInfo(DL, UnderlyingType);
691
692 if (SlotInfo.Indirect) {
693 // The va_arg lowering loads through a pointer. Set up an alloca to aim
694 // that pointer at.
695 Builder.SetInsertPointPastAllocas(CBF);
696 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
697 Value *CallerCopy =
698 Builder.CreateAlloca(UnderlyingType, nullptr, "IndirectAlloca");
699
700 Builder.SetInsertPoint(CB);
701 if (IsByVal)
702 Builder.CreateMemCpy(CallerCopy, {}, ArgVal, {}, UnderlyingSize);
703 else
704 Builder.CreateStore(ArgVal, CallerCopy);
705
706 // Indirection now handled, pass the alloca ptr by value
707 FrameFieldType = DL.getAllocaPtrType(Ctx);
708 SourceValue = CallerCopy;
709 }
710
711 // Alignment of the value within the frame
712 // This probably needs to be controllable as a function of type
713 Align DataAlign = SlotInfo.DataAlign;
714
715 MaxFieldAlign = std::max(MaxFieldAlign, DataAlign);
716
717 uint64_t DataAlignV = DataAlign.value();
718 if (uint64_t Rem = CurrentOffset % DataAlignV) {
719 // Inject explicit padding to deal with alignment requirements
720 uint64_t Padding = DataAlignV - Rem;
721 Frame.padding(Ctx, Padding);
722 CurrentOffset += Padding;
723 }
724
725 if (SlotInfo.Indirect) {
726 Frame.store(Ctx, FrameFieldType, SourceValue);
727 } else {
728 if (IsByVal)
729 Frame.memcpy(Ctx, FrameFieldType, SourceValue, UnderlyingSize);
730 else
731 Frame.store(Ctx, FrameFieldType, SourceValue);
732 }
733
734 CurrentOffset += DL.getTypeAllocSize(FrameFieldType).getFixedValue();
735 }
736
737 if (Frame.empty()) {
738 // Not passing any arguments, hopefully va_arg won't try to read any
739 // Creating a single byte frame containing nothing to point the va_list
740 // instance as that is less special-casey in the compiler and probably
741 // easier to interpret in a debugger.
742 Frame.padding(Ctx, 1);
743 }
744
745 StructType *VarargsTy = Frame.asStruct(Ctx, CBF->getName());
746
747 // The struct instance needs to be at least MaxFieldAlign for the alignment of
748 // the fields to be correct at runtime. Use the native stack alignment instead
749 // if that's greater as that tends to give better codegen.
750 // This is an awkward way to guess whether there is a known stack alignment
751 // without hitting an assert in DL.getStackAlignment, 1024 is an arbitrary
752 // number likely to be greater than the natural stack alignment.
753 Align AllocaAlign = MaxFieldAlign;
754 if (MaybeAlign StackAlign = DL.getStackAlignment();
755 StackAlign && *StackAlign > AllocaAlign)
756 AllocaAlign = *StackAlign;
757
758 // Put the alloca to hold the variadic args in the entry basic block.
759 Builder.SetInsertPointPastAllocas(CBF);
760
761 // SetCurrentDebugLocation when the builder SetInsertPoint method does not
762 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
763
764 // The awkward construction here is to set the alignment on the instance
765 AllocaInst *Alloced = Builder.Insert(
766 new AllocaInst(VarargsTy, DL.getAllocaAddrSpace(), nullptr, AllocaAlign),
767 "vararg_buffer");
768 Changed = true;
769 assert(Alloced->getAllocatedType() == VarargsTy);
770
771 // Initialize the fields in the struct
772 Builder.SetInsertPoint(CB);
773 Builder.CreateLifetimeStart(Alloced);
774 Frame.initializeStructAlloca(DL, Builder, Alloced, VarargsTy);
775
776 const unsigned NumArgs = FuncType->getNumParams();
777 SmallVector<Value *> Args(CB->arg_begin(), CB->arg_begin() + NumArgs);
778
779 // Initialize a va_list pointing to that struct and pass it as the last
780 // argument
781 AllocaInst *VaList = nullptr;
782 {
783 if (!ABI->vaListPassedInSSARegister()) {
784 Type *VaListTy = ABI->vaListType(Ctx);
785 Builder.SetInsertPointPastAllocas(CBF);
786 Builder.SetCurrentDebugLocation(CB->getStableDebugLoc());
787 VaList = Builder.CreateAlloca(VaListTy, nullptr, "va_argument");
788 Builder.SetInsertPoint(CB);
789 Builder.CreateLifetimeStart(VaList);
790 }
791 Builder.SetInsertPoint(CB);
792 Args.push_back(ABI->initializeVaList(M, Ctx, Builder, VaList, Alloced));
793 }
794
795 // Attributes excluding any on the vararg arguments
796 AttributeList PAL = CB->getAttributes();
797 if (!PAL.isEmpty()) {
799 for (unsigned ArgNo = 0; ArgNo < NumArgs; ArgNo++)
800 ArgAttrs.push_back(PAL.getParamAttrs(ArgNo));
801 PAL =
802 AttributeList::get(Ctx, PAL.getFnAttrs(), PAL.getRetAttrs(), ArgAttrs);
803 }
804
806 CB->getOperandBundlesAsDefs(OpBundles);
807
808 CallBase *NewCB = nullptr;
809
810 if (CallInst *CI = dyn_cast<CallInst>(CB)) {
811 Value *Dst = NF ? NF : CI->getCalledOperand();
812 FunctionType *NFTy = inlinableVariadicFunctionType(M, VarargFunctionType);
813
814 NewCB = CallInst::Create(NFTy, Dst, Args, OpBundles, "", CI->getIterator());
815
816 CallInst::TailCallKind TCK = CI->getTailCallKind();
818
819 // Can't tail call a function that is being passed a pointer to an alloca
820 if (TCK == CallInst::TCK_Tail)
821 TCK = CallInst::TCK_None;
822 CI->setTailCallKind(TCK);
823
824 } else {
825 llvm_unreachable("Unreachable when !expansionApplicableToFunctionCall()");
826 }
827
828 if (VaList)
829 Builder.CreateLifetimeEnd(VaList);
830
831 Builder.CreateLifetimeEnd(Alloced);
832
833 NewCB->setAttributes(PAL);
834 NewCB->takeName(CB);
835 NewCB->setCallingConv(CB->getCallingConv());
836 NewCB->setDebugLoc(DebugLoc());
837
838 // DeadArgElim and ArgPromotion copy exactly this metadata
839 NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
840
841 CB->replaceAllUsesWith(NewCB);
842 CB->eraseFromParent();
843 return Changed;
844}
845
846bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
847 const DataLayout &DL,
848 VAStartInst *Inst) {
849 // Only removing va_start instructions that are not in variadic functions.
850 // Those would be rejected by the IR verifier before this pass.
851 // After splicing basic blocks from a variadic function into a fixed arity
852 // one the va_start that used to refer to the ... parameter still exist.
853 // There are also variadic functions that this pass did not change and
854 // va_start instances in the created single block wrapper functions.
855 // Replace exactly the instances in non-variadic functions as those are
856 // the ones to be fixed up to use the va_list passed as the final argument.
857
858 Function *ContainingFunction = Inst->getFunction();
859 if (ContainingFunction->isVarArg()) {
860 return false;
861 }
862
863 // The last argument is a vaListParameterType, either a va_list
864 // or a pointer to one depending on the target.
865 bool PassedByValue = ABI->vaListPassedInSSARegister();
866 Argument *PassedVaList =
867 ContainingFunction->getArg(ContainingFunction->arg_size() - 1);
868
869 // va_start takes a pointer to a va_list, e.g. one on the stack
870 Value *VaStartArg = Inst->getArgList();
871
872 Builder.SetInsertPoint(Inst);
873
874 if (PassedByValue) {
875 // The general thing to do is create an alloca, store the va_list argument
876 // to it, then create a va_copy. When vaCopyIsMemcpy(), this optimises to a
877 // store to the VaStartArg.
878 assert(ABI->vaCopyIsMemcpy());
879 Builder.CreateStore(PassedVaList, VaStartArg);
880 } else {
881
882 // Otherwise emit a vacopy to pick up target-specific handling if any
883 auto &Ctx = Builder.getContext();
884
885 Builder.CreateIntrinsic(Intrinsic::vacopy, {DL.getAllocaPtrType(Ctx)},
886 {VaStartArg, PassedVaList});
887 }
888
889 Inst->eraseFromParent();
890 return true;
891}
892
893bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &, const DataLayout &,
894 VAEndInst *Inst) {
895 assert(ABI->vaEndIsNop());
896 Inst->eraseFromParent();
897 return true;
898}
899
900bool ExpandVariadics::expandVAIntrinsicCall(IRBuilder<> &Builder,
901 const DataLayout &DL,
902 VACopyInst *Inst) {
903 assert(ABI->vaCopyIsMemcpy());
904 Builder.SetInsertPoint(Inst);
905
906 auto &Ctx = Builder.getContext();
907 Type *VaListTy = ABI->vaListType(Ctx);
908 uint64_t Size = DL.getTypeAllocSize(VaListTy).getFixedValue();
909
910 Builder.CreateMemCpy(Inst->getDest(), {}, Inst->getSrc(), {},
911 Builder.getInt32(Size));
912
913 Inst->eraseFromParent();
914 return true;
915}
916
917struct Amdgpu final : public VariadicABIInfo {
918
919 bool enableForTarget() override { return true; }
920
921 bool vaListPassedInSSARegister() override { return true; }
922
923 Type *vaListType(LLVMContext &Ctx) override {
924 return PointerType::getUnqual(Ctx);
925 }
926
927 Type *vaListParameterType(Module &M) override {
928 return PointerType::getUnqual(M.getContext());
929 }
930
931 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
932 AllocaInst * /*va_list*/, Value *Buffer) override {
933 // Given Buffer, which is an AllocInst of vararg_buffer
934 // need to return something usable as parameter type
935 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
936 }
937
938 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
939 return {Align(4), false};
940 }
941};
942
943struct NVPTX final : public VariadicABIInfo {
944
945 bool enableForTarget() override { return true; }
946
947 bool vaListPassedInSSARegister() override { return true; }
948
949 Type *vaListType(LLVMContext &Ctx) override {
950 return PointerType::getUnqual(Ctx);
951 }
952
953 Type *vaListParameterType(Module &M) override {
954 return PointerType::getUnqual(M.getContext());
955 }
956
957 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
958 AllocaInst *, Value *Buffer) override {
959 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
960 }
961
962 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
963 // NVPTX expects natural alignment in all cases. The variadic call ABI will
964 // handle promoting types to their appropriate size and alignment.
965 Align A = DL.getABITypeAlign(Parameter);
966 return {A, false};
967 }
968};
969
970struct SPIRV final : public VariadicABIInfo {
971
972 bool enableForTarget() override { return true; }
973
974 bool vaListPassedInSSARegister() override { return true; }
975
976 Type *vaListType(LLVMContext &Ctx) override {
977 return PointerType::getUnqual(Ctx);
978 }
979
980 Type *vaListParameterType(Module &M) override {
981 return PointerType::getUnqual(M.getContext());
982 }
983
984 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
985 AllocaInst *, Value *Buffer) override {
986 return Builder.CreateAddrSpaceCast(Buffer, vaListParameterType(M));
987 }
988
989 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
990 // Expects natural alignment in all cases. The variadic call ABI will handle
991 // promoting types to their appropriate size and alignment.
992 Align A = DL.getABITypeAlign(Parameter);
993 return {A, false};
994 }
995
996 // The SPIR-V backend has special handling for builtins.
997 bool ignoreFunction(const Function *F) override {
998 if (!F->isDeclaration())
999 return false;
1000
1001 std::string Demangled = llvm::demangle(F->getName());
1002 StringRef DemangledName(Demangled);
1003
1004 // Skip any SPIR-V builtins.
1005 if (DemangledName.starts_with("__spirv_") ||
1006 DemangledName.starts_with("printf("))
1007 return true;
1008
1009 return false;
1010 }
1011
1012 // We will likely see va intrinsics in the generic addrspace (4).
1013 SmallVector<unsigned> getTargetSpecificVaIntrinAddrSpaces() const override {
1014 return {4};
1015 }
1016};
1017
1018struct Wasm final : public VariadicABIInfo {
1019
1020 bool enableForTarget() override {
1021 // Currently wasm is only used for testing.
1022 return commandLineOverride();
1023 }
1024
1025 bool vaListPassedInSSARegister() override { return true; }
1026
1027 Type *vaListType(LLVMContext &Ctx) override {
1028 return PointerType::getUnqual(Ctx);
1029 }
1030
1031 Type *vaListParameterType(Module &M) override {
1032 return PointerType::getUnqual(M.getContext());
1033 }
1034
1035 Value *initializeVaList(Module &M, LLVMContext &Ctx, IRBuilder<> &Builder,
1036 AllocaInst * /*va_list*/, Value *Buffer) override {
1037 return Buffer;
1038 }
1039
1040 VAArgSlotInfo slotInfo(const DataLayout &DL, Type *Parameter) override {
1041 LLVMContext &Ctx = Parameter->getContext();
1042 const unsigned MinAlign = 4;
1043 Align A = DL.getABITypeAlign(Parameter);
1044 if (A < MinAlign)
1045 A = Align(MinAlign);
1046
1047 if (auto *S = dyn_cast<StructType>(Parameter)) {
1048 if (S->getNumElements() > 1) {
1049 return {DL.getABITypeAlign(PointerType::getUnqual(Ctx)), true};
1050 }
1051 }
1052
1053 return {A, false};
1054 }
1055};
1056
1057std::unique_ptr<VariadicABIInfo> VariadicABIInfo::create(const Triple &T) {
1058 switch (T.getArch()) {
1059 case Triple::r600:
1060 case Triple::amdgcn: {
1061 return std::make_unique<Amdgpu>();
1062 }
1063
1064 case Triple::wasm32: {
1065 return std::make_unique<Wasm>();
1066 }
1067
1068 case Triple::nvptx:
1069 case Triple::nvptx64: {
1070 return std::make_unique<NVPTX>();
1071 }
1072
1073 case Triple::spirv:
1074 case Triple::spirv32:
1075 case Triple::spirv64: {
1076 return std::make_unique<SPIRV>();
1077 }
1078
1079 default:
1080 return {};
1081 }
1082}
1083
1084} // namespace
1085
1086char ExpandVariadics::ID = 0;
1087
1088INITIALIZE_PASS(ExpandVariadics, DEBUG_TYPE, "Expand variadic functions", false,
1089 false)
1090
1092 return new ExpandVariadics(M);
1093}
1094
1096 return ExpandVariadics(Mode).runOnModule(M) ? PreservedAnalyses::none()
1098}
1099
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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
#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")))
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)
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
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
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:217
const Comdat * getComdat() const
LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
Definition Value.h:577
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:331
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:2811
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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:689
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:311
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:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:397
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:259
iterator_range< user_iterator > users()
Definition Value.h:427
bool use_empty() const
Definition Value.h:347
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:403
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:1669
ModulePass * createExpandVariadicsPass(ExpandVariadicsMode)
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:634
ExpandVariadicsMode
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
Definition MathExtras.h:357
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
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition Demangle.cpp:20
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