Skip to content

Commit 3320052

Browse files
committed
Merge remote-tracking branch 'origin/swift-4.1-branch' into swift-5.0-branch
2 parents b01ed59 + ac020e0 commit 3320052

11 files changed

+101
-33
lines changed

include/swift/Option/Options.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,14 @@ def whole_module_optimization : Flag<["-"], "whole-module-optimization">,
619619
HelpText<"Optimize input files together instead of individually">,
620620
Flags<[FrontendOption, NoInteractiveOption]>;
621621

622+
def enable_batch_mode : Flag<["-"], "enable-batch-mode">,
623+
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
624+
HelpText<"Enable combining frontend jobs into batches">;
625+
626+
def disable_batch_mode : Flag<["-"], "disable-batch-mode">,
627+
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
628+
HelpText<"Disable combining frontend jobs into batches">;
629+
622630
def wmo : Flag<["-"], "wmo">, Alias<whole_module_optimization>,
623631
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>;
624632

include/swift/SIL/TypeLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,8 @@ class TypeConverter {
830830
/// The ABI compatible relation is not symmetric on function types -- while
831831
/// T and T! are both subtypes of each other, a calling convention conversion
832832
/// of T! to T always requires a thunk.
833-
ABIDifference checkForABIDifferences(SILType type1, SILType type2);
833+
ABIDifference checkForABIDifferences(SILType type1, SILType type2,
834+
bool thunkOptionals = true);
834835

835836
/// \brief Same as above but for SIL function types.
836837
ABIDifference checkFunctionForABIDifferences(SILFunctionType *fnTy1,

lib/IRGen/GenBuiltin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
198198
// At that stage, the function name GV used by the profiling pass is hidden.
199199
// Fix the intrinsic call here by pointing it to the correct GV.
200200
if (IID == llvm::Intrinsic::instrprof_increment) {
201+
// If we import profiling intrinsics from a swift module but profiling is
202+
// not enabled, ignore the increment.
203+
if (!IGF.getSILModule().getOptions().GenerateProfile)
204+
return;
205+
201206
// Extract the PGO function name.
202207
auto *NameGEP = cast<llvm::User>(args.claimNext());
203208
auto *NameGV = dyn_cast<llvm::GlobalVariable>(NameGEP->stripPointerCasts());

lib/IRGen/LoadableByAddress.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,16 @@ static bool shouldTransformFunctionType(GenericEnvironment *env,
7979
CanSILFunctionType fnType,
8080
irgen::IRGenModule &IGM);
8181

82+
static SILParameterInfo getNewParameter(GenericEnvironment *env,
83+
SILParameterInfo param,
84+
irgen::IRGenModule &IGM);
85+
8286
static bool shouldTransformParameter(GenericEnvironment *env,
8387
SILParameterInfo param,
8488
irgen::IRGenModule &IGM) {
85-
SILType storageType = param.getSILStorageType();
86-
87-
// FIXME: only function types and not recursively-transformable types?
88-
if (auto fnType = storageType.getAs<SILFunctionType>())
89-
return shouldTransformFunctionType(env, fnType, IGM);
9089

91-
switch (param.getConvention()) {
92-
case ParameterConvention::Indirect_In_Guaranteed:
93-
case ParameterConvention::Indirect_Inout:
94-
case ParameterConvention::Indirect_InoutAliasable:
95-
case ParameterConvention::Indirect_In:
96-
return false;
97-
default:
98-
return isLargeLoadableType(env, storageType, IGM);
99-
}
90+
auto newParam = getNewParameter(env, param, IGM);
91+
return (param != newParam);
10092
}
10193

10294
static bool shouldTransformFunctionType(GenericEnvironment *env,
@@ -2464,6 +2456,10 @@ void LoadableByAddress::run() {
24642456
if (isa<ProjectBlockStorageInst>(dest)) {
24652457
storeToBlockStorageInstrs.insert(SI);
24662458
}
2459+
} else if (auto *PAI = dyn_cast<PartialApplyInst>(&I)) {
2460+
if (modApplies.count(PAI) == 0) {
2461+
modApplies.insert(PAI);
2462+
}
24672463
}
24682464
}
24692465
}

lib/SIL/TypeLowering.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,7 +2267,8 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
22672267
/// Given that type1 is known to be a subtype of type2, check if the two
22682268
/// types have the same calling convention representation.
22692269
TypeConverter::ABIDifference
2270-
TypeConverter::checkForABIDifferences(SILType type1, SILType type2) {
2270+
TypeConverter::checkForABIDifferences(SILType type1, SILType type2,
2271+
bool thunkOptionals) {
22712272
// Unwrap optionals, but remember that we did.
22722273
bool type1WasOptional = false;
22732274
bool type2WasOptional = false;
@@ -2280,15 +2281,23 @@ TypeConverter::checkForABIDifferences(SILType type1, SILType type2) {
22802281
type2 = object;
22812282
}
22822283

2283-
// Forcing IUOs always requires a thunk.
2284-
if (type1WasOptional && !type2WasOptional)
2285-
return ABIDifference::NeedsThunk;
2286-
2287-
// Except for the above case, we should not be making a value less optional.
2284+
bool optionalityChange;
2285+
if (thunkOptionals) {
2286+
// Forcing IUOs always requires a thunk.
2287+
if (type1WasOptional && !type2WasOptional)
2288+
return ABIDifference::NeedsThunk;
22882289

2289-
// If we're introducing a level of optionality, only certain types are
2290-
// ABI-compatible -- check below.
2291-
bool optionalityChange = (!type1WasOptional && type2WasOptional);
2290+
// Except for the above case, we should not be making a value less optional.
2291+
2292+
// If we're introducing a level of optionality, only certain types are
2293+
// ABI-compatible -- check below.
2294+
optionalityChange = (!type1WasOptional && type2WasOptional);
2295+
} else {
2296+
// We haven't implemented codegen for optional thunking at all levels
2297+
// (particularly objc_blocks at depth). Just accept ABI compatibility
2298+
// in either direction in these cases.
2299+
optionalityChange = type1WasOptional != type2WasOptional;
2300+
}
22922301

22932302
// If the types are identical and there was no optionality change,
22942303
// we're done.
@@ -2393,7 +2402,8 @@ TypeConverter::checkFunctionForABIDifferences(SILFunctionType *fnTy1,
23932402
return ABIDifference::NeedsThunk;
23942403

23952404
if (checkForABIDifferences(result1.getSILStorageType(),
2396-
result2.getSILStorageType())
2405+
result2.getSILStorageType(),
2406+
/*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
23972407
!= ABIDifference::Trivial)
23982408
return ABIDifference::NeedsThunk;
23992409
}
@@ -2408,7 +2418,8 @@ TypeConverter::checkFunctionForABIDifferences(SILFunctionType *fnTy1,
24082418
return ABIDifference::NeedsThunk;
24092419

24102420
if (checkForABIDifferences(error1.getSILStorageType(),
2411-
error2.getSILStorageType())
2421+
error2.getSILStorageType(),
2422+
/*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
24122423
!= ABIDifference::Trivial)
24132424
return ABIDifference::NeedsThunk;
24142425
}
@@ -2424,7 +2435,8 @@ TypeConverter::checkFunctionForABIDifferences(SILFunctionType *fnTy1,
24242435
std::swap(param1, param2);
24252436

24262437
if (checkForABIDifferences(param1.getSILStorageType(),
2427-
param2.getSILStorageType())
2438+
param2.getSILStorageType(),
2439+
/*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
24282440
!= ABIDifference::Trivial)
24292441
return ABIDifference::NeedsThunk;
24302442
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,12 +2773,13 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
27732773
auto *vd = cast<ParamDecl>(dre->getDecl());
27742774
ManagedValue selfValue;
27752775

2776+
Scope S(SGF, loc);
2777+
Optional<FormalEvaluationScope> FES;
27762778
// If we have not exclusively borrowed self, we need to do so now.
27772779
if (SGF.SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
27782780
// We need to use a full scope here to ensure that any underlying
27792781
// "normal cleanup" borrows are cleaned up.
2780-
Scope S(SGF, loc);
2781-
selfValue = S.popPreservingValue(SGF.emitRValueAsSingleValue(dre));
2782+
selfValue = SGF.emitRValueAsSingleValue(dre);
27822783
} else {
27832784
// If we already exclusively borrowed self, then we need to emit self
27842785
// using formal evaluation primitives.
@@ -2788,6 +2789,7 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
27882789
// This needs to be inlined since there is a Formal Evaluation Scope
27892790
// in emitRValueForDecl that causing any borrow for this LValue to be
27902791
// popped too soon.
2792+
FES.emplace(SGF);
27912793
selfValue =
27922794
SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
27932795
AccessKind::Read, dre->getAccessSemantics());
@@ -2796,9 +2798,7 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
27962798
selfValue.getLValueAddress(), ctx)
27972799
.getAsSingleValue(SGF, loc);
27982800
}
2799-
assert(selfValue && !selfValue.hasCleanup());
28002801

2801-
// Check if we need to perform a conversion here.
28022802
return SGF.B.createValueMetatype(loc, metaTy, selfValue.getValue());
28032803
}
28042804

@@ -2814,7 +2814,6 @@ SILValue SILGenFunction::emitMetatypeOfValue(SILLocation loc, Expr *baseExpr) {
28142814
SGFContext::AllowImmediatePlusZero).getValue();
28152815
return B.createExistentialMetatype(loc, metaTy, base);
28162816
}
2817-
28182817
SILType metaTy = getLoweredLoadableType(CanMetatypeType::get(baseTy));
28192818
// If the lowered metatype has a thick representation, we need to derive it
28202819
// dynamically from the instance.
@@ -2836,7 +2835,6 @@ SILValue SILGenFunction::emitMetatypeOfValue(SILLocation loc, Expr *baseExpr) {
28362835
return S.popPreservingValue(B.createValueMetatype(loc, metaTy, base))
28372836
.getValue();
28382837
}
2839-
28402838
// Otherwise, ignore the base and return the static thin metatype.
28412839
emitIgnoredExpr(baseExpr);
28422840
return B.createMetatype(loc, metaTy);

test/IRGen/big_types_corner_cases.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -enable-large-loadable-types %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
2+
// REQUIRES: optimized_stdlib
23
// UNSUPPORTED: resilient_stdlib
34

45
public struct BigStruct {
@@ -205,3 +206,17 @@ func bigStructGet() -> BigStruct {
205206
public func testGetFunc() {
206207
let testGetPtr: @convention(thin) () -> BigStruct = bigStructGet
207208
}
209+
210+
// CHECK-LABEL: define{{( protected)?}} hidden swiftcc void @_T022big_types_corner_cases7TestBigC4testyyF(%T22big_types_corner_cases7TestBigC* swiftself)
211+
// CHECK: [[CALL1:%.*]] = call %swift.type* @_T0Sayy22big_types_corner_cases9BigStructVcSgGMa
212+
// CHECK: [[CALL2:%.*]] = call i8** @_T0Sayy22big_types_corner_cases9BigStructVcSgGSayxGs10CollectionsWl
213+
// CHECK: call swiftcc void @_T0s10CollectionPsE5index5IndexQzSgSb7ElementQzKc5where_tKF(%TSq.0* noalias nocapture sret %10, i8* bitcast (i1 (%T22big_types_corner_cases9BigStructVytIegir_Sg*, %swift.refcounted*, %swift.error**)* @_T022big_types_corner_cases9BigStructVIegy_SgSbs5Error_pIgxdzo_ACytIegir_SgSbsAE_pIgidzo_TRTA to i8*), %swift.refcounted* %7, %swift.type* %11, i8** [[CALL2]]
214+
// CHECK: ret void
215+
class TestBig {
216+
typealias Handler = (BigStruct) -> Void
217+
218+
func test() {
219+
let arr = [Handler?]()
220+
let d = arr.index(where: { _ in true })
221+
}
222+
}

test/IRGen/coverage_ignored.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -profile-generate -emit-sil -o %t.sil
2+
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir -o - | %FileCheck %s
3+
4+
// CHECK-NOT: llvm.instrprof
5+
// CHECK-NOT: profc
6+
func foo() {}
7+
foo()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@import Foundation;
2+
3+
#pragma clang assume_nonnull begin
4+
typedef void (^HandlerBlock)(NSString *(^message)(void));
5+
#pragma clang assume_nonnull end
6+
7+
/// Default handler for logging.
8+
extern HandlerBlock TheHandlerBlock;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend -emit-silgen -verify %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
import CoreData
6+
7+
@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
8+
class Foo : NSManagedObject {
9+
convenience init(context: NSManagedObjectContext, value: Int) {
10+
self.init(entity: type(of: self).entity(), insertInto: context)
11+
}
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s -import-objc-header %S/Inputs/objc_bridged_block_optionality_diff.h -verify
2+
// REQUIRES: objc_interop
3+
import Foundation
4+
5+
TheHandlerBlock = { x in () }
6+

0 commit comments

Comments
 (0)