@@ -1128,7 +1128,81 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
1128
1128
llvm::Value *dest = args.claimNext ();
1129
1129
llvm::Value *src = args.claimNext ();
1130
1130
llvm::Value *count = args.claimNext ();
1131
-
1131
+
1132
+ if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
1133
+ auto tyPair = getLoweredTypeAndTypeInfo (
1134
+ IGF.IGM , substitutions.getReplacementTypes ()[0 ]);
1135
+ SILType elemTy = tyPair.first ;
1136
+ const TypeInfo &elemTI = tyPair.second ;
1137
+
1138
+ llvm::Value *firstSrcElem = IGF.Builder .CreateBitCast (
1139
+ src, elemTI.getStorageType ()->getPointerTo ());
1140
+ llvm::Value *firstDestElem = IGF.Builder .CreateBitCast (
1141
+ dest, elemTI.getStorageType ()->getPointerTo ());
1142
+
1143
+ auto *origBB = IGF.Builder .GetInsertBlock ();
1144
+ auto *headerBB = IGF.createBasicBlock (" loop_header" );
1145
+ auto *loopBB = IGF.createBasicBlock (" loop_body" );
1146
+ auto *exitBB = IGF.createBasicBlock (" loop_exit" );
1147
+ IGF.Builder .CreateBr (headerBB);
1148
+ IGF.Builder .emitBlock (headerBB);
1149
+ auto *phi = IGF.Builder .CreatePHI (count->getType (), 2 );
1150
+ phi->addIncoming (llvm::ConstantInt::get (count->getType (), 0 ), origBB);
1151
+ llvm::Value *cmp = IGF.Builder .CreateICmpSLT (phi, count);
1152
+ IGF.Builder .CreateCondBr (cmp, loopBB, exitBB);
1153
+
1154
+ IGF.Builder .emitBlock (loopBB);
1155
+ llvm::Value *idx = phi;
1156
+
1157
+ switch (Builtin.ID ) {
1158
+ case BuiltinValueKind::TakeArrayBackToFront:
1159
+ case BuiltinValueKind::AssignCopyArrayBackToFront: {
1160
+ llvm::Value *countMinusIdx = IGF.Builder .CreateSub (count, phi);
1161
+ auto *one = llvm::ConstantInt::get (count->getType (), 1 );
1162
+ idx = IGF.Builder .CreateSub (countMinusIdx, one);
1163
+ break ;
1164
+ }
1165
+ default :
1166
+ break ;
1167
+ }
1168
+
1169
+ auto *srcElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1170
+ firstSrcElem, idx);
1171
+ auto *destElem = IGF.Builder .CreateInBoundsGEP (elemTI.getStorageType (),
1172
+ firstDestElem, idx);
1173
+ Address destAddr = elemTI.getAddressForPointer (destElem);
1174
+ Address srcAddr = elemTI.getAddressForPointer (srcElem);
1175
+
1176
+ bool isOutlined = false ;
1177
+ switch (Builtin.ID ) {
1178
+ case BuiltinValueKind::CopyArray:
1179
+ elemTI.initializeWithCopy (IGF, destAddr, srcAddr, elemTy, isOutlined);
1180
+ break ;
1181
+ case BuiltinValueKind::TakeArrayNoAlias:
1182
+ case BuiltinValueKind::TakeArrayFrontToBack:
1183
+ case BuiltinValueKind::TakeArrayBackToFront:
1184
+ elemTI.initializeWithTake (IGF, destAddr, srcAddr, elemTy, isOutlined);
1185
+ break ;
1186
+ case BuiltinValueKind::AssignCopyArrayNoAlias:
1187
+ case BuiltinValueKind::AssignCopyArrayFrontToBack:
1188
+ case BuiltinValueKind::AssignCopyArrayBackToFront:
1189
+ elemTI.assignWithCopy (IGF, destAddr, srcAddr, elemTy, isOutlined);
1190
+ break ;
1191
+ case BuiltinValueKind::AssignTakeArray:
1192
+ elemTI.assignWithTake (IGF, destAddr, srcAddr, elemTy, isOutlined);
1193
+ break ;
1194
+ default :
1195
+ llvm_unreachable (" out of sync with if condition" );
1196
+ }
1197
+ auto *one = llvm::ConstantInt::get (count->getType (), 1 );
1198
+ auto *addIdx = IGF.Builder .CreateAdd (phi, one);
1199
+ phi->addIncoming (addIdx, loopBB);
1200
+ IGF.Builder .CreateBr (headerBB);
1201
+
1202
+ IGF.Builder .emitBlock (exitBB);
1203
+ return ;
1204
+ }
1205
+
1132
1206
auto valueTy = getLoweredTypeAndTypeInfo (IGF.IGM ,
1133
1207
substitutions.getReplacementTypes ()[0 ]);
1134
1208
0 commit comments