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