@@ -2325,35 +2325,6 @@ llvm::CallSite CallEmission::emitCallSite(bool hasIndirectResult) {
2325
2325
return call;
2326
2326
}
2327
2327
2328
- enum class ResultDifference {
2329
- // / The substituted result type is the same as the original result type.
2330
- Identical,
2331
-
2332
- // / The substituted result type is a different formal type from, but
2333
- // / has the same layout and interpretation as, the original result type.
2334
- Aliasable,
2335
-
2336
- // / The substitued result type has the same layout as the original
2337
- // / result type, but may differ in interpretation.
2338
- // Reinterpretable,
2339
-
2340
- // / The substituted result type differs not just in interpretation,
2341
- // / but in layout, from the original result type.
2342
- Divergent
2343
- };
2344
-
2345
- static ResultDifference computeResultDifference (IRGenModule &IGM,
2346
- CanType origResultType,
2347
- CanType substResultType) {
2348
- if (origResultType == substResultType)
2349
- return ResultDifference::Identical;
2350
-
2351
- if (differsByAbstractionInMemory (IGM, origResultType, substResultType))
2352
- return ResultDifference::Divergent;
2353
-
2354
- return ResultDifference::Aliasable;
2355
- }
2356
-
2357
2328
// / Emit the result of this call to memory.
2358
2329
void CallEmission::emitToMemory (Address addr, const TypeInfo &substResultTI) {
2359
2330
assert (LastArgWritten <= 1 );
@@ -2383,28 +2354,17 @@ void CallEmission::emitToMemory(Address addr, const TypeInfo &substResultTI) {
2383
2354
substResultType = substFnType->getResult ().getType ();
2384
2355
}
2385
2356
2386
- // Figure out how the substituted result differs from the original.
2387
- auto resultDiff =
2388
- computeResultDifference (IGF. IGM , origResultType, substResultType);
2389
- switch (resultDiff) {
2357
+ if (origResultType-> hasTypeParameter ())
2358
+ origResultType = IGF. IGM . getContextArchetypes ()
2359
+ . substDependentType (origResultType)
2360
+ -> getCanonicalType ();
2390
2361
2391
- // For aliasable types, just bitcast the output address.
2392
- case ResultDifference::Aliasable: {
2362
+ if (origResultType != substResultType) {
2393
2363
auto origTy = IGF.IGM .getStoragePointerTypeForLowered (origResultType);
2394
2364
origAddr = IGF.Builder .CreateBitCast (origAddr, origTy);
2395
- SWIFT_FALLTHROUGH;
2396
2365
}
2397
2366
2398
- case ResultDifference::Identical:
2399
- emitToUnmappedMemory (origAddr);
2400
- return ;
2401
-
2402
- case ResultDifference::Divergent:
2403
- // We need to do layout+allocation under substitution rules.
2404
- return IGF.unimplemented (SourceLoc (), " divergent emission to memory" );
2405
- }
2406
-
2407
- llvm_unreachable (" bad difference kind" );
2367
+ emitToUnmappedMemory (origAddr);
2408
2368
}
2409
2369
2410
2370
// / Emit the result of this call to an explosion.
@@ -2442,17 +2402,7 @@ void CallEmission::emitToExplosion(Explosion &out) {
2442
2402
->getCanonicalType ();
2443
2403
2444
2404
// Okay, we're naturally emitting to an explosion.
2445
- // Figure out how the substituted result differs from the original.
2446
- auto resultDiff = computeResultDifference (IGF.IGM , origResultType,
2447
- substResultType.getSwiftRValueType ());
2448
-
2449
- switch (resultDiff) {
2450
- // If they don't differ at all, we're good.
2451
- case ResultDifference::Identical:
2452
- emitToUnmappedExplosion (out);
2453
- return ;
2454
-
2455
- case ResultDifference::Aliasable: {
2405
+ if (origResultType != substResultType.getSwiftRValueType ()) {
2456
2406
Explosion temp;
2457
2407
emitToUnmappedExplosion (temp);
2458
2408
ExplosionSchema resultSchema = substResultTI.getSchema ();
@@ -2468,48 +2418,7 @@ void CallEmission::emitToExplosion(Explosion &out) {
2468
2418
return ;
2469
2419
}
2470
2420
2471
- // If they do differ, we need to remap.
2472
- case ResultDifference::Divergent:
2473
- if (substResultType.is <MetatypeType>() &&
2474
- isa<MetatypeType>(origResultType)) {
2475
- // If we got here, it's because the substituted metatype is trivial.
2476
- // Remapping is easy--the substituted type is empty, so we drop the
2477
- // nontrivial representation of the original type.
2478
- assert (substResultType.castTo <MetatypeType>()->getRepresentation ()
2479
- == MetatypeRepresentation::Thin
2480
- && " remapping to non-thin metatype?!" );
2481
-
2482
- Explosion temp;
2483
- emitToUnmappedExplosion (temp);
2484
- temp.claimAll ();
2485
- return ;
2486
- }
2487
-
2488
- if (auto origArchetype = dyn_cast<ArchetypeType>(origResultType)) {
2489
- if (origArchetype->requiresClass ()) {
2490
- // Remap a class archetype to an instance.
2491
- assert (substResultType.hasReferenceSemantics () &&
2492
- " remapping class archetype to non-class?!" );
2493
- auto schema = substResultTI.getSchema ();
2494
- assert (schema.size () == 1 && schema.begin ()->isScalar ()
2495
- && " remapping class archetype to non-single-scalar" );
2496
- Explosion temp;
2497
- emitToUnmappedExplosion (temp);
2498
- llvm::Value *pointer = temp.claimNext ();
2499
- pointer = IGF.Builder .CreateBitCast (pointer,
2500
- schema.begin ()->getScalarType ());
2501
- out.add (pointer);
2502
- return ;
2503
- }
2504
- }
2505
-
2506
- // There's a related FIXME in the Builtin.load/move code.
2507
- IGF.unimplemented (SourceLoc (), " remapping explosion" );
2508
- IGF.emitFakeExplosion (substResultTI, out);
2509
- return ;
2510
- }
2511
-
2512
- llvm_unreachable (" bad difference kind" );
2421
+ emitToUnmappedExplosion (out);
2513
2422
}
2514
2423
2515
2424
CallEmission::CallEmission (CallEmission &&other)
0 commit comments