52#define DEBUG_TYPE "coro-frame"
55class FrameTypeBuilder;
67 : Spills(Spills), Allocas(Allocas) {}
71 for (
const auto &
P : Spills)
73 for (
const auto &
A : Allocas)
79 auto Itr = FieldIndexMap.find(V);
80 assert(Itr != FieldIndexMap.end() &&
81 "Value does not have a frame field index");
86 assert(FieldIndexMap.count(V) == 0 &&
87 "Cannot set the index for the same field twice.");
88 FieldIndexMap[V] = Index;
92 auto Iter = FieldAlignMap.find(V);
93 assert(Iter != FieldAlignMap.end());
98 assert(FieldAlignMap.count(V) == 0);
99 FieldAlignMap.insert({V, AL});
103 auto Iter = FieldDynamicAlignMap.find(V);
104 assert(Iter != FieldDynamicAlignMap.end());
109 assert(FieldDynamicAlignMap.count(V) == 0);
110 FieldDynamicAlignMap.insert({V,
Align});
114 auto Iter = FieldOffsetMap.find(V);
115 assert(Iter != FieldOffsetMap.end());
120 assert(FieldOffsetMap.count(V) == 0);
121 FieldOffsetMap.insert({V,
Offset});
125 void updateLayoutInfo(FrameTypeBuilder &
B);
142 dbgs() <<
"------------- " << Title <<
" --------------\n";
143 for (
const auto &
E : Spills) {
146 for (
auto *
I :
E.second)
152 dbgs() <<
"------------- Allocas --------------\n";
153 for (
const auto &
A : Allocas) {
160using FieldIDType =
size_t;
165class FrameTypeBuilder {
171 uint64_t DynamicAlignBuffer;
174 const DataLayout &DL;
175 uint64_t StructSize = 0;
177 bool IsFinished =
false;
179 std::optional<Align> MaxFrameAlignment;
182 DenseMap<Value*, unsigned> FieldIndexByKey;
185 FrameTypeBuilder(
const DataLayout &DL, std::optional<Align> MaxFrameAlignment)
186 : DL(DL), MaxFrameAlignment(MaxFrameAlignment) {}
190 [[nodiscard]] FieldIDType addFieldForAlloca(AllocaInst *AI,
191 bool IsHeader =
false) {
195 "Coroutines cannot handle non static or vscale allocas yet");
196 return addField(
Size->getFixedValue(), AI->
getAlign(), IsHeader);
226 void addFieldForAllocas(
const Function &
F, FrameDataInfo &FrameData,
227 coro::Shape &Shape,
bool OptimizeFrame);
230 [[nodiscard]] FieldIDType addField(
Type *Ty, MaybeAlign MaybeFieldAlignment,
231 bool IsHeader =
false,
232 bool IsSpillOfValue =
false) {
233 assert(Ty &&
"must provide a type for a field");
235 uint64_t FieldSize = DL.getTypeAllocSize(Ty);
239 Align ABIAlign = DL.getABITypeAlign(Ty);
240 Align TyAlignment = ABIAlign;
241 if (IsSpillOfValue && MaxFrameAlignment && *MaxFrameAlignment < ABIAlign)
242 TyAlignment = *MaxFrameAlignment;
243 Align FieldAlignment = MaybeFieldAlignment.value_or(TyAlignment);
244 return addField(FieldSize, FieldAlignment, IsHeader);
248 [[nodiscard]] FieldIDType addField(uint64_t FieldSize, Align FieldAlignment,
249 bool IsHeader =
false) {
250 assert(!IsFinished &&
"adding fields to a finished builder");
260 uint64_t DynamicAlignBuffer = 0;
261 if (MaxFrameAlignment && (FieldAlignment > *MaxFrameAlignment)) {
264 FieldAlignment = *MaxFrameAlignment;
265 FieldSize = FieldSize + DynamicAlignBuffer;
272 StructSize =
Offset + FieldSize;
279 Fields.push_back({FieldSize,
Offset, FieldAlignment, DynamicAlignBuffer});
280 return Fields.size() - 1;
286 uint64_t getStructSize()
const {
287 assert(IsFinished &&
"not yet finished!");
291 Align getStructAlign()
const {
292 assert(IsFinished &&
"not yet finished!");
296 Field getLayoutField(FieldIDType Id)
const {
297 assert(IsFinished &&
"not yet finished!");
303void FrameDataInfo::updateLayoutInfo(FrameTypeBuilder &
B) {
304 auto Updater = [&](
Value *
I) {
305 uint32_t FieldIndex = getFieldIndex(
I);
306 auto Field =
B.getLayoutField(FieldIndex);
308 uint64_t dynamicAlign =
309 Field.DynamicAlignBuffer
312 setDynamicAlign(
I, dynamicAlign);
315 for (
auto &S : Spills)
317 for (
const auto &
A : Allocas)
321void FrameTypeBuilder::addFieldForAllocas(
const Function &
F,
322 FrameDataInfo &FrameData,
324 bool OptimizeFrame) {
330 for (
auto AllocaList : NonOverlapedAllocas) {
331 auto *LargestAI = *AllocaList.begin();
332 FieldIDType
Id = addFieldForAlloca(LargestAI);
333 for (
auto *Alloca : AllocaList)
338 if (!OptimizeFrame) {
340 AllocaInst *Alloca =
A.Alloca;
341 NonOverlapedAllocas.emplace_back(AllocaSetType(1, Alloca));
358 DenseMap<SwitchInst *, BasicBlock *> DefaultSuspendDest;
360 for (
auto *U : CoroSuspendInst->users()) {
362 auto *SWI =
const_cast<SwitchInst *
>(ConstSWI);
363 DefaultSuspendDest[SWI] = SWI->getDefaultDest();
364 SWI->setDefaultDest(SWI->getSuccessor(1));
369 auto ExtractAllocas = [&]() {
370 AllocaSetType Allocas;
371 Allocas.reserve(
FrameData.Allocas.size());
373 Allocas.push_back(
A.Alloca);
376 StackLifetime StackLifetimeAnalyzer(
F, ExtractAllocas(),
377 StackLifetime::LivenessType::May);
378 StackLifetimeAnalyzer.run();
379 auto DoAllocasInterfere = [&](
const AllocaInst *AI1,
const AllocaInst *AI2) {
380 return StackLifetimeAnalyzer.getLiveRange(AI1).overlaps(
381 StackLifetimeAnalyzer.getLiveRange(AI2));
383 auto GetAllocaSize = [&](
const coro::AllocaInfo &
A) {
384 std::optional<TypeSize> RetSize =
A.Alloca->getAllocationSize(
DL);
385 assert(RetSize &&
"Variable Length Arrays (VLA) are not supported.\n");
386 assert(!RetSize->isScalable() &&
"Scalable vectors are not yet supported");
387 return RetSize->getFixedValue();
393 sort(
FrameData.Allocas, [&](
const auto &Iter1,
const auto &Iter2) {
394 return GetAllocaSize(Iter1) > GetAllocaSize(Iter2);
397 AllocaInst *Alloca =
A.Alloca;
402 for (
auto &AllocaSet : NonOverlapedAllocas) {
403 assert(!AllocaSet.empty() &&
"Processing Alloca Set is not empty.\n");
404 bool NoInterference =
none_of(AllocaSet, [&](
auto Iter) {
405 return DoAllocasInterfere(Alloca, Iter);
413 bool Alignable = [&]() ->
bool {
414 auto *LargestAlloca = *AllocaSet.begin();
415 return LargestAlloca->getAlign().value() % Alloca->
getAlign().
value() ==
418 bool CouldMerge = NoInterference && Alignable;
421 AllocaSet.push_back(Alloca);
426 NonOverlapedAllocas.emplace_back(AllocaSetType(1, Alloca));
431 for (
auto SwitchAndDefaultDest : DefaultSuspendDest) {
432 SwitchInst *SWI = SwitchAndDefaultDest.first;
433 BasicBlock *DestBB = SwitchAndDefaultDest.second;
438 : NonOverlapedAllocas) {
439 if (AllocaSet.size() > 1) {
440 dbgs() <<
"In Function:" <<
F.getName() <<
"\n";
441 dbgs() <<
"Find Union Set "
443 dbgs() <<
"\tAllocas are \n";
444 for (
auto Alloca : AllocaSet)
445 dbgs() <<
"\t\t" << *Alloca <<
"\n";
450void FrameTypeBuilder::finish() {
451 assert(!IsFinished &&
"already finished!");
457 for (
auto &
Field : Fields) {
464 StructSize = SizeAndAlign.first;
465 StructAlign = SizeAndAlign.second;
467 auto getField = [](
const OptimizedStructLayoutField &LayoutField) ->
Field & {
468 return *
static_cast<Field *
>(
const_cast<void*
>(LayoutField.Id));
472 for (
auto &LayoutField : LayoutFields) {
473 auto &
F = getField(LayoutField);
474 F.Offset = LayoutField.Offset;
482 for (
auto *V : FrameData.getAllDefs()) {
486 auto CacheIt = [&DIVarCache, V](
const auto &Container) {
488 return DDI->getExpression()->getNumElements() == 0;
490 if (
I != Container.end())
491 DIVarCache.
insert({V, (*I)->getVariable()});
501 if (Ty->isIntegerTy()) {
507 return MDName->getString();
510 if (Ty->isFloatingPointTy()) {
513 if (Ty->isDoubleTy())
515 return "__floating_type_";
518 if (Ty->isPointerTy())
519 return "PointerType";
521 if (Ty->isStructTy()) {
523 return "__LiteralStructType_";
525 auto Name = Ty->getStructName();
528 for (
auto &Iter : Buffer)
529 if (Iter ==
'.' || Iter ==
':')
532 return MDName->getString();
535 return "UnknownType";
547 DIType *RetType =
nullptr;
549 if (Ty->isIntegerTy()) {
551 RetType = Builder.createBasicType(Name,
BitWidth, dwarf::DW_ATE_signed,
552 llvm::DINode::FlagArtificial);
553 }
else if (Ty->isFloatingPointTy()) {
556 llvm::DINode::FlagArtificial);
557 }
else if (Ty->isPointerTy()) {
569 }
else if (Ty->isStructTy()) {
570 auto *DIStruct = Builder.createStructType(
573 llvm::DINode::FlagArtificial,
nullptr, llvm::DINodeArray());
577 for (
unsigned I = 0;
I < StructTy->getNumElements();
I++) {
579 DIStruct, LineNum, DITypeCache);
581 Elements.push_back(Builder.createMemberType(
582 DIStruct, DITy->
getName(), DIStruct->getFile(), LineNum,
585 llvm::DINode::FlagArtificial, DITy));
588 Builder.replaceArrays(DIStruct, Builder.getOrCreateArray(Elements));
594 auto *CharSizeType = Builder.createBasicType(
595 Name, 8, dwarf::DW_ATE_unsigned_char, llvm::DINode::FlagArtificial);
598 RetType = CharSizeType;
603 RetType = Builder.createArrayType(
605 Builder.getOrCreateArray(Builder.getOrCreateSubrange(0,
Size / 8)));
609 DITypeCache.
insert({Ty, RetType});
626 FrameDataInfo &FrameData) {
631 if (!DIS || !DIS->getUnit())
635 DIS->getUnit()->getSourceLanguage().getUnversionedName())) ||
636 DIS->getUnit()->getEmissionKind() !=
641 "We could only build debug infomation for C++ coroutine now.\n");
646 unsigned LineNum = DIS->getLine();
649 DIS->getUnit(),
Twine(
F.getName() +
".coro_frame_ty").
str(), DFile,
651 llvm::DINode::FlagArtificial,
nullptr, llvm::DINodeArray());
662 unsigned UnknownTypeNum = 0;
668 FrameDITy, Name, DFile, LineNum, SizeInBits, Alignment,
Offset * 8,
669 llvm::DINode::FlagArtificial, DITy));
672 auto addDIDef = [&](
Value *V) {
675 Align Alignment = FrameData.getAlign(V);
681 auto It = DIVarCache.
find(V);
682 if (It != DIVarCache.
end()) {
684 Name = It->second->getName().str();
685 DITy = It->second->getType();
690 LineNum, DITypeCache);
693 DITy =
solveDIType(DBuilder, V->getType(), Layout, FrameDITy, LineNum,
696 assert(DITy &&
"SolveDIType shouldn't return nullptr.\n");
698 Name +=
"_" + std::to_string(UnknownTypeNum);
706 "unreachable due to addFieldForAlloca checks");
707 SizeInBits =
Size->getFixedValue() * 8;
713 addElement(Name, SizeInBits, Alignment.
value() * 8,
Offset, DITy);
723 FnPtrTy->getAddressSpace());
724 addElement(
"__resume_fn", PtrSize, PtrAlign, 0, DIPtr);
725 addElement(
"__destroy_fn", PtrSize, PtrAlign,
732 (IndexSize < 8) ? 8 : IndexSize,
733 dwarf::DW_ATE_unsigned_char));
735 auto Defs = FrameData.getAllDefs();
743 FrameDITy,
true, DINode::FlagArtificial);
752 DIS->retainNodes(&FrameDIVar, &FrameDIVar + 1);
758 assert(FrameDIVar->isValidLocationForIntrinsic(DILoc));
765 It->getParent()->insertDbgRecordBefore(NewDVR, It);
773 auto *Inst = dyn_cast<Instruction>(U.getUser());
774 if (!Inst || DT.dominates(Shape.CoroBegin, Inst))
777 if (auto *CI = dyn_cast<CallInst>(Inst)) {
782 if (CI->onlyReadsMemory() || CI->onlyReadsMemory(CI->getArgOperandNo(&U)))
807 bool OptimizeFrame) {
811 std::optional<Align> MaxFrameAlignment;
814 FrameTypeBuilder
B(
DL, MaxFrameAlignment);
817 std::optional<FieldIDType> SwitchIndexFieldId;
832 FrameData.setFieldIndex(
833 PromiseAlloca,
B.addFieldForAlloca(PromiseAlloca,
true));
840 SwitchIndexFieldId =
B.addField(SwitchIndexType,
MaybeAlign());
842 assert(PromiseAlloca ==
nullptr &&
"lowering doesn't support promises");
847 B.addFieldForAllocas(
F, FrameData, Shape, OptimizeFrame);
854 FrameData.Allocas.emplace_back(
859 for (
auto &S : FrameData.Spills) {
860 Type *FieldType = S.first->getType();
865 if (
A->hasByValAttr()) {
866 FieldType =
A->getParamByValType();
867 MA =
A->getParamAlign();
871 B.addField(FieldType, MA,
false ,
true );
872 FrameData.setFieldIndex(S.first, Id);
877 FrameData.updateLayoutInfo(
B);
888 auto IndexField =
B.getLayoutField(*SwitchIndexFieldId);
904 = (
B.getStructSize() <= Id->getStorageSize() &&
905 B.getStructAlign() <= Id->getStorageAlignment());
918 "The alignment requirment of frame variables cannot be higher than "
919 "the alignment of the async function context");
931 Arg->getParent()->removeParamAttr(Arg->getArgNo(), Attribute::Captures);
933 if (Arg->hasByValAttr())
934 return Arg->getParamByValType();
942 const FrameDataInfo &FrameData) {
949 G = Builder.CreateInBoundsPtrAdd(
G, OffsetVal,
950 Def->getName() +
Twine(
".spill.addr"));
952 auto SpillAlignment =
Align(FrameData.getAlign(Def));
956 auto &
DL = Builder.GetInsertBlock()->getDataLayout();
957 auto Size =
DL.getTypeStoreSize(ByValTy);
959 Builder.CreateMemCpy(
G, SpillAlignment, Def, SpillAlignment,
Size);
961 Builder.CreateAlignedStore(Def,
G, SpillAlignment);
973 Value *Ptr = Builder.CreateInBoundsPtrAdd(Shape.
FramePtr, OffsetVal);
976 if (FrameData.getDynamicAlign(Orig) != 0) {
980 auto *PtrValue = Builder.CreatePtrToInt(Ptr,
IntPtrTy);
982 PtrValue = Builder.CreateAdd(PtrValue, AlignMask);
983 PtrValue = Builder.CreateAnd(PtrValue, Builder.CreateNot(AlignMask));
984 return Builder.CreateIntToPtr(PtrValue, AI->
getType());
991 Ptr = Builder.CreateAddrSpaceCast(Ptr, Orig->
getType(),
999template <DbgVariableRecord::LocationType record_type>
1000static TinyPtrVector<DbgVariableRecord *>
1004 constexpr auto FindFunc =
1011 if (!
F.getSubprogram())
1014 Value *CurDef = Def;
1017 if (!LdInst->getType()->isPointerTy())
1019 CurDef = LdInst->getPointerOperand();
1022 Records = FindFunc(CurDef);
1035 Value *
Size = Builder.CreateAllocationSize(Builder.getInt64Ty(), Alloca);
1037 Builder.CreateMemCpy(
G, FrameData.getAlign(Alloca), Alloca,
1074 MDNode *TBAATag =
nullptr;
1080 (
F->getName() +
".Frame Slot").str(), TBAARoot);
1083 for (
auto const &
E : FrameData.Spills) {
1091 Value *CurrentReload =
nullptr;
1092 for (
auto *U :
E.second) {
1098 Builder.SetInsertPoint(CurrentBlock,
1102 GEP->setName(
E.first->getName() +
Twine(
".reload.addr"));
1104 CurrentReload =
GEP;
1106 auto SpillAlignment =
Align(FrameData.getAlign(Def));
1108 Builder.CreateAlignedLoad(
E.first->getType(),
GEP, SpillAlignment,
1109 E.first->getName() +
Twine(
".reload"));
1111 LI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
1124 DDI->getExpression(), DDI->getDebugLoc(),
1126 Builder.GetInsertPoint()->getParent()->insertDbgRecordBefore(
1127 NewDVR, Builder.GetInsertPoint());
1139 auto SalvageOneCoro = [&](
auto *DDI) {
1146 Type *Ty = VAM->getValue()->getType();
1150 DDI->getExpression(), DDI->getDebugLoc(),
1153 Builder.GetInsertPoint()->getParent()->insertDbgRecordBefore(
1154 NewDVR, Builder.GetInsertPoint());
1159 for_each(DVRDeclareValues, SalvageOneCoro);
1165 assert(PN->getNumIncomingValues() == 1 &&
1166 "unexpected number of incoming "
1167 "values in the PHINode");
1168 PN->replaceAllUsesWith(CurrentReload);
1169 PN->eraseFromParent();
1175 U->replaceUsesOfWith(Def, CurrentReload);
1179 DVR.replaceVariableLocationOp(Def, CurrentReload,
true);
1194 Builder.SetInsertPoint(SpillBlock, SpillBlock->begin());
1195 for (
const auto &
P : FrameData.Allocas) {
1202 if (
I->isLifetimeStartOrEnd())
1203 I->eraseFromParent();
1208 G->takeName(Alloca);
1223 for (
const auto &
A : FrameData.Allocas) {
1225 UsersToUpdate.
clear();
1231 if (
I->isLifetimeStartOrEnd())
1232 I->eraseFromParent();
1237 if (UsersToUpdate.
empty())
1244 for (
auto *DVR : DbgVariableRecords)
1245 DVR->replaceVariableLocationOp(Alloca,
G);
1248 I->replaceUsesOfWith(Alloca,
G);
1254 for (
const auto &
A : FrameData.Allocas) {
1256 if (
A.MayWriteBeforeCoroBegin) {
1263 for (
const auto &Alias :
A.Aliases) {
1266 auto &
Value = *Alias.second;
1269 Builder.CreateInBoundsPtrAdd(
FramePtr, ConstantInt::get(ITy,
Value));
1270 Alias.first->replaceUsesWithIf(
1281 PHINode *UntilPHI =
nullptr) {
1284 int Index = PN->getBasicBlockIndex(InsertedBB);
1285 Value *V = PN->getIncomingValue(Index);
1287 V->getType(), 1, V->getName() +
Twine(
".") + SuccBB->
getName());
1290 PN->setIncomingValue(Index, InputV);
1292 }
while (PN != UntilPHI);
1329 Builder.CreateUnreachable();
1332 auto *NewCleanupPadBB =
1335 CleanupPadBB->
getParent(), CleanupPadBB);
1336 Builder.SetInsertPoint(NewCleanupPadBB);
1337 auto *SwitchType = Builder.getInt8Ty();
1338 auto *SetDispatchValuePN =
1339 Builder.CreatePHI(SwitchType,
pred_size(CleanupPadBB));
1341 CleanupPad->
insertAfter(SetDispatchValuePN->getIterator());
1342 auto *SwitchOnDispatch = Builder.CreateSwitch(SetDispatchValuePN, UnreachBB,
1345 int SwitchIndex = 0;
1351 Twine(
".from.") + Pred->getName(),
1352 CleanupPadBB->
getParent(), CleanupPadBB);
1354 CaseBB->setName(CleanupPadBB->
getName() +
Twine(
".from.") +
1356 Builder.SetInsertPoint(CaseBB);
1357 Builder.CreateBr(CleanupPadBB);
1364 auto *SwitchConstant = ConstantInt::get(SwitchType, SwitchIndex);
1365 SetDispatchValuePN->addIncoming(SwitchConstant, Pred);
1366 SwitchOnDispatch->addCase(SwitchConstant, CaseBB);
1377 for (
int i = 0; i < SwitchIndex; ++i) {
1380 SwitchOnDispatch->setMetadata(LLVMContext::MD_prof,
1387 for (
auto &BB :
F) {
1388 for (
auto &Phi : BB.phis()) {
1389 if (Phi.getNumIncomingValues() == 1) {
1395 while (!Worklist.
empty()) {
1397 auto *OriginalValue = Phi->getIncomingValue(0);
1398 Phi->replaceAllUsesWith(OriginalValue);
1427 if (
auto *CleanupPad =
1435 assert(
CS->getUnwindDest() == &BB);
1464 IncomingBB->setName(BB.
getName() +
Twine(
".from.") + Pred->getName());
1483 if (PN->getNumIncomingValues() > 1)
1493 auto *BB =
I->getParent();
1494 if (&BB->front() ==
I) {
1495 if (BB->getSinglePredecessor()) {
1500 return BB->splitBasicBlock(
I, Name);
1513 unsigned depth = 3) {
1516 if (depth == 0)
return false;
1536 for (
auto *U : AI->
users()) {
1552 for (
auto *AI : LocalAllocas) {
1557 Value *StackSave =
nullptr;
1559 StackSave = Builder.CreateStackSave();
1562 auto Alloca = Builder.CreateAlloca(Builder.getInt8Ty(), AI->getSize());
1565 for (
auto *U : AI->
users()) {
1568 U->replaceAllUsesWith(Alloca);
1576 Builder.SetInsertPoint(FI);
1577 Builder.CreateStackRestore(StackSave);
1594 auto Call = Builder.CreateCall(FnTy, Fn, {});
1607 {V->getType()},
false);
1610 auto Call = Builder.CreateCall(FnTy, Fn, { V });
1629 auto ValueBeforeCall = Builder.CreateLoad(ValueTy, Alloca);
1636 Builder.SetInsertPoint(
Call->getNextNode());
1639 Builder.SetInsertPoint(Invoke->getNormalDest()->getFirstNonPHIOrDbg());
1644 Builder.CreateStore(ValueAfterCall, Alloca);
1681 F.getEntryBlock().getFirstNonPHIOrDbg());
1689 auto Alloca = Builder.CreateAlloca(ValueTy, ArgTy->getAddressSpace());
1694 Builder.CreateStore(InitialValue, Alloca);
1703 Builder.SetInsertPoint(End);
1704 auto FinalValue = Builder.CreateLoad(ValueTy, Alloca);
1719 for (
auto &Arg :
F.args()) {
1720 if (!Arg.hasSwiftErrorAttr())
continue;
1727 for (
auto &Inst :
F.getEntryBlock()) {
1740 if (!AllocasToPromote.
empty()) {
1758 DomSet.
insert(&
F.getEntryBlock());
1763 "should have split coro.suspend into its own block");
1778 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1787 if (!U->hasOneUse() || U->stripPointerCasts() != AI)
1806 if (collectLifetimeStart(UI, AI))
1814 if (Valid && Lifetimes.
size() != 0) {
1815 auto *NewLifetime = Lifetimes[0]->clone();
1816 NewLifetime->replaceUsesOfWith(NewLifetime->getOperand(0), AI);
1817 NewLifetime->insertBefore(DomBB->getTerminator()->getIterator());
1821 S->eraseFromParent();
1829static std::optional<std::pair<Value &, DIExpression &>>
1834 auto InsertPt =
F->getEntryBlock().getFirstInsertionPt();
1837 Builder.SetInsertPoint(&
F->getEntryBlock(), InsertPt);
1841 Storage = LdInst->getPointerOperand();
1848 if (!SkipOutermostLoad)
1851 Storage = StInst->getValueOperand();
1858 if (!
Op || !AdditionalValues.
empty()) {
1866 SkipOutermostLoad =
false;
1869 return std::nullopt;
1876 const bool WillUseEntryValue =
1877 UseEntryValue && StorageAsArg &&
1878 StorageAsArg->hasAttribute(Attribute::SwiftAsync) &&
1881 if (WillUseEntryValue)
1890 if (StorageAsArg && !WillUseEntryValue && IsSingleLocationExpression) {
1891 auto &Cached = ArgToAllocaMap[StorageAsArg];
1893 Cached = Builder.CreateAlloca(Storage->
getType(), 0,
nullptr,
1894 Storage->
getName() +
".debug");
1895 Builder.CreateStore(Storage, Cached);
1909 return {{*Storage, *Expr}};
1928 Value *Storage = &SalvagedInfo->first;
1938 std::optional<BasicBlock::iterator> InsertPt;
1940 InsertPt =
I->getInsertionPointAfterDef();
1944 if (ILoc && DVRLoc &&
1945 DVRLoc->getScope()->getSubprogram() ==
1946 ILoc->getScope()->getSubprogram())
1949 InsertPt =
F->getEntryBlock().begin();
1958 Type *Ty = VAM->getValue()->getType();
1959 if (Ty->isPointerTy())
1965 (*InsertPt)->getParent()->insertDbgRecordBefore(&DVR, *InsertPt);
1985 if (
auto *Save = CSI->getCoroSave())
1999 auto *MustTailCallFn = AsyncEnd->getMustTailCallFunction();
2000 if (!MustTailCallFn)
2006 AsyncEnd->getDebugLoc(), MustTailCallFn,
TTI,
Arguments, Builder);
2039 LocalAllocas,
F, Checker, DT,
Shape);
2050 FrameDataInfo FrameData(Spills, Allocas);
2059 for (
auto *
I : DeadInstructions)
2060 I->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
Rewrite undef for false bool rewritePHIs(Function &F, UniformityInfo &UA, DominatorTree *DT)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static void cleanupSinglePredPHIs(Function &F)
static TinyPtrVector< DbgVariableRecord * > findDbgRecordsThroughLoads(Function &F, Value *Def)
Find dbg.declare or dbg.declare_value records referencing Def.
static void createStoreIntoFrame(IRBuilder<> &Builder, Value *Def, Type *ByValTy, const coro::Shape &Shape, const FrameDataInfo &FrameData)
Store Def into the coroutine frame.
static void eliminateSwiftError(Function &F, coro::Shape &Shape)
Eliminate all problematic uses of swifterror arguments and allocas from the function.
static void lowerLocalAllocas(ArrayRef< CoroAllocaAllocInst * > LocalAllocas, SmallVectorImpl< Instruction * > &DeadInsts)
Turn each of the given local allocas into a normal (dynamic) alloca instruction.
static Value * emitSetSwiftErrorValue(IRBuilder<> &Builder, Value *V, coro::Shape &Shape)
Set the given value as the current swifterror value.
static Value * emitSetAndGetSwiftErrorValueAround(Instruction *Call, AllocaInst *Alloca, coro::Shape &Shape)
Set the swifterror value from the given alloca before a call, then put in back in the alloca afterwar...
static void cacheDIVar(FrameDataInfo &FrameData, DenseMap< Value *, DILocalVariable * > &DIVarCache)
static bool localAllocaNeedsStackSave(CoroAllocaAllocInst *AI)
static void dumpAllocas(const SmallVectorImpl< coro::AllocaInfo > &Allocas)
static void splitAround(Instruction *I, const Twine &Name)
static void eliminateSwiftErrorAlloca(Function &F, AllocaInst *Alloca, coro::Shape &Shape)
Eliminate a formerly-swifterror alloca by inserting the get/set intrinsics and attempting to MemToReg...
static void buildFrameLayout(Function &F, const DominatorTree &DT, coro::Shape &Shape, FrameDataInfo &FrameData, bool OptimizeFrame)
static void movePHIValuesToInsertedBlock(BasicBlock *SuccBB, BasicBlock *InsertedBB, BasicBlock *PredBB, PHINode *UntilPHI=nullptr)
static void dumpSpills(StringRef Title, const coro::SpillInfo &Spills)
static DIType * solveDIType(DIBuilder &Builder, Type *Ty, const DataLayout &Layout, DIScope *Scope, unsigned LineNum, DenseMap< Type *, DIType * > &DITypeCache)
static bool willLeaveFunctionImmediatelyAfter(BasicBlock *BB, unsigned depth=3)
After we split the coroutine, will the given basic block be along an obvious exit path for the resump...
static void eliminateSwiftErrorArgument(Function &F, Argument &Arg, coro::Shape &Shape, SmallVectorImpl< AllocaInst * > &AllocasToPromote)
"Eliminate" a swifterror argument by reducing it to the alloca case and then loading and storing in t...
static void buildFrameDebugInfo(Function &F, coro::Shape &Shape, FrameDataInfo &FrameData)
Build artificial debug info for C++ coroutine frames to allow users to inspect the contents of the fr...
static Value * createGEPToFramePointer(const FrameDataInfo &FrameData, IRBuilder<> &Builder, coro::Shape &Shape, Value *Orig)
Returns a pointer into the coroutine frame at the offset where Orig is located.
static bool hasAccessingPromiseBeforeCB(const DominatorTree &DT, coro::Shape &Shape)
static BasicBlock * splitBlockIfNotFirst(Instruction *I, const Twine &Name)
static void rewritePHIsForCleanupPad(BasicBlock *CleanupPadBB, CleanupPadInst *CleanupPad)
static void sinkLifetimeStartMarkers(Function &F, coro::Shape &Shape, SuspendCrossingInfo &Checker, const DominatorTree &DT)
For each local variable that all of its user are only used inside one of suspended region,...
static Type * extractByvalIfArgument(Value *MaybeArgument)
If MaybeArgument is a byval Argument, return its byval type.
static StringRef solveTypeName(Type *Ty)
Create name for Type.
static Value * emitGetSwiftErrorValue(IRBuilder<> &Builder, Type *ValueTy, coro::Shape &Shape)
Get the current swifterror value.
static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape)
static void handleAccessBeforeCoroBegin(const FrameDataInfo &FrameData, coro::Shape &Shape, IRBuilder<> &Builder, AllocaInst *Alloca)
static bool isLifetimeStart(const Instruction *Inst)
static MaybeAlign getAlign(Value *Ptr)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
This file provides an interface for laying out a sequence of fields as a struct in a way that attempt...
This file contains the declarations for profiling metadata utility functions.
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallString class.
static const unsigned FramePtr
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
void setSwiftError(bool V)
Specify whether this alloca is used to represent a swifterror.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction & front() const
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This represents the llvm.coro.alloca.alloc instruction.
LLVM_ABI DICompositeType * createStructType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang=0, DIType *VTableHolder=nullptr, StringRef UniqueIdentifier="", DIType *Specification=nullptr, uint32_t NumExtraInhabitants=0, DINodeArray Annotations=nullptr)
Create debugging information entry for a struct.
LLVM_ABI DIDerivedType * createMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations=nullptr)
Create debugging information entry for a member.
LLVM_ABI DIDerivedType * createPointerType(DIType *PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits=0, std::optional< unsigned > DWARFAddressSpace=std::nullopt, StringRef Name="", DINodeArray Annotations=nullptr)
Create debugging information entry for a pointer.
LLVM_ABI DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero, uint32_t NumExtraInhabitants=0, uint32_t DataSizeInBits=0)
Create debugging information entry for a basic type.
LLVM_ABI DINodeArray getOrCreateArray(ArrayRef< Metadata * > Elements)
Get a DINodeArray, create one if required.
LLVM_ABI DIExpression * createExpression(ArrayRef< uint64_t > Addr={})
Create a new descriptor for the specified variable which has a complex address expression for its add...
LLVM_ABI DILocalVariable * createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve=false, DINode::DIFlags Flags=DINode::FlagZero, uint32_t AlignInBits=0)
Create a new descriptor for an auto variable.
LLVM_ABI void replaceArrays(DICompositeType *&T, DINodeArray Elements, DINodeArray TParams=DINodeArray())
Replace arrays on a composite type.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
LLVM_ABI DIExpression * foldConstantMath()
Try to shorten an expression with constant math operations that can be evaluated at compile time.
LLVM_ABI uint64_t getNumLocationOperands() const
Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...
static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
LLVM_ABI bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
Base class for scope-like contexts.
Subprogram description. Uses SubclassData1.
StringRef getName() const
uint64_t getSizeInBits() const
LLVM_ABI uint32_t getAlignInBits() const
A parsed version of the target data layout string in and methods for querying it.
unsigned getPointerSizeInBits(unsigned AS=0) const
The size in bits of the pointer representation in a given address space.
LLVM_ABI const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
LLVM_ABI Align getPointerABIAlignment(unsigned AS) const
Layout pointer alignment.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
LLVM_ABI void removeFromParent()
DebugLoc getDebugLoc() const
void setDebugLoc(DebugLoc Loc)
LLVM_ABI Function * getFunction()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType getType() const
LocationType Type
Classification of the debug-info record that this DbgVariableRecord represents.
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
void setExpression(DIExpression *NewExpr)
DIExpression * getExpression() const
bool isDbgDeclareValue() const
Metadata * getRawLocation() const
Returns the metadata operand for the first location description.
bool isDbgDeclare() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
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 insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
LLVM_ABI MDNode * createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, uint64_t Offset=0)
Return metadata for a TBAA scalar type node with the given name, an offset and a parent in the TBAA t...
static constexpr uint32_t kUnlikelyBranchWeight
The weight for a branch taken with low probability.
LLVM_ABI MDNode * createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, uint64_t Offset, bool IsConstant=false)
Return metadata for a TBAA tag node with the given base type, access type and offset relative to the ...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVMContext & getContext() const
static MDTuple * getIfExists(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static LLVM_ABI MDString * getIfExists(LLVMContext &Context, StringRef Str)
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
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.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
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.
std::string str() const
Get the contents as an std::string.
TypeSize getElementOffsetInBits(unsigned Idx) const
bool isDefinitionAcrossSuspend(BasicBlock *DefBB, User *U) const
void setDefaultDest(BasicBlock *DefaultCase)
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
A Use represents the edge between a Value definition and its users.
LLVM_ABI void set(Value *Val)
User * getUser() const
Returns the User that contains this Use.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::function< bool(Instruction &I)> IsMaterializable
virtual void buildCoroutineFrame(bool OptimizeFrame)
constexpr ScalarTy getFixedValue() const
const ParentTy * getParent() const
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
SmallMapVector< Value *, SmallVector< Instruction *, 2 >, 8 > SpillInfo
@ Async
The "async continuation" lowering, where each suspend point creates a single continuation function.
@ RetconOnce
The "unique returned-continuation" lowering, where each suspend point creates a single continuation f...
@ Retcon
The "returned-continuation" lowering, where each suspend point creates a single continuation function...
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
LLVM_ABI BasicBlock::iterator getSpillInsertionPt(const coro::Shape &, Value *Def, const DominatorTree &DT)
bool isSuspendBlock(BasicBlock *BB)
void normalizeCoroutine(Function &F, coro::Shape &Shape, TargetTransformInfo &TTI)
CallInst * createMustTailCall(DebugLoc Loc, Function *MustTailCallFn, TargetTransformInfo &TTI, ArrayRef< Value * > Arguments, IRBuilder<> &)
LLVM_ABI void sinkSpillUsesAfterCoroBegin(const DominatorTree &DT, CoroBeginInst *CoroBegin, coro::SpillInfo &Spills, SmallVectorImpl< coro::AllocaInfo > &Allocas)
Async and Retcon{Once} conventions assume that all spill uses can be sunk after the coro....
LLVM_ABI void doRematerializations(Function &F, SuspendCrossingInfo &Checker, std::function< bool(Instruction &)> IsMaterializable)
LLVM_ABI void collectSpillsFromArgs(SpillInfo &Spills, Function &F, const SuspendCrossingInfo &Checker)
LLVM_ABI void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F, const SuspendCrossingInfo &Checker)
void salvageDebugInfo(SmallDenseMap< Argument *, AllocaInst *, 4 > &ArgToAllocaMap, DbgVariableRecord &DVR, bool UseEntryValue)
Attempts to rewrite the location operand of debug records in terms of the coroutine frame pointer,...
LLVM_ABI void collectSpillsAndAllocasFromInsts(SpillInfo &Spills, SmallVector< AllocaInfo, 8 > &Allocas, SmallVector< Instruction *, 4 > &DeadInstructions, SmallVector< CoroAllocaAllocInst *, 4 > &LocalAllocas, Function &F, const SuspendCrossingInfo &Checker, const DominatorTree &DT, const coro::Shape &Shape)
bool isCPlusPlus(SourceLanguage S)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
auto successors(const MachineBasicBlock *BB)
scope_exit(Callable) -> scope_exit< Callable >
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...
auto pred_size(const MachineBasicBlock *BB)
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
LLVM_ABI BasicBlock * ehAwareSplitEdge(BasicBlock *BB, BasicBlock *Succ, LandingPadInst *OriginalPad=nullptr, PHINode *LandingPadReplacement=nullptr, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
Split the edge connect the specficed blocks in the case that Succ is an Exception Handling Block.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
LLVM_ABI Value * salvageDebugInfoImpl(Instruction &I, uint64_t CurrentLocOps, SmallVectorImpl< uint64_t > &Ops, SmallVectorImpl< Value * > &AdditionalValues)
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
LLVM_ABI std::pair< uint64_t, Align > performOptimizedStructLayout(MutableArrayRef< OptimizedStructLayoutField > Fields)
Compute a layout for a struct containing the given fields, making a best-effort attempt to minimize t...
DWARFExpression::Operation Op
LLVM_ABI TinyPtrVector< DbgVariableRecord * > findDVRDeclareValues(Value *V)
As above, for DVRDeclareValues.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI void updatePhiNodes(BasicBlock *DestBB, BasicBlock *OldPred, BasicBlock *NewPred, PHINode *Until=nullptr)
Replaces all uses of OldPred with the NewPred block in all PHINodes in a block.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI TinyPtrVector< DbgVariableRecord * > findDVRDeclares(Value *V)
Finds dbg.declare records declaring local variables as living in the memory that 'V' points to.
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI void setUnwindEdgeTo(Instruction *TI, BasicBlock *Succ)
Sets the unwind edge of an instruction to a particular successor.
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align Alignment
The required alignment of this field.
uint64_t Offset
The offset of this field in the final layout.
uint64_t Size
The required size of this field in bytes.
static constexpr uint64_t FlexibleOffset
A special value for Offset indicating that the field can be moved anywhere.
Align getContextAlignment() const
uint64_t ContextHeaderSize
bool IsFrameInlineInStorage
AllocaInst * PromiseAlloca
AsyncLoweringStorage AsyncLowering
IntegerType * getIndexType() const
AnyCoroIdRetconInst * getRetconCoroId() const
PointerType * getSwitchResumePointerType() const
CoroIdInst * getSwitchCoroId() const
SmallVector< AnyCoroSuspendInst *, 4 > CoroSuspends
AllocaInst * getPromiseAlloca() const
SwitchLoweringStorage SwitchLowering
CoroBeginInst * CoroBegin
BasicBlock::iterator getInsertPtAfterFramePtr() const
RetconLoweringStorage RetconLowering
SmallVector< AnyCoroEndInst *, 4 > CoroEnds
SmallVector< CallInst *, 2 > SwiftErrorOps
BasicBlock * AllocaSpillBlock