@@ -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 ;
@@ -1105,7 +1108,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1105
1108
1106
1109
llvm::Value *firstElem =
1107
1110
IGF.Builder .CreatePtrToInt (IGF.Builder .CreateBitCast (
1108
- ptr, elemTI.getStorageType ()->getPointerTo ()));
1111
+ ptr, elemTI.getStorageType ()->getPointerTo ()), IGF. IGM . IntPtrTy );
1109
1112
1110
1113
auto *origBB = IGF.Builder .GetInsertBlock ();
1111
1114
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1173,6 +1176,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1173
1176
llvm::Value *src = args.claimNext ();
1174
1177
llvm::Value *count = args.claimNext ();
1175
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.
1176
1182
if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1177
1183
auto tyPair = getLoweredTypeAndTypeInfo (
1178
1184
IGF.IGM , substitutions.getReplacementTypes ()[0 ]);
@@ -1188,10 +1194,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1188
1194
return ;
1189
1195
}
1190
1196
1191
- llvm::Value *firstSrcElem = IGF.Builder .CreateBitCast (
1192
- src, elemTI.getStorageType ()->getPointerTo ());
1193
- llvm::Value *firstDestElem = IGF.Builder .CreateBitCast (
1194
- 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 );
1195
1205
1196
1206
auto *origBB = IGF.Builder .GetInsertBlock ();
1197
1207
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1219,10 +1229,16 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1219
1229
break ;
1220
1230
}
1221
1231
1222
- auto *srcElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1223
- firstSrcElem, idx);
1224
- auto *destElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1225
- 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
+
1226
1242
Address destAddr = elemTI.getAddressForPointer (destElem);
1227
1243
Address srcAddr = elemTI.getAddressForPointer (srcElem);
1228
1244
0 commit comments