@@ -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,
@@ -1157,6 +1165,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1157
1165
llvm::Value *src = args.claimNext ();
1158
1166
llvm::Value *count = args.claimNext ();
1159
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.
1160
1171
if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1161
1172
auto tyPair = getLoweredTypeAndTypeInfo (
1162
1173
IGF.IGM , substitutions.getReplacementTypes ()[0 ]);
@@ -1172,10 +1183,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1172
1183
return ;
1173
1184
}
1174
1185
1175
- llvm::Value *firstSrcElem = IGF.Builder .CreateBitCast (
1176
- src, elemTI.getStorageType ()->getPointerTo ());
1177
- llvm::Value *firstDestElem = IGF.Builder .CreateBitCast (
1178
- 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 );
1179
1194
1180
1195
auto *origBB = IGF.Builder .GetInsertBlock ();
1181
1196
auto *headerBB = IGF.createBasicBlock (" loop_header" );
@@ -1203,10 +1218,16 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1203
1218
break ;
1204
1219
}
1205
1220
1206
- auto *srcElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1207
- firstSrcElem, idx);
1208
- auto *destElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1209
- 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
+
1210
1231
Address destAddr = elemTI.getAddressForPointer (destElem);
1211
1232
Address srcAddr = elemTI.getAddressForPointer (srcElem);
1212
1233
0 commit comments