@@ -1095,6 +1095,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1095
1095
auto valueTy = getLoweredTypeAndTypeInfo (IGF.IGM ,
1096
1096
substitutions.getReplacementTypes ()[0 ]);
1097
1097
1098
+ // In Embedded Swift we don't have metadata and witness tables, so we can't
1099
+ // just use TypeInfo's destroyArray, which needs metadata to emit a call to
1100
+ // swift_arrayDestroy. Emit a loop to destroy elements directly instead.
1098
1101
if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1099
1102
SILType elemTy = valueTy.first ;
1100
1103
const TypeInfo &elemTI = valueTy.second ;
@@ -1103,8 +1106,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1103
1106
IsTriviallyDestroyable)
1104
1107
return ;
1105
1108
1106
- llvm::Value *firstElem = IGF.Builder .CreateBitCast (
1107
- ptr, elemTI.getStorageType ()->getPointerTo ());
1109
+ llvm::Value *firstElem =
1110
+ IGF.Builder .CreatePtrToInt (IGF.Builder .CreateBitCast (
1111
+ ptr, elemTI.getStorageType ()->getPointerTo ()), IGF.IGM .IntPtrTy );
1108
1112
1109
1113
auto *origBB = IGF.Builder .GetInsertBlock ();
1110
1114
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1118,8 +1122,12 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1118
1122
IGF.Builder .CreateCondBr (cmp, loopBB, exitBB);
1119
1123
1120
1124
IGF.Builder .emitBlock (loopBB);
1121
- auto *addr = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1122
- firstElem, phi);
1125
+
1126
+ llvm::Value *offset =
1127
+ IGF.Builder .CreateMul (phi, elemTI.getStaticStride (IGF.IGM ));
1128
+ llvm::Value *added = IGF.Builder .CreateAdd (firstElem, offset);
1129
+ llvm::Value *addr = IGF.Builder .CreateIntToPtr (
1130
+ added, elemTI.getStorageType ()->getPointerTo ());
1123
1131
1124
1132
bool isOutlined = false ;
1125
1133
elemTI.destroy (IGF, elemTI.getAddressForPointer (addr), elemTy,
@@ -1168,6 +1176,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1168
1176
llvm::Value *src = args.claimNext ();
1169
1177
llvm::Value *count = args.claimNext ();
1170
1178
1179
+ // In Embedded Swift we don't have metadata and witness tables, so we can't
1180
+ // just use TypeInfo's initialize... and assign... APIs, which need
1181
+ // metadata to emit calls. Emit a loop to process elements directly instead.
1171
1182
if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1172
1183
auto tyPair = getLoweredTypeAndTypeInfo (
1173
1184
IGF.IGM , substitutions.getReplacementTypes ()[0 ]);
@@ -1183,10 +1194,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1183
1194
return ;
1184
1195
}
1185
1196
1186
- llvm::Value *firstSrcElem = IGF.Builder .CreateBitCast (
1187
- src, elemTI.getStorageType ()->getPointerTo ());
1188
- llvm::Value *firstDestElem = IGF.Builder .CreateBitCast (
1189
- dest, elemTI.getStorageType ()->getPointerTo ());
1197
+ llvm::Value *firstSrcElem = IGF.Builder .CreatePtrToInt (
1198
+ IGF.Builder .CreateBitCast (src,
1199
+ elemTI.getStorageType ()->getPointerTo ()),
1200
+ IGF.IGM .IntPtrTy );
1201
+ llvm::Value *firstDestElem = IGF.Builder .CreatePtrToInt (
1202
+ IGF.Builder .CreateBitCast (dest,
1203
+ elemTI.getStorageType ()->getPointerTo ()),
1204
+ IGF.IGM .IntPtrTy );
1190
1205
1191
1206
auto *origBB = IGF.Builder .GetInsertBlock ();
1192
1207
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1214,10 +1229,16 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1214
1229
break ;
1215
1230
}
1216
1231
1217
- auto *srcElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1218
- firstSrcElem, idx);
1219
- auto *destElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1220
- firstDestElem, idx);
1232
+ llvm::Value *offset =
1233
+ IGF.Builder .CreateMul (idx, elemTI.getStaticStride (IGF.IGM ));
1234
+
1235
+ llvm::Value *srcAdded = IGF.Builder .CreateAdd (firstSrcElem, offset);
1236
+ auto *srcElem = IGF.Builder .CreateIntToPtr (
1237
+ srcAdded, elemTI.getStorageType ()->getPointerTo ());
1238
+ llvm::Value *dstAdded = IGF.Builder .CreateAdd (firstDestElem, offset);
1239
+ auto *destElem = IGF.Builder .CreateIntToPtr (
1240
+ dstAdded, elemTI.getStorageType ()->getPointerTo ());
1241
+
1221
1242
Address destAddr = elemTI.getAddressForPointer (destElem);
1222
1243
Address srcAddr = elemTI.getAddressForPointer (srcElem);
1223
1244
0 commit comments