LLVM 24.0.0git
PreISelIntrinsicLowering.cpp
Go to the documentation of this file.
1//===- PreISelIntrinsicLowering.cpp - Pre-ISel intrinsic lowering pass ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass implements IR lowering for the llvm.memcpy, llvm.memmove,
10// llvm.memset, llvm.load.relative and llvm.objc.* intrinsics.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
22#include "llvm/CodeGen/Passes.h"
26#include "llvm/IR/Function.h"
27#include "llvm/IR/GlobalValue.h"
28#include "llvm/IR/IRBuilder.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/IR/Module.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Use.h"
38#include "llvm/Pass.h"
46
47using namespace llvm;
48
49#define DEBUG_TYPE "pre-isel-intrinsic-lowering"
50
51/// Threshold to leave statically sized memory intrinsic calls. Calls of known
52/// size larger than this will be expanded by the pass. Calls of unknown or
53/// lower size will be left for expansion in codegen.
55 "mem-intrinsic-expand-size",
56 cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1),
58
59namespace {
60
61struct PreISelIntrinsicLowering {
62 const TargetMachine *TM;
63 const ModuleLibcallLoweringInfo &ModuleLibcalls;
64 const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
65 const function_ref<TargetLibraryInfo &(Function &)> LookupTLI;
66
67 /// If this is true, assume it's preferably to leave memory intrinsic calls
68 /// for replacement with a library call later. Otherwise this depends on
69 /// TargetLoweringInfo availability of the corresponding function.
70 const bool UseMemIntrinsicLibFunc;
71
72 explicit PreISelIntrinsicLowering(
73 const TargetMachine *TM_,
74 const ModuleLibcallLoweringInfo &ModuleLibcalls_,
77 bool UseMemIntrinsicLibFunc_ = true)
78 : TM(TM_), ModuleLibcalls(ModuleLibcalls_), LookupTTI(LookupTTI_),
79 LookupTLI(LookupTLI_), UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {
80 }
81
82 static bool shouldExpandMemIntrinsicWithSize(Value *Size,
83 const TargetTransformInfo &TTI);
84 bool
85 expandMemIntrinsicUses(Function &F,
86 DenseMap<Constant *, GlobalVariable *> &CMap) const;
87 bool lowerIntrinsics(Module &M) const;
88};
89
90} // namespace
91
92template <class T> static bool forEachCall(Function &Intrin, T Callback) {
93 // Lowering all intrinsics in a function will delete multiple uses, so we
94 // can't use an early-inc-range. In case some remain, we don't want to look
95 // at them again. Unfortunately, Value::UseList is private, so we can't use a
96 // simple Use**. If LastUse is null, the next use to consider is
97 // Intrin.use_begin(), otherwise it's LastUse->getNext().
98 Use *LastUse = nullptr;
99 bool Changed = false;
100 while (!Intrin.use_empty() && (!LastUse || LastUse->getNext())) {
101 Use *U = LastUse ? LastUse->getNext() : &*Intrin.use_begin();
102 bool Removed = false;
103 // An intrinsic cannot have its address taken, so it cannot be an argument
104 // operand. It might be used as operand in debug metadata, though.
105 if (auto CI = dyn_cast<CallInst>(U->getUser()))
106 Changed |= Removed = Callback(CI);
107 if (!Removed)
108 LastUse = U;
109 }
110 return Changed;
111}
112
114 if (F.use_empty())
115 return false;
116
117 bool Changed = false;
118 Type *Int32Ty = Type::getInt32Ty(F.getContext());
119
120 for (Use &U : llvm::make_early_inc_range(F.uses())) {
121 auto CI = dyn_cast<CallInst>(U.getUser());
122 if (!CI || CI->getCalledOperand() != &F)
123 continue;
124
125 IRBuilder<> B(CI);
126 Value *OffsetPtr =
127 B.CreatePtrAdd(CI->getArgOperand(0), CI->getArgOperand(1));
128 Value *OffsetI32 = B.CreateAlignedLoad(Int32Ty, OffsetPtr, Align(4));
129
130 Value *ResultPtr = B.CreatePtrAdd(CI->getArgOperand(0), OffsetI32);
131
132 CI->replaceAllUsesWith(ResultPtr);
133 CI->eraseFromParent();
134 Changed = true;
135 }
136
137 return Changed;
138}
139
140// ObjCARC has knowledge about whether an obj-c runtime function needs to be
141// always tail-called or never tail-called.
150
151static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
152 bool setNonLazyBind = false) {
154 "Pre-ISel intrinsics do lower into regular function calls");
155 if (F.use_empty())
156 return false;
157
158 // FIXME: When RuntimeLibcalls is an analysis, check if the function is really
159 // supported, and go through RTLIB::Libcall.
161
162 // If we haven't already looked up this function, check to see if the
163 // program already contains a function with this name.
164 Module *M = F.getParent();
165 FunctionCallee FCache =
166 M->getOrInsertFunction(NewFnName, F.getFunctionType());
167
168 if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
169 Fn->setLinkage(F.getLinkage());
170 if (setNonLazyBind && !Fn->isWeakForLinker()) {
171 // If we have Native ARC, set nonlazybind attribute for these APIs for
172 // performance.
173 Fn->addFnAttr(Attribute::NonLazyBind);
174 }
175 }
176
178
179 for (Use &U : llvm::make_early_inc_range(F.uses())) {
180 auto *CB = cast<CallBase>(U.getUser());
181
182 if (CB->getCalledFunction() != &F) {
184 "use expected to be the argument of operand bundle "
185 "\"clang.arc.attachedcall\"");
186 U.set(FCache.getCallee());
187 continue;
188 }
189
190 auto *CI = cast<CallInst>(CB);
191 assert(CI->getCalledFunction() && "Cannot lower an indirect call!");
192
193 IRBuilder<> Builder(CI->getParent(), CI->getIterator());
194 SmallVector<Value *, 8> Args(CI->args());
196 CI->getOperandBundlesAsDefs(BundleList);
197 CallInst *NewCI = Builder.CreateCall(FCache, Args, BundleList);
198 NewCI->setName(CI->getName());
199
200 // Try to set the most appropriate TailCallKind based on both the current
201 // attributes and the ones that we could get from ObjCARC's special
202 // knowledge of the runtime functions.
203 //
204 // std::max respects both requirements of notail and tail here:
205 // * notail on either the call or from ObjCARC becomes notail
206 // * tail on either side is stronger than none, but not notail
207 CallInst::TailCallKind TCK = CI->getTailCallKind();
208 NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
209
210 // Transfer the 'returned' attribute from the intrinsic to the call site.
211 // By applying this only to intrinsic call sites, we avoid applying it to
212 // non-ARC explicit calls to things like objc_retain which have not been
213 // auto-upgraded to use the intrinsics.
214 unsigned Index;
215 if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
216 Index)
217 NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
218 Attribute::Returned);
219
220 if (!CI->use_empty())
221 CI->replaceAllUsesWith(NewCI);
222 CI->eraseFromParent();
223 }
224
225 return true;
226}
227
228// TODO: Should refine based on estimated number of accesses (e.g. does it
229// require splitting based on alignment)
230bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize(
232 ConstantInt *CI = dyn_cast<ConstantInt>(Size);
233 if (!CI)
234 return true;
235 uint64_t Threshold = MemIntrinsicExpandSizeThresholdOpt.getNumOccurrences()
238 uint64_t SizeVal = CI->getZExtValue();
239
240 // Treat a threshold of 0 as a special case to force expansion of all
241 // intrinsics, including size 0.
242 return SizeVal > Threshold || Threshold == 0;
243}
244
245static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering,
246 const TargetMachine *TM, Function *F,
247 RTLIB::Libcall LC) {
248 // TODO: Should this consider the address space of the memcpy?
249 if (!TM)
250 return true;
252 getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
253 return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported;
254}
255
256static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering,
257 const TargetMachine *TM, Function *F) {
258 // TODO: Should this consider the address space of the memcpy?
259 if (!TM)
260 return true;
262 getLibcallLowering(ModuleLowering, *TM->getSubtargetImpl(*F));
263 return Lowering.getMemcpyImpl() != RTLIB::Unsupported;
264}
265
266// Return a value appropriate for use with the memset_pattern16 libcall, if
267// possible and if we know how. (Adapted from equivalent helper in
268// LoopIdiomRecognize).
270 const TargetLibraryInfo &TLI) {
271 // TODO: This could check for UndefValue because it can be merged into any
272 // other valid pattern.
273
274 // Don't emit libcalls if a non-default address space is being used.
275 if (Inst->getRawDest()->getType()->getPointerAddressSpace() != 0)
276 return nullptr;
277
278 Value *V = Inst->getValue();
279 Type *VTy = V->getType();
280 const DataLayout &DL = Inst->getDataLayout();
281 Module *M = Inst->getModule();
282
283 if (!isLibFuncEmittable(M, &TLI, LibFunc_memset_pattern16))
284 return nullptr;
285
286 // If the value isn't a constant, we can't promote it to being in a constant
287 // array. We could theoretically do a store to an alloca or something, but
288 // that doesn't seem worthwhile.
290 if (!C || isa<ConstantExpr>(C))
291 return nullptr;
292
293 // Only handle simple values that are a power of two bytes in size.
294 uint64_t Size = DL.getTypeSizeInBits(VTy);
295 if (!DL.typeSizeEqualsStoreSize(VTy) || !isPowerOf2_64(Size))
296 return nullptr;
297
298 // Don't care enough about darwin/ppc to implement this.
299 if (DL.isBigEndian())
300 return nullptr;
301
302 // Convert to size in bytes.
303 Size /= 8;
304
305 // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see
306 // if the top and bottom are the same (e.g. for vectors and large integers).
307 if (Size > 16)
308 return nullptr;
309
310 // If the constant is exactly 16 bytes, just use it.
311 if (Size == 16)
312 return C;
313
314 // Otherwise, we'll use an array of the constants.
315 uint64_t ArraySize = 16 / Size;
316 ArrayType *AT = ArrayType::get(V->getType(), ArraySize);
317 return ConstantArray::get(AT, std::vector<Constant *>(ArraySize, C));
318}
319
320// TODO: Handle atomic memcpy and memcpy.inline
321// TODO: Pass ScalarEvolution
322bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
323 Function &F, DenseMap<Constant *, GlobalVariable *> &CMap) const {
324 Intrinsic::ID ID = F.getIntrinsicID();
325 bool Changed = false;
326
327 for (User *U : llvm::make_early_inc_range(F.users())) {
329
330 switch (ID) {
331 case Intrinsic::memcpy: {
332 auto *Memcpy = cast<MemCpyInst>(Inst);
333 Function *ParentFunc = Memcpy->getFunction();
334 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
335 if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) {
336 if (UseMemIntrinsicLibFunc &&
337 canEmitMemcpy(ModuleLibcalls, TM, ParentFunc))
338 break;
339
340 // TODO: For optsize, emit the loop into a separate function
341 expandMemCpyAsLoop(Memcpy, TTI);
342 Changed = true;
343 Memcpy->eraseFromParent();
344 }
345
346 break;
347 }
348 case Intrinsic::memcpy_inline: {
349 // Only expand llvm.memcpy.inline with non-constant length in this
350 // codepath, leaving the current SelectionDAG expansion for constant
351 // length memcpy intrinsics undisturbed.
352 auto *Memcpy = cast<MemCpyInst>(Inst);
353 if (isa<ConstantInt>(Memcpy->getLength()))
354 break;
355
356 Function *ParentFunc = Memcpy->getFunction();
357 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
358 expandMemCpyAsLoop(Memcpy, TTI);
359 Changed = true;
360 Memcpy->eraseFromParent();
361 break;
362 }
363 case Intrinsic::memmove: {
364 auto *Memmove = cast<MemMoveInst>(Inst);
365 Function *ParentFunc = Memmove->getFunction();
366 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
367 if (shouldExpandMemIntrinsicWithSize(Memmove->getLength(), TTI)) {
368 if (UseMemIntrinsicLibFunc &&
369 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMMOVE))
370 break;
371
372 if (expandMemMoveAsLoop(Memmove, TTI)) {
373 Changed = true;
374 Memmove->eraseFromParent();
375 }
376 }
377
378 break;
379 }
380 case Intrinsic::memset: {
381 auto *Memset = cast<MemSetInst>(Inst);
382 Function *ParentFunc = Memset->getFunction();
383 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
384 if (shouldExpandMemIntrinsicWithSize(Memset->getLength(), TTI)) {
385 if (UseMemIntrinsicLibFunc &&
386 canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMSET))
387 break;
388
389 expandMemSetAsLoop(Memset, TTI);
390 Changed = true;
391 Memset->eraseFromParent();
392 }
393
394 break;
395 }
396 case Intrinsic::memset_inline: {
397 // Only expand llvm.memset.inline with non-constant length in this
398 // codepath, leaving the current SelectionDAG expansion for constant
399 // length memset intrinsics undisturbed.
400 auto *Memset = cast<MemSetInst>(Inst);
401 if (isa<ConstantInt>(Memset->getLength()))
402 break;
403
404 Function *ParentFunc = Memset->getFunction();
405 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
406 expandMemSetAsLoop(Memset, TTI);
407 Changed = true;
408 Memset->eraseFromParent();
409 break;
410 }
411 case Intrinsic::experimental_memset_pattern: {
412 auto *Memset = cast<MemSetPatternInst>(Inst);
413 Function *ParentFunc = Memset->getFunction();
414 const TargetLibraryInfo &TLI = LookupTLI(*ParentFunc);
415 Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
416 if (!PatternValue) {
417 // If it isn't possible to emit a memset_pattern16 libcall, expand to
418 // a loop instead.
419 const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
421 Changed = true;
422 Memset->eraseFromParent();
423 break;
424 }
425 // FIXME: There is currently no profitability calculation for emitting
426 // the libcall vs expanding the memset.pattern directly.
427 IRBuilder<> Builder(Inst);
428 Module *M = Memset->getModule();
429 const DataLayout &DL = Memset->getDataLayout();
430
431 Type *DestPtrTy = Memset->getRawDest()->getType();
432 Type *SizeTTy = TLI.getSizeTType(*M);
433 StringRef FuncName = "memset_pattern16";
434 FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
435 Builder.getVoidTy(), DestPtrTy,
436 Builder.getPtrTy(), SizeTTy);
437 inferNonMandatoryLibFuncAttrs(M, FuncName, TLI);
438
439 // Otherwise we should form a memset_pattern16. PatternValue is known
440 // to be an constant array of 16-bytes. Put the value into a mergable
441 // global.
442 assert(Memset->getRawDest()->getType()->getPointerAddressSpace() == 0 &&
443 "Should have skipped if non-zero AS");
444 GlobalVariable *GV;
445 auto It = CMap.find(PatternValue);
446 if (It != CMap.end()) {
447 GV = It->second;
448 } else {
449 GV = new GlobalVariable(
450 *M, PatternValue->getType(), /*isConstant=*/true,
451 GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
452 GV->setUnnamedAddr(
453 GlobalValue::UnnamedAddr::Global); // Ok to merge these.
454 // TODO: Consider relaxing alignment requirement.
455 GV->setAlignment(Align(16));
456 CMap[PatternValue] = GV;
457 }
458 Value *PatternPtr = GV;
459 Value *NumBytes = Builder.CreateMul(
460 TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
461 *M),
462 Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
463 CallInst *MemsetPattern16Call =
464 Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
465 MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
466 // Preserve any call site attributes on the destination pointer
467 // argument (e.g. alignment).
468 AttrBuilder ArgAttrs(Memset->getContext(),
469 Memset->getAttributes().getParamAttrs(0));
470 MemsetPattern16Call->setAttributes(
471 MemsetPattern16Call->getAttributes().addParamAttributes(
472 Memset->getContext(), 0, ArgAttrs));
473 Changed = true;
474 Memset->eraseFromParent();
475 break;
476 }
477 default:
478 llvm_unreachable("unhandled intrinsic");
479 }
480 }
481
482 return Changed;
483}
484
486 if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
487 return cast<GlobalValue>(Bundle->Inputs[0]);
488 return nullptr;
489}
490
492 Module &M = *Intr.getParent();
493 if (Triple(M.getTargetTriple()).isArm64e())
494 return false;
495
496 Type *Int64Ty = Type::getInt64Ty(M.getContext());
497
498 assert(Intr.getIntrinsicID() == Intrinsic::ptrauth_sign ||
499 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth);
500 auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
501 FunctionCallee EmuIntr = M.getOrInsertFunction(
502 Intr.getIntrinsicID() == Intrinsic::ptrauth_auth ? "__emupac_autda"
503 : "__emupac_pacda",
504 EmuFnTy);
505
506 for (User *U : llvm::make_early_inc_range(Intr.users())) {
507 auto *Call = cast<CallInst>(U);
508 // We only support the DA key for now.
509 if (auto *Key = dyn_cast<ConstantInt>(Call->getArgOperand(1));
510 !Key || Key->getZExtValue() != /*AArch64PACKey::DA*/ 2)
511 continue;
512
513 Function *F = Call->getParent()->getParent();
514 Attribute FSAttr = F->getFnAttribute("target-features");
515 if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
516 continue;
517
518 std::vector<OperandBundleDef> DSBundle;
519 if (auto *DS = getDeactivationSymbol(Call))
520 DSBundle.push_back(OperandBundleDef("deactivation-symbol", DS));
521
523 auto *EmuCall = B.CreateCall(
524 EmuIntr, {Call->getArgOperand(0), Call->getArgOperand(2)}, DSBundle);
525 Call->replaceAllUsesWith(EmuCall);
526 Call->eraseFromParent();
527 }
528 return true;
529}
530
532 Module &M = *Intr.getParent();
533
534 SmallPtrSet<GlobalValue *, 2> DSsToDeactivate;
535
536 Type *Int8Ty = Type::getInt8Ty(M.getContext());
537 Type *Int64Ty = Type::getInt64Ty(M.getContext());
538 PointerType *PtrTy = PointerType::get(M.getContext(), 0);
539
540 for (User *U : llvm::make_early_inc_range(Intr.users())) {
541 auto *Call = cast<CallInst>(U);
542
543 auto *Pointer = Call->getArgOperand(0);
544 bool UseHWEncoding =
545 cast<ConstantInt>(Call->getArgOperand(2))->getZExtValue();
546 if (!UseHWEncoding)
547 reportFatalUsageError("software encoding currently unsupported");
548
549 auto *DS = getDeactivationSymbol(Call);
550 OperandBundleDef DSBundle("deactivation-symbol", DS);
551
552 for (Use &U : llvm::make_early_inc_range(Call->uses())) {
553 // Comparisons against null cannot be used to recover the original
554 // pointer so we replace them with comparisons against the original
555 // pointer.
556 if (auto *CI = dyn_cast<ICmpInst>(U.getUser())) {
557 if (auto *Op = dyn_cast<Constant>(CI->getOperand(0))) {
558 if (Op->isNullValue()) {
559 CI->setOperand(1, Pointer);
560 continue;
561 }
562 }
563 if (auto *Op = dyn_cast<Constant>(CI->getOperand(1))) {
564 if (Op->isNullValue()) {
565 CI->setOperand(0, Pointer);
566 continue;
567 }
568 }
569 }
570
571 // If we are here, this means that we couldn't rewrite away this use of
572 // the intrinsic. Any load or store uses were removed by InstCombine, and
573 // in general, we can't rewrite away non-load/store uses of
574 // llvm.protected.field.ptr because doing so could expose the encoded
575 // pointer value to the program. Replace it with the pointer operand, and
576 // arrange to define a deactivation symbol.
577 U.set(Pointer);
578 if (DS)
579 DSsToDeactivate.insert(DS);
580 }
581
582 Call->eraseFromParent();
583 }
584
585 if (!DSsToDeactivate.empty()) {
586 // This is an AArch64 NOP instruction. When the deactivation symbol support
587 // is expanded to more architectures, there will likely need to be an API
588 // for retrieving this constant.
589 Constant *Nop =
590 ConstantExpr::getIntToPtr(ConstantInt::get(Int64Ty, 0xd503201f), PtrTy);
591 for (GlobalValue *OldDS : DSsToDeactivate) {
593 Int8Ty, 0, GlobalValue::ExternalLinkage, OldDS->getName(), Nop, &M);
594 DS->setVisibility(GlobalValue::HiddenVisibility);
595 DS->takeName(OldDS);
596 OldDS->replaceAllUsesWith(DS);
597 OldDS->eraseFromParent();
598 }
599 }
600 return true;
601}
602
603static bool expandCondLoop(Function &Intr) {
604 for (User *U : llvm::make_early_inc_range(Intr.users())) {
605 auto *Call = cast<CallInst>(U);
606
607 auto *Br = cast<UncondBrInst>(
608 SplitBlockAndInsertIfThen(Call->getArgOperand(0), Call, false,
610 *Call->getFunction(), DEBUG_TYPE)));
611 Br->setSuccessor(Br->getParent());
612 Call->eraseFromParent();
613 }
614 return true;
615}
616
617static bool expandLoopTrap(Function &Intr) {
618 for (User *U : make_early_inc_range(Intr.users())) {
619 auto *Call = cast<CallInst>(U);
620 if (!Call->getParent()->isEntryBlock() &&
621 std::all_of(Call->getParent()->begin(), BasicBlock::iterator(Call),
622 [](Instruction &I) { return !I.mayHaveSideEffects(); })) {
623 for (auto *BB : predecessors(Call->getParent())) {
624 auto *BI = dyn_cast<CondBrInst>(BB->getTerminator());
625 if (!BI)
626 continue;
627 IRBuilder<> B(BI);
628 Value *Cond;
629 // The looptrap can either be on the true branch or the false branch.
630 // We insert the cond loop before the branch, which uses the branch's
631 // original condition for going to the looptrap as its condition, and
632 // force the branch to take whichever path does not lead to the
633 // looptrap, as the original path to the looptrap is now unreachable
634 // thanks to the cond loop. The codegenprepare pass will clean up our
635 // "unconditional conditional branch" by combining the two basic blocks
636 // if possible, or replacing it with an unconditional branch.
637 if (BI->getSuccessor(0) == Call->getParent()) {
638 // The looptrap is on the true branch.
639 Cond = BI->getCondition();
640 BI->setCondition(ConstantInt::getFalse(BI->getContext()));
641 } else {
642 // The looptrap is on the false branch, which means that we need to
643 // invert the condition.
644 Cond = B.CreateNot(BI->getCondition());
645 BI->setCondition(ConstantInt::getTrue(BI->getContext()));
646 }
647 B.CreateIntrinsic(Intrinsic::cond_loop, Cond);
648 }
649 }
651 B.CreateIntrinsic(Intrinsic::cond_loop,
652 ConstantInt::getTrue(Call->getContext()));
653 Call->eraseFromParent();
654 }
655 return true;
656}
657
658bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
659 // Map unique constants to globals.
660 DenseMap<Constant *, GlobalVariable *> CMap;
661 bool Changed = false;
662 for (Function &F : M) {
663 switch (F.getIntrinsicID()) {
664 default:
665 break;
666 case Intrinsic::memcpy:
667 case Intrinsic::memcpy_inline:
668 case Intrinsic::memmove:
669 case Intrinsic::memset:
670 case Intrinsic::memset_inline:
671 case Intrinsic::experimental_memset_pattern:
672 Changed |= expandMemIntrinsicUses(F, CMap);
673 break;
674 case Intrinsic::load_relative:
676 break;
677 case Intrinsic::is_constant:
678 case Intrinsic::objectsize:
679 Changed |= forEachCall(F, [&](CallInst *CI) {
680 Function *Parent = CI->getParent()->getParent();
681 TargetLibraryInfo &TLI = LookupTLI(*Parent);
682 // Intrinsics in unreachable code are not lowered.
683 bool Changed = lowerConstantIntrinsics(*Parent, TLI, /*DT=*/nullptr);
684 return Changed;
685 });
686 break;
687#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
688 case Intrinsic::VPID:
689#include "llvm/IR/VPIntrinsics.def"
690 forEachCall(F, [&](CallInst *CI) {
691 Function *Parent = CI->getParent()->getParent();
692 const TargetTransformInfo &TTI = LookupTTI(*Parent);
693 auto *VPI = cast<VPIntrinsic>(CI);
695 // Expansion of VP intrinsics may change the IR but not actually
696 // replace the intrinsic, so update Changed for the pass
697 // and compute Removed for forEachCall.
698 Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
699 bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
700 return Removed;
701 });
702 break;
703 case Intrinsic::objc_autorelease:
704 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autorelease);
705 break;
706 case Intrinsic::objc_autoreleasePoolPop:
707 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPop);
708 break;
709 case Intrinsic::objc_autoreleasePoolPush:
710 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPush);
711 break;
712 case Intrinsic::objc_autoreleaseReturnValue:
713 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleaseReturnValue);
714 break;
715 case Intrinsic::objc_copyWeak:
716 Changed |= lowerObjCCall(F, RTLIB::impl_objc_copyWeak);
717 break;
718 case Intrinsic::objc_destroyWeak:
719 Changed |= lowerObjCCall(F, RTLIB::impl_objc_destroyWeak);
720 break;
721 case Intrinsic::objc_initWeak:
722 Changed |= lowerObjCCall(F, RTLIB::impl_objc_initWeak);
723 break;
724 case Intrinsic::objc_loadWeak:
725 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeak);
726 break;
727 case Intrinsic::objc_loadWeakRetained:
728 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeakRetained);
729 break;
730 case Intrinsic::objc_moveWeak:
731 Changed |= lowerObjCCall(F, RTLIB::impl_objc_moveWeak);
732 break;
733 case Intrinsic::objc_release:
734 Changed |= lowerObjCCall(F, RTLIB::impl_objc_release, true);
735 break;
736 case Intrinsic::objc_retain:
737 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain, true);
738 break;
739 case Intrinsic::objc_retainAutorelease:
740 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainAutorelease);
741 break;
742 case Intrinsic::objc_retainAutoreleaseReturnValue:
743 Changed |=
744 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleaseReturnValue);
745 break;
746 case Intrinsic::objc_retainAutoreleasedReturnValue:
747 Changed |=
748 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleasedReturnValue);
749 break;
750 case Intrinsic::objc_claimAutoreleasedReturnValue:
751 Changed |=
752 lowerObjCCall(F, RTLIB::impl_objc_claimAutoreleasedReturnValue);
753 break;
754 case Intrinsic::objc_retainBlock:
755 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainBlock);
756 break;
757 case Intrinsic::objc_storeStrong:
758 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeStrong);
759 break;
760 case Intrinsic::objc_storeWeak:
761 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeWeak);
762 break;
763 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
764 Changed |=
765 lowerObjCCall(F, RTLIB::impl_objc_unsafeClaimAutoreleasedReturnValue);
766 break;
767 case Intrinsic::objc_retainedObject:
768 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainedObject);
769 break;
770 case Intrinsic::objc_unretainedObject:
771 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedObject);
772 break;
773 case Intrinsic::objc_unretainedPointer:
774 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedPointer);
775 break;
776 case Intrinsic::objc_retain_autorelease:
777 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain_autorelease);
778 break;
779 case Intrinsic::objc_sync_enter:
780 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_enter);
781 break;
782 case Intrinsic::objc_sync_exit:
783 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_exit);
784 break;
785 case Intrinsic::acos:
786 case Intrinsic::asin:
787 case Intrinsic::atan:
788 case Intrinsic::cos:
789 case Intrinsic::cosh:
790 case Intrinsic::exp:
791 case Intrinsic::exp2:
792 case Intrinsic::exp10:
793 case Intrinsic::log:
794 case Intrinsic::log2:
795 case Intrinsic::log10:
796 case Intrinsic::sin:
797 case Intrinsic::sinh:
798 case Intrinsic::tan:
799 case Intrinsic::tanh:
800 Changed |= forEachCall(F, [&](CallInst *CI) {
801 Type *Ty = CI->getArgOperand(0)->getType();
803 return false;
804 const TargetLowering *TL = TM->getSubtargetImpl(F)->getTargetLowering();
805 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
806 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
807 if (!TL->isOperationExpand(Op, EVT::getEVT(Ty)))
808 return false;
810 });
811 break;
812 case Intrinsic::modf:
813 case Intrinsic::sincos:
814 case Intrinsic::sincospi:
815 Changed |= forEachCall(F, [&](CallInst *CI) {
816 Type *Ty = CI->getArgOperand(0)->getType();
818 return false;
819 const TargetLowering *TL = TM->getSubtargetImpl(F)->getTargetLowering();
820 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
821 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
822 EVT VT = EVT::getEVT(Ty);
823 if (!TL->isOperationExpand(Op, VT))
824 return false;
825 // The vector legalizer can expand these to a vector math library call.
826 RTLIB::Libcall LC;
827 switch (Op) {
828 case ISD::FMODF:
829 LC = RTLIB::getMODF(VT);
830 break;
831 case ISD::FSINCOS:
832 LC = RTLIB::getSINCOS(VT);
833 break;
834 case ISD::FSINCOSPI:
835 LC = RTLIB::getSINCOSPI(VT);
836 break;
837 default:
838 llvm_unreachable("unexpected intrinsic");
839 }
840 if (TL->getLibcallImpl(LC) != RTLIB::Unsupported)
841 return false;
843 });
844 break;
845 case Intrinsic::ptrauth_sign:
846 case Intrinsic::ptrauth_auth:
848 break;
849 case Intrinsic::protected_field_ptr:
851 break;
852 case Intrinsic::cond_loop:
853 if (!TM->canLowerCondLoop())
855 break;
856 case Intrinsic::looptrap:
858 if (!TM->canLowerCondLoop())
859 if (auto *CondLoop = M.getFunction("llvm.cond.loop"))
860 Changed |= expandCondLoop(*CondLoop);
861 break;
862 }
863 }
864 return Changed;
865}
866
867namespace {
868
869class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
870public:
871 static char ID;
872
873 PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
874
875 void getAnalysisUsage(AnalysisUsage &AU) const override {
876 AU.addRequired<TargetTransformInfoWrapperPass>();
877 AU.addRequired<TargetLibraryInfoWrapperPass>();
878 AU.addRequired<LibcallLoweringInfoWrapper>();
879 AU.addRequired<TargetPassConfig>();
880 }
881
882 bool runOnModule(Module &M) override {
883 const ModuleLibcallLoweringInfo &ModuleLibcalls =
884 getAnalysis<LibcallLoweringInfoWrapper>().getResult(M);
885
886 auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
887 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
888 };
889 auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
890 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
891 };
892
893 const auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
894 PreISelIntrinsicLowering Lowering(TM, ModuleLibcalls, LookupTTI, LookupTLI);
895 return Lowering.lowerIntrinsics(M);
896 }
897};
898
899} // end anonymous namespace
900
901char PreISelIntrinsicLoweringLegacyPass::ID;
902
903INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
904 "pre-isel-intrinsic-lowering",
905 "Pre-ISel Intrinsic Lowering", false, false)
911INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
912 "pre-isel-intrinsic-lowering",
913 "Pre-ISel Intrinsic Lowering", false, false)
914
916 return new PreISelIntrinsicLoweringLegacyPass();
917}
918
921 const ModuleLibcallLoweringInfo &LibcallLowering =
923
924 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
925
926 auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
927 return FAM.getResult<TargetIRAnalysis>(F);
928 };
929 auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
930 return FAM.getResult<TargetLibraryAnalysis>(F);
931 };
932
933 PreISelIntrinsicLowering Lowering(TM, LibcallLowering, LookupTTI, LookupTLI);
934 if (!Lowering.lowerIntrinsics(M))
935 return PreservedAnalyses::all();
936 else
938}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool setNonLazyBind(Function &F)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
Module.h This file contains the declarations for the Module class.
This defines the Use class.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file contains the declarations for metadata subclasses.
#define T
This file defines ARC utility functions which are used by various parts of the compiler.
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static cl::opt< int64_t > MemIntrinsicExpandSizeThresholdOpt("mem-intrinsic-expand-size", cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1), cl::Hidden)
Threshold to leave statically sized memory intrinsic calls.
static bool canEmitMemcpy(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine *TM, Function *F)
static GlobalValue * getDeactivationSymbol(CallInst *Call)
static bool canEmitLibcall(const ModuleLibcallLoweringInfo &ModuleLowering, const TargetMachine *TM, Function *F, RTLIB::Libcall LC)
static bool forEachCall(Function &Intrin, T Callback)
static bool expandLoopTrap(Function &Intr)
static bool expandCondLoop(Function &Intr)
pre isel intrinsic Pre ISel Intrinsic Lowering
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static bool expandPtrauthForEmuPAC(Function &Intr)
static Constant * getMemSetPattern16Value(MemSetPatternInst *Inst, const TargetLibraryInfo &TLI)
static bool expandProtectedFieldPtr(Function &Intr)
static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn, bool setNonLazyBind=false)
static bool lowerLoadRelative(Function &F)
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
AnalysisUsage & addRequired()
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:266
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCallKind(TailCallKind TCK)
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:251
iterator end()
Definition DenseMap.h:169
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:247
const Function & getFunction() const
Definition Function.h:167
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:692
void setUnnamedAddr(UnnamedAddr Val)
Module * getParent()
Get the module that this global value is contained inside of...
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2908
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI bool mayLowerToFunctionCall(Intrinsic::ID IID)
Check if the intrinsic might lower into a regular function call in the course of IR transformations.
Tracks which library functions to use for a particular subtarget or function.
Value * getRawDest() const
Value * getValue() const
This class wraps the llvm.experimental.memset.pattern intrinsic.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
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:68
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
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
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition StringRef.h:446
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
ConstantInt * getAsSizeT(uint64_t V, const Module &M) const
Returns a constant materialized as a size_t type.
IntegerType * getSizeTType(const Module &M) const
Returns an IntegerType corresponding to size_t.
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Get the libcall impl routine name for the specified libcall.
int IntrinsicIDToISD(Intrinsic::ID ID) const
Get the ISD node that corresponds to the Intrinsic ID.
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual bool canLowerCondLoop() const
Returns whether the backend can lower the llvm.cond.loop intrinsic.
Target-Independent Code Generator Pass Configuration Options.
virtual const TargetLowering * getTargetLowering() const
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI uint64_t getMaxMemIntrinsicInlineSizeThreshold() const
Returns the maximum memset / memcpy size in bytes that still makes it profitable to inline the call.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
Definition Triple.h:1219
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:394
iterator_range< user_iterator > users()
Definition Value.h:428
use_iterator use_begin()
Definition Value.h:366
bool use_empty() const
Definition Value.h:348
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
CallInst * Call
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
initializer< Ty > init(const Ty &Val)
LLVM_ABI bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
LLVM_ABI bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
ARCInstKind
Equivalence classes of instructions in the ARC Model.
LLVM_ABI ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
std::optional< Function * > getAttachedARCFunction(const CallBase *CB)
This function returns operand bundle clang_arc_attachedcall's argument, which is the address of the A...
Definition ObjCARCUtil.h:43
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI)
Lower CI as a loop.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
LLVM_ABI bool expandMemMoveAsLoop(MemMoveInst *MemMove, const TargetTransformInfo &TTI)
Expand MemMove as a loop.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
LLVM_ABI bool inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name, const TargetLibraryInfo &TLI)
Analyze the name and prototype of the given function and set any applicable attributes.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
LLVM_ABI ModulePass * createPreISelIntrinsicLoweringPass()
This pass lowers the @llvm.load.relative and @llvm.objc.
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
LLVM_ABI FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
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
LLVM_ABI MDNode * getExplicitlyUnknownBranchWeightsIfProfiled(Function &F, StringRef PassName)
Returns a metadata node containing unknown branch weights if the function has an entry count,...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI VPExpansionDetails expandVectorPredicationIntrinsic(VPIntrinsic &VPI, const TargetTransformInfo &TTI)
Expand a vector predication intrinsic.
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
Definition AutoUpgrade.h:34
DWARFExpression::Operation Op
LLVM_ABI void expandMemSetAsLoop(MemSetInst *MemSet, const TargetTransformInfo *TTI=nullptr)
Expand MemSet as a loop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI void expandMemSetPatternAsLoop(MemSetPatternInst *MemSet, const TargetTransformInfo *TTI=nullptr)
Expand MemSetPattern as a loop.
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI, ScalarEvolution *SE=nullptr)
Expand MemCpy as a loop. MemCpy is not deleted.
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
VPExpansionDetails
Represents the details the expansion of a VP intrinsic.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.