@@ -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" );
@@ -1162,6 +1165,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1162
1165
llvm::Value *src = args.claimNext ();
1163
1166
llvm::Value *count = args.claimNext ();
1164
1167
1168
+ // In Embedded Swift we don't have metadata and witness tables, so we can't
1169
+ // just use TypeInfo's initialize... and assign... APIs, which need
1170
+ // metadata to emit calls. Emit a loop to process elements directly instead.
1165
1171
if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1166
1172
auto tyPair = getLoweredTypeAndTypeInfo (
1167
1173
IGF.IGM , substitutions.getReplacementTypes ()[0 ]);
@@ -1177,10 +1183,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1177
1183
return ;
1178
1184
}
1179
1185
1180
- llvm::Value *firstSrcElem = IGF.Builder .CreateBitCast (
1181
- src, elemTI.getStorageType ()->getPointerTo ());
1182
- llvm::Value *firstDestElem = IGF.Builder .CreateBitCast (
1183
- dest, elemTI.getStorageType ()->getPointerTo ());
1186
+ llvm::Value *firstSrcElem = IGF.Builder .CreatePtrToInt (
1187
+ IGF.Builder .CreateBitCast (src,
1188
+ elemTI.getStorageType ()->getPointerTo ()),
1189
+ IGF.IGM .IntPtrTy );
1190
+ llvm::Value *firstDestElem = IGF.Builder .CreatePtrToInt (
1191
+ IGF.Builder .CreateBitCast (dest,
1192
+ elemTI.getStorageType ()->getPointerTo ()),
1193
+ IGF.IGM .IntPtrTy );
1184
1194
1185
1195
auto *origBB = IGF.Builder .GetInsertBlock ();
1186
1196
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1208,10 +1218,16 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1208
1218
break ;
1209
1219
}
1210
1220
1211
- auto *srcElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1212
- firstSrcElem, idx);
1213
- auto *destElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1214
- firstDestElem, idx);
1221
+ llvm::Value *offset =
1222
+ IGF.Builder .CreateMul (idx, elemTI.getStaticStride (IGF.IGM ));
1223
+
1224
+ llvm::Value *srcAdded = IGF.Builder .CreateAdd (firstSrcElem, offset);
1225
+ auto *srcElem = IGF.Builder .CreateIntToPtr (
1226
+ srcAdded, elemTI.getStorageType ()->getPointerTo ());
1227
+ llvm::Value *dstAdded = IGF.Builder .CreateAdd (firstDestElem, offset);
1228
+ auto *destElem = IGF.Builder .CreateIntToPtr (
1229
+ dstAdded, elemTI.getStorageType ()->getPointerTo ());
1230
+
1215
1231
Address destAddr = elemTI.getAddressForPointer (destElem);
1216
1232
Address srcAddr = elemTI.getAddressForPointer (srcElem);
1217
1233
0 commit comments