@@ -429,12 +429,15 @@ class FrameTypeBuilder {
429
429
Align StructAlign;
430
430
bool IsFinished = false ;
431
431
432
+ Optional<Align> MaxFrameAlignment;
433
+
432
434
SmallVector<Field, 8 > Fields;
433
435
DenseMap<Value*, unsigned > FieldIndexByKey;
434
436
435
437
public:
436
- FrameTypeBuilder (LLVMContext &Context, DataLayout const &DL)
437
- : DL(DL), Context(Context) {}
438
+ FrameTypeBuilder (LLVMContext &Context, DataLayout const &DL,
439
+ Optional<Align> MaxFrameAlignment)
440
+ : DL(DL), Context(Context), MaxFrameAlignment(MaxFrameAlignment) {}
438
441
439
442
// / Add a field to this structure for the storage of an `alloca`
440
443
// / instruction.
@@ -485,7 +488,8 @@ class FrameTypeBuilder {
485
488
486
489
// / Add a field to this structure.
487
490
LLVM_NODISCARD FieldIDType addField (Type *Ty, MaybeAlign FieldAlignment,
488
- bool IsHeader = false ) {
491
+ bool IsHeader = false ,
492
+ bool IsSpillOfValue = false ) {
489
493
assert (!IsFinished && " adding fields to a finished builder" );
490
494
assert (Ty && " must provide a type for a field" );
491
495
@@ -500,8 +504,16 @@ class FrameTypeBuilder {
500
504
501
505
// The field alignment might not be the type alignment, but we need
502
506
// to remember the type alignment anyway to build the type.
503
- Align TyAlignment = DL.getABITypeAlign (Ty);
504
- if (!FieldAlignment) FieldAlignment = TyAlignment;
507
+ // If we are spilling values we don't need to worry about ABI alignment
508
+ // concerns.
509
+ auto ABIAlign = DL.getABITypeAlign (Ty);
510
+ Align TyAlignment =
511
+ (IsSpillOfValue && MaxFrameAlignment)
512
+ ? (*MaxFrameAlignment < ABIAlign ? *MaxFrameAlignment : ABIAlign)
513
+ : ABIAlign;
514
+ if (!FieldAlignment) {
515
+ FieldAlignment = TyAlignment;
516
+ }
505
517
506
518
// Lay out header fields immediately.
507
519
uint64_t Offset;
@@ -1089,7 +1101,11 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
1089
1101
return StructType::create (C, Name);
1090
1102
}();
1091
1103
1092
- FrameTypeBuilder B (C, DL);
1104
+ // We will use this value to cap the alignment of spilled values.
1105
+ Optional<Align> MaxFrameAlignment;
1106
+ if (Shape.ABI == coro::ABI::Async)
1107
+ MaxFrameAlignment = Shape.AsyncLowering .getContextAlignment ();
1108
+ FrameTypeBuilder B (C, DL, MaxFrameAlignment);
1093
1109
1094
1110
AllocaInst *PromiseAlloca = Shape.getPromiseAlloca ();
1095
1111
Optional<FieldIDType> SwitchIndexFieldId;
@@ -1142,7 +1158,8 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
1142
1158
if (const Argument *A = dyn_cast<Argument>(S.first ))
1143
1159
if (A->hasByValAttr ())
1144
1160
FieldType = FieldType->getPointerElementType ();
1145
- FieldIDType Id = B.addField (FieldType, None);
1161
+ FieldIDType Id =
1162
+ B.addField (FieldType, None, false /* header*/ , true /* IsSpillOfValue*/ );
1146
1163
FrameData.setFieldIndex (S.first , Id);
1147
1164
}
1148
1165
@@ -1545,6 +1562,7 @@ static Instruction *insertSpills(const FrameDataInfo &FrameData,
1545
1562
1546
1563
for (auto const &E : FrameData.Spills ) {
1547
1564
Value *Def = E.first ;
1565
+ auto SpillAlignment = Align (FrameData.getAlign (Def));
1548
1566
// Create a store instruction storing the value into the
1549
1567
// coroutine frame.
1550
1568
Instruction *InsertPt = nullptr ;
@@ -1601,9 +1619,9 @@ static Instruction *insertSpills(const FrameDataInfo &FrameData,
1601
1619
// instead of the pointer itself.
1602
1620
auto *Value =
1603
1621
Builder.CreateLoad (Def->getType ()->getPointerElementType (), Def);
1604
- Builder.CreateStore (Value, G);
1622
+ Builder.CreateAlignedStore (Value, G, SpillAlignment );
1605
1623
} else {
1606
- Builder.CreateStore (Def, G);
1624
+ Builder.CreateAlignedStore (Def, G, SpillAlignment );
1607
1625
}
1608
1626
1609
1627
BasicBlock *CurrentBlock = nullptr ;
@@ -1621,9 +1639,9 @@ static Instruction *insertSpills(const FrameDataInfo &FrameData,
1621
1639
if (NeedToCopyArgPtrValue)
1622
1640
CurrentReload = GEP;
1623
1641
else
1624
- CurrentReload = Builder.CreateLoad (
1642
+ CurrentReload = Builder.CreateAlignedLoad (
1625
1643
FrameTy->getElementType (FrameData.getFieldIndex (E.first )), GEP,
1626
- E.first ->getName () + Twine (" .reload" ));
1644
+ SpillAlignment, E.first ->getName () + Twine (" .reload" ));
1627
1645
1628
1646
TinyPtrVector<DbgDeclareInst *> DIs = FindDbgDeclareUses (Def);
1629
1647
for (DbgDeclareInst *DDI : DIs) {
0 commit comments