LLVM 23.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"
25#include "llvm/IR/Function.h"
26#include "llvm/IR/GlobalValue.h"
27#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/IR/Module.h"
34#include "llvm/IR/Type.h"
35#include "llvm/IR/Use.h"
37#include "llvm/Pass.h"
45
46using namespace llvm;
47
48#define DEBUG_TYPE "pre-isel-intrinsic-lowering"
49
50/// Threshold to leave statically sized memory intrinsic calls. Calls of known
51/// size larger than this will be expanded by the pass. Calls of unknown or
52/// lower size will be left for expansion in codegen.
54 "mem-intrinsic-expand-size",
55 cl::desc("Set minimum mem intrinsic size to expand in IR"), cl::init(-1),
57
58namespace {
59
60struct PreISelIntrinsicLowering {
61 const TargetMachine *TM;
62 const LibcallLoweringModuleAnalysisResult &ModuleLibcalls;
63 const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
64 const function_ref<TargetLibraryInfo &(Function &)> LookupTLI;
65
66 /// If this is true, assume it's preferably to leave memory intrinsic calls
67 /// for replacement with a library call later. Otherwise this depends on
68 /// TargetLoweringInfo availability of the corresponding function.
69 const bool UseMemIntrinsicLibFunc;
70
71 explicit PreISelIntrinsicLowering(
72 const TargetMachine *TM_,
73 const LibcallLoweringModuleAnalysisResult &ModuleLibcalls_,
76 bool UseMemIntrinsicLibFunc_ = true)
77 : TM(TM_), ModuleLibcalls(ModuleLibcalls_), LookupTTI(LookupTTI_),
78 LookupTLI(LookupTLI_), UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {
79 }
80
81 static bool shouldExpandMemIntrinsicWithSize(Value *Size,
82 const TargetTransformInfo &TTI);
83 bool
84 expandMemIntrinsicUses(Function &F,
85 DenseMap<Constant *, GlobalVariable *> &CMap) const;
86 bool lowerIntrinsics(Module &M) const;
87};
88
89} // namespace
90
91template <class T> static bool forEachCall(Function &Intrin, T Callback) {
92 // Lowering all intrinsics in a function will delete multiple uses, so we
93 // can't use an early-inc-range. In case some remain, we don't want to look
94 // at them again. Unfortunately, Value::UseList is private, so we can't use a
95 // simple Use**. If LastUse is null, the next use to consider is
96 // Intrin.use_begin(), otherwise it's LastUse->getNext().
97 Use *LastUse = nullptr;
98 bool Changed = false;
99 while (!Intrin.use_empty() && (!LastUse || LastUse->getNext())) {
100 Use *U = LastUse ? LastUse->getNext() : &*Intrin.use_begin();
101 bool Removed = false;
102 // An intrinsic cannot have its address taken, so it cannot be an argument
103 // operand. It might be used as operand in debug metadata, though.
104 if (auto CI = dyn_cast<CallInst>(U->getUser()))
105 Changed |= Removed = Callback(CI);
106 if (!Removed)
107 LastUse = U;
108 }
109 return Changed;
110}
111
113 if (F.use_empty())
114 return false;
115
116 bool Changed = false;
117 Type *Int32Ty = Type::getInt32Ty(F.getContext());
118
119 for (Use &U : llvm::make_early_inc_range(F.uses())) {
120 auto CI = dyn_cast<CallInst>(U.getUser());
121 if (!CI || CI->getCalledOperand() != &F)
122 continue;
123
124 IRBuilder<> B(CI);
125 Value *OffsetPtr =
126 B.CreatePtrAdd(CI->getArgOperand(0), CI->getArgOperand(1));
127 Value *OffsetI32 = B.CreateAlignedLoad(Int32Ty, OffsetPtr, Align(4));
128
129 Value *ResultPtr = B.CreatePtrAdd(CI->getArgOperand(0), OffsetI32);
130
131 CI->replaceAllUsesWith(ResultPtr);
132 CI->eraseFromParent();
133 Changed = true;
134 }
135
136 return Changed;
137}
138
139// ObjCARC has knowledge about whether an obj-c runtime function needs to be
140// always tail-called or never tail-called.
149
150static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
151 bool setNonLazyBind = false) {
153 "Pre-ISel intrinsics do lower into regular function calls");
154 if (F.use_empty())
155 return false;
156
157 // FIXME: When RuntimeLibcalls is an analysis, check if the function is really
158 // supported, and go through RTLIB::Libcall.
160
161 // If we haven't already looked up this function, check to see if the
162 // program already contains a function with this name.
163 Module *M = F.getParent();
164 FunctionCallee FCache =
165 M->getOrInsertFunction(NewFnName, F.getFunctionType());
166
167 if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
168 Fn->setLinkage(F.getLinkage());
169 if (setNonLazyBind && !Fn->isWeakForLinker()) {
170 // If we have Native ARC, set nonlazybind attribute for these APIs for
171 // performance.
172 Fn->addFnAttr(Attribute::NonLazyBind);
173 }
174 }
175
177
178 for (Use &U : llvm::make_early_inc_range(F.uses())) {
179 auto *CB = cast<CallBase>(U.getUser());
180
181 if (CB->getCalledFunction() != &F) {
183 "use expected to be the argument of operand bundle "
184 "\"clang.arc.attachedcall\"");
185 U.set(FCache.getCallee());
186 continue;
187 }
188
189 auto *CI = cast<CallInst>(CB);
190 assert(CI->getCalledFunction() && "Cannot lower an indirect call!");
191
192 IRBuilder<> Builder(CI->getParent(), CI->getIterator());
193 SmallVector<Value *, 8> Args(CI->args());
195 CI->getOperandBundlesAsDefs(BundleList);
196 CallInst *NewCI = Builder.CreateCall(FCache, Args, BundleList);
197 NewCI->setName(CI->getName());
198
199 // Try to set the most appropriate TailCallKind based on both the current
200 // attributes and the ones that we could get from ObjCARC's special
201 // knowledge of the runtime functions.
202 //
203 // std::max respects both requirements of notail and tail here:
204 // * notail on either the call or from ObjCARC becomes notail
205 // * tail on either side is stronger than none, but not notail
206 CallInst::TailCallKind TCK = CI->getTailCallKind();
207 NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
208
209 // Transfer the 'returned' attribute from the intrinsic to the call site.
210 // By applying this only to intrinsic call sites, we avoid applying it to
211 // non-ARC explicit calls to things like objc_retain which have not been
212 // auto-upgraded to use the intrinsics.
213 unsigned Index;
214 if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
215 Index)
216 NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
217 Attribute::Returned);
218
219 if (!CI->use_empty())
220 CI->replaceAllUsesWith(NewCI);
221 CI->eraseFromParent();
222 }
223
224 return true;
225}
226
227// TODO: Should refine based on estimated number of accesses (e.g. does it
228// require splitting based on alignment)
229bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize(
231 ConstantInt *CI = dyn_cast<ConstantInt>(Size);
232 if (!CI)
233 return true;
234 uint64_t Threshold = MemIntrinsicExpandSizeThresholdOpt.getNumOccurrences()
237 uint64_t SizeVal = CI->getZExtValue();
238
239 // Treat a threshold of 0 as a special case to force expansion of all
240 // intrinsics, including size 0.
241 return SizeVal > Threshold || Threshold == 0;
242}
243
244static bool
246 const TargetMachine *TM, Function *F, RTLIB::Libcall LC) {
247 // TODO: Should this consider the address space of the memcpy?
248 if (!TM)
249 return true;
251 ModuleLowering.getLibcallLowering(*TM->getSubtargetImpl(*F));
252 return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported;
253}
254
255static bool
257 const TargetMachine *TM, Function *F) {
258 // TODO: Should this consider the address space of the memcpy?
259 if (!TM)
260 return true;
262 ModuleLowering.getLibcallLowering(*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 const TargetLibraryInfo &TLI = LookupTLI(*Memset->getFunction());
414 Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
415 if (!PatternValue) {
416 // If it isn't possible to emit a memset_pattern16 libcall, expand to
417 // a loop instead.
419 Changed = true;
420 Memset->eraseFromParent();
421 break;
422 }
423 // FIXME: There is currently no profitability calculation for emitting
424 // the libcall vs expanding the memset.pattern directly.
425 IRBuilder<> Builder(Inst);
426 Module *M = Memset->getModule();
427 const DataLayout &DL = Memset->getDataLayout();
428
429 Type *DestPtrTy = Memset->getRawDest()->getType();
430 Type *SizeTTy = TLI.getSizeTType(*M);
431 StringRef FuncName = "memset_pattern16";
432 FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
433 Builder.getVoidTy(), DestPtrTy,
434 Builder.getPtrTy(), SizeTTy);
435 inferNonMandatoryLibFuncAttrs(M, FuncName, TLI);
436
437 // Otherwise we should form a memset_pattern16. PatternValue is known
438 // to be an constant array of 16-bytes. Put the value into a mergable
439 // global.
440 assert(Memset->getRawDest()->getType()->getPointerAddressSpace() == 0 &&
441 "Should have skipped if non-zero AS");
442 GlobalVariable *GV;
443 auto It = CMap.find(PatternValue);
444 if (It != CMap.end()) {
445 GV = It->second;
446 } else {
447 GV = new GlobalVariable(
448 *M, PatternValue->getType(), /*isConstant=*/true,
449 GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern");
450 GV->setUnnamedAddr(
451 GlobalValue::UnnamedAddr::Global); // Ok to merge these.
452 // TODO: Consider relaxing alignment requirement.
453 GV->setAlignment(Align(16));
454 CMap[PatternValue] = GV;
455 }
456 Value *PatternPtr = GV;
457 Value *NumBytes = Builder.CreateMul(
458 TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
459 *M),
460 Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
461 CallInst *MemsetPattern16Call =
462 Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
463 MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
464 // Preserve any call site attributes on the destination pointer
465 // argument (e.g. alignment).
466 AttrBuilder ArgAttrs(Memset->getContext(),
467 Memset->getAttributes().getParamAttrs(0));
468 MemsetPattern16Call->setAttributes(
469 MemsetPattern16Call->getAttributes().addParamAttributes(
470 Memset->getContext(), 0, ArgAttrs));
471 Changed = true;
472 Memset->eraseFromParent();
473 break;
474 }
475 default:
476 llvm_unreachable("unhandled intrinsic");
477 }
478 }
479
480 return Changed;
481}
482
484 Module &M = *Intr.getParent();
485
486 SmallPtrSet<GlobalValue *, 2> DSsToDeactivate;
487
488 Type *Int8Ty = Type::getInt8Ty(M.getContext());
489 Type *Int64Ty = Type::getInt64Ty(M.getContext());
490 PointerType *PtrTy = PointerType::get(M.getContext(), 0);
491
492 Function *SignIntr =
493 Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign, {});
494 Function *AuthIntr =
495 Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_auth, {});
496
497 auto *EmuFnTy = FunctionType::get(Int64Ty, {Int64Ty, Int64Ty}, false);
498
499 auto CreateSign = [&](IRBuilder<> &B, Value *Val, Value *Disc,
500 OperandBundleDef DSBundle) {
501 Function *F = B.GetInsertBlock()->getParent();
502 Attribute FSAttr = F->getFnAttribute("target-features");
503 if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
504 return B.CreateCall(
505 SignIntr, {Val, B.getInt32(/*AArch64PACKey::DA*/ 2), Disc}, DSBundle);
506 FunctionCallee EmuSignIntr =
507 M.getOrInsertFunction("__emupac_pacda", EmuFnTy);
508 return B.CreateCall(EmuSignIntr, {Val, Disc}, DSBundle);
509 };
510
511 auto CreateAuth = [&](IRBuilder<> &B, Value *Val, Value *Disc,
512 OperandBundleDef DSBundle) {
513 Function *F = B.GetInsertBlock()->getParent();
514 Attribute FSAttr = F->getFnAttribute("target-features");
515 if (FSAttr.isValid() && FSAttr.getValueAsString().contains("+pauth"))
516 return B.CreateCall(
517 AuthIntr, {Val, B.getInt32(/*AArch64PACKey::DA*/ 2), Disc}, DSBundle);
518 FunctionCallee EmuAuthIntr =
519 M.getOrInsertFunction("__emupac_autda", EmuFnTy);
520 return B.CreateCall(EmuAuthIntr, {Val, Disc}, DSBundle);
521 };
522
523 auto GetDeactivationSymbol = [&](CallInst *Call) -> GlobalValue * {
524 if (auto Bundle =
525 Call->getOperandBundle(LLVMContext::OB_deactivation_symbol))
526 return cast<GlobalValue>(Bundle->Inputs[0]);
527 return nullptr;
528 };
529
530 for (User *U : llvm::make_early_inc_range(Intr.users())) {
531 auto *Call = cast<CallInst>(U);
532
533 auto *Pointer = Call->getArgOperand(0);
534 auto *Disc = Call->getArgOperand(1);
535 bool UseHWEncoding =
536 cast<ConstantInt>(Call->getArgOperand(2))->getZExtValue();
537 if (!UseHWEncoding)
538 reportFatalUsageError("software encoding currently unsupported");
539
540 auto *DS = GetDeactivationSymbol(Call);
541 OperandBundleDef DSBundle("deactivation-symbol", DS);
542
543 for (Use &U : llvm::make_early_inc_range(Call->uses())) {
544 // Insert code to encode each pointer stored to the pointer returned by
545 // the intrinsic.
546 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
547 if (U.getOperandNo() == 1 &&
548 isa<PointerType>(SI->getValueOperand()->getType())) {
550 auto *SIValInt =
551 B.CreatePtrToInt(SI->getValueOperand(), B.getInt64Ty());
552 Value *Sign = CreateSign(B, SIValInt, Disc, DSBundle);
553 SI->setOperand(0, B.CreateIntToPtr(Sign, B.getPtrTy()));
554 SI->setOperand(1, Pointer);
555 continue;
556 }
557 }
558
559 // Insert code to decode each pointer loaded from the pointer returned by
560 // the intrinsic. This is the inverse of the encode operation implemented
561 // above.
562 if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
563 if (isa<PointerType>(LI->getType())) {
564 IRBuilder<> B(LI);
565 auto *NewLI = cast<LoadInst>(LI->clone());
566 NewLI->setOperand(0, Pointer);
567 B.Insert(NewLI);
568 auto *LIInt = B.CreatePtrToInt(NewLI, B.getInt64Ty());
569 Value *Auth = CreateAuth(B, LIInt, Disc, DSBundle);
570 LI->replaceAllUsesWith(B.CreateIntToPtr(Auth, B.getPtrTy()));
571 LI->eraseFromParent();
572 continue;
573 }
574 }
575 // Comparisons against null cannot be used to recover the original
576 // pointer so we replace them with comparisons against the original
577 // pointer.
578 if (auto *CI = dyn_cast<ICmpInst>(U.getUser())) {
579 if (auto *Op = dyn_cast<Constant>(CI->getOperand(0))) {
580 if (Op->isNullValue()) {
581 CI->setOperand(1, Pointer);
582 continue;
583 }
584 }
585 if (auto *Op = dyn_cast<Constant>(CI->getOperand(1))) {
586 if (Op->isNullValue()) {
587 CI->setOperand(0, Pointer);
588 continue;
589 }
590 }
591 }
592
593 // We couldn't rewrite away this use of the intrinsic. Replace it with the
594 // pointer operand, and arrange to define a deactivation symbol.
595 U.set(Pointer);
596 if (DS)
597 DSsToDeactivate.insert(DS);
598 }
599
600 Call->eraseFromParent();
601 }
602
603 if (!DSsToDeactivate.empty()) {
604 // This is an AArch64 NOP instruction. When the deactivation symbol support
605 // is expanded to more architectures, there will likely need to be an API
606 // for retrieving this constant.
607 Constant *Nop =
608 ConstantExpr::getIntToPtr(ConstantInt::get(Int64Ty, 0xd503201f), PtrTy);
609 for (GlobalValue *OldDS : DSsToDeactivate) {
611 Int8Ty, 0, GlobalValue::ExternalLinkage, OldDS->getName(), Nop, &M);
612 DS->setVisibility(GlobalValue::HiddenVisibility);
613 DS->takeName(OldDS);
614 OldDS->replaceAllUsesWith(DS);
615 OldDS->eraseFromParent();
616 }
617 }
618 return true;
619}
620
621static bool expandCondLoop(Function &Intr) {
622 for (User *U : llvm::make_early_inc_range(Intr.users())) {
623 auto *Call = cast<CallInst>(U);
624
625 auto *Br = cast<BranchInst>(
626 SplitBlockAndInsertIfThen(Call->getArgOperand(0), Call, false,
628 *Call->getFunction(), DEBUG_TYPE)));
629 Br->setSuccessor(0, Br->getParent());
630 Call->eraseFromParent();
631 }
632 return true;
633}
634
635static bool expandLoopTrap(Function &Intr) {
636 for (User *U : make_early_inc_range(Intr.users())) {
637 auto *Call = cast<CallInst>(U);
638 if (!Call->getParent()->isEntryBlock() &&
639 std::all_of(Call->getParent()->begin(), BasicBlock::iterator(Call),
640 [](Instruction &I) { return !I.mayHaveSideEffects(); })) {
641 for (auto *BB : predecessors(Call->getParent())) {
642 auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
643 if (!BI || BI->isUnconditional())
644 continue;
645 IRBuilder<> B(BI);
646 Value *Cond;
647 // The looptrap can either be on the true branch or the false branch.
648 // We insert the cond loop before the branch, which uses the branch's
649 // original condition for going to the looptrap as its condition, and
650 // force the branch to take whichever path does not lead to the
651 // looptrap, as the original path to the looptrap is now unreachable
652 // thanks to the cond loop. The codegenprepare pass will clean up our
653 // "unconditional conditional branch" by combining the two basic blocks
654 // if possible, or replacing it with an unconditional branch.
655 if (BI->getSuccessor(0) == Call->getParent()) {
656 // The looptrap is on the true branch.
657 Cond = BI->getCondition();
658 BI->setCondition(ConstantInt::getFalse(BI->getContext()));
659 } else {
660 // The looptrap is on the false branch, which means that we need to
661 // invert the condition.
662 Cond = B.CreateNot(BI->getCondition());
663 BI->setCondition(ConstantInt::getTrue(BI->getContext()));
664 }
665 B.CreateIntrinsic(Intrinsic::cond_loop, Cond);
666 }
667 }
669 B.CreateIntrinsic(Intrinsic::cond_loop,
670 ConstantInt::getTrue(Call->getContext()));
671 Call->eraseFromParent();
672 }
673 return true;
674}
675
676bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
677 // Map unique constants to globals.
678 DenseMap<Constant *, GlobalVariable *> CMap;
679 bool Changed = false;
680 for (Function &F : M) {
681 switch (F.getIntrinsicID()) {
682 default:
683 break;
684 case Intrinsic::memcpy:
685 case Intrinsic::memcpy_inline:
686 case Intrinsic::memmove:
687 case Intrinsic::memset:
688 case Intrinsic::memset_inline:
689 case Intrinsic::experimental_memset_pattern:
690 Changed |= expandMemIntrinsicUses(F, CMap);
691 break;
692 case Intrinsic::load_relative:
694 break;
695 case Intrinsic::is_constant:
696 case Intrinsic::objectsize:
697 Changed |= forEachCall(F, [&](CallInst *CI) {
698 Function *Parent = CI->getParent()->getParent();
699 TargetLibraryInfo &TLI = LookupTLI(*Parent);
700 // Intrinsics in unreachable code are not lowered.
701 bool Changed = lowerConstantIntrinsics(*Parent, TLI, /*DT=*/nullptr);
702 return Changed;
703 });
704 break;
705#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
706 case Intrinsic::VPID:
707#include "llvm/IR/VPIntrinsics.def"
708 forEachCall(F, [&](CallInst *CI) {
709 Function *Parent = CI->getParent()->getParent();
710 const TargetTransformInfo &TTI = LookupTTI(*Parent);
711 auto *VPI = cast<VPIntrinsic>(CI);
713 // Expansion of VP intrinsics may change the IR but not actually
714 // replace the intrinsic, so update Changed for the pass
715 // and compute Removed for forEachCall.
716 Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
717 bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
718 return Removed;
719 });
720 break;
721 case Intrinsic::objc_autorelease:
722 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autorelease);
723 break;
724 case Intrinsic::objc_autoreleasePoolPop:
725 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPop);
726 break;
727 case Intrinsic::objc_autoreleasePoolPush:
728 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleasePoolPush);
729 break;
730 case Intrinsic::objc_autoreleaseReturnValue:
731 Changed |= lowerObjCCall(F, RTLIB::impl_objc_autoreleaseReturnValue);
732 break;
733 case Intrinsic::objc_copyWeak:
734 Changed |= lowerObjCCall(F, RTLIB::impl_objc_copyWeak);
735 break;
736 case Intrinsic::objc_destroyWeak:
737 Changed |= lowerObjCCall(F, RTLIB::impl_objc_destroyWeak);
738 break;
739 case Intrinsic::objc_initWeak:
740 Changed |= lowerObjCCall(F, RTLIB::impl_objc_initWeak);
741 break;
742 case Intrinsic::objc_loadWeak:
743 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeak);
744 break;
745 case Intrinsic::objc_loadWeakRetained:
746 Changed |= lowerObjCCall(F, RTLIB::impl_objc_loadWeakRetained);
747 break;
748 case Intrinsic::objc_moveWeak:
749 Changed |= lowerObjCCall(F, RTLIB::impl_objc_moveWeak);
750 break;
751 case Intrinsic::objc_release:
752 Changed |= lowerObjCCall(F, RTLIB::impl_objc_release, true);
753 break;
754 case Intrinsic::objc_retain:
755 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain, true);
756 break;
757 case Intrinsic::objc_retainAutorelease:
758 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainAutorelease);
759 break;
760 case Intrinsic::objc_retainAutoreleaseReturnValue:
761 Changed |=
762 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleaseReturnValue);
763 break;
764 case Intrinsic::objc_retainAutoreleasedReturnValue:
765 Changed |=
766 lowerObjCCall(F, RTLIB::impl_objc_retainAutoreleasedReturnValue);
767 break;
768 case Intrinsic::objc_claimAutoreleasedReturnValue:
769 Changed |=
770 lowerObjCCall(F, RTLIB::impl_objc_claimAutoreleasedReturnValue);
771 break;
772 case Intrinsic::objc_retainBlock:
773 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainBlock);
774 break;
775 case Intrinsic::objc_storeStrong:
776 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeStrong);
777 break;
778 case Intrinsic::objc_storeWeak:
779 Changed |= lowerObjCCall(F, RTLIB::impl_objc_storeWeak);
780 break;
781 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
782 Changed |=
783 lowerObjCCall(F, RTLIB::impl_objc_unsafeClaimAutoreleasedReturnValue);
784 break;
785 case Intrinsic::objc_retainedObject:
786 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retainedObject);
787 break;
788 case Intrinsic::objc_unretainedObject:
789 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedObject);
790 break;
791 case Intrinsic::objc_unretainedPointer:
792 Changed |= lowerObjCCall(F, RTLIB::impl_objc_unretainedPointer);
793 break;
794 case Intrinsic::objc_retain_autorelease:
795 Changed |= lowerObjCCall(F, RTLIB::impl_objc_retain_autorelease);
796 break;
797 case Intrinsic::objc_sync_enter:
798 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_enter);
799 break;
800 case Intrinsic::objc_sync_exit:
801 Changed |= lowerObjCCall(F, RTLIB::impl_objc_sync_exit);
802 break;
803 case Intrinsic::exp:
804 case Intrinsic::exp2:
805 case Intrinsic::log:
806 Changed |= forEachCall(F, [&](CallInst *CI) {
807 Type *Ty = CI->getArgOperand(0)->getType();
808 if (!TM || !isa<ScalableVectorType>(Ty))
809 return false;
810 const TargetLowering *TL = TM->getSubtargetImpl(F)->getTargetLowering();
811 unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
812 assert(Op != ISD::DELETED_NODE && "unsupported intrinsic");
813 if (!TL->isOperationExpand(Op, EVT::getEVT(Ty)))
814 return false;
816 });
817 break;
818 case Intrinsic::protected_field_ptr:
820 break;
821 case Intrinsic::cond_loop:
822 if (!TM->canLowerCondLoop())
824 break;
825 case Intrinsic::looptrap:
827 if (!TM->canLowerCondLoop())
828 if (auto *CondLoop = M.getFunction("llvm.cond.loop"))
829 Changed |= expandCondLoop(*CondLoop);
830 break;
831 }
832 }
833 return Changed;
834}
835
836namespace {
837
838class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
839public:
840 static char ID;
841
842 PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
843
844 void getAnalysisUsage(AnalysisUsage &AU) const override {
845 AU.addRequired<TargetTransformInfoWrapperPass>();
846 AU.addRequired<TargetLibraryInfoWrapperPass>();
847 AU.addRequired<LibcallLoweringInfoWrapper>();
848 AU.addRequired<TargetPassConfig>();
849 }
850
851 bool runOnModule(Module &M) override {
852 const LibcallLoweringModuleAnalysisResult &ModuleLibcalls =
853 getAnalysis<LibcallLoweringInfoWrapper>().getResult(M);
854
855 auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
856 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
857 };
858 auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
859 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
860 };
861
862 const auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
863 PreISelIntrinsicLowering Lowering(TM, ModuleLibcalls, LookupTTI, LookupTLI);
864 return Lowering.lowerIntrinsics(M);
865 }
866};
867
868} // end anonymous namespace
869
870char PreISelIntrinsicLoweringLegacyPass::ID;
871
872INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
873 "pre-isel-intrinsic-lowering",
874 "Pre-ISel Intrinsic Lowering", false, false)
880INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
881 "pre-isel-intrinsic-lowering",
882 "Pre-ISel Intrinsic Lowering", false, false)
883
885 return new PreISelIntrinsicLoweringLegacyPass();
886}
887
890 const LibcallLoweringModuleAnalysisResult &LibcallLowering =
892
893 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
894
895 auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
896 return FAM.getResult<TargetIRAnalysis>(F);
897 };
898 auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
899 return FAM.getResult<TargetLibraryAnalysis>(F);
900 };
901
902 PreISelIntrinsicLowering Lowering(TM, LibcallLowering, LookupTTI, LookupTLI);
903 if (!Lowering.lowerIntrinsics(M))
904 return PreservedAnalyses::all();
905 else
907}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool setNonLazyBind(Function &F)
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 forEachCall(Function &Intrin, T Callback)
static bool expandLoopTrap(Function &Intr)
static bool expandCondLoop(Function &Intr)
pre isel intrinsic Pre ISel Intrinsic Lowering
static bool canEmitLibcall(const LibcallLoweringModuleAnalysisResult &ModuleLowering, const TargetMachine *TM, Function *F, RTLIB::Libcall LC)
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static bool canEmitMemcpy(const LibcallLoweringModuleAnalysisResult &ModuleLowering, const TargetMachine *TM, Function *F)
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:105
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:261
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:178
iterator end()
Definition DenseMap.h:81
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.
const Function & getFunction() const
Definition Function.h:166
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:613
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:2787
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.
Record a mapping from subtarget to LibcallLoweringInfo.
const LibcallLoweringInfo & getLibcallLowering(const TargetSubtargetInfo &Subtarget) const
Value * getRawDest() const
Value * getValue() const
This class wraps the llvm.experimental.memset.pattern intrinsic.
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 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
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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...
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.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
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:294
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:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:397
iterator_range< user_iterator > users()
Definition Value.h:426
use_iterator use_begin()
Definition Value.h:364
bool use_empty() const
Definition Value.h:346
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.
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
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
initializer< Ty > init(const Ty &Val)
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
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.
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.
Definition Types.h:26
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
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
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:296
bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
LLVM_ABI void expandMemSetPatternAsLoop(MemSetPatternInst *MemSet)
Expand MemSetPattern as a loop. MemSet is not deleted.
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:634
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:284
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.
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 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,...
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
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.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.