Skip to content

Commit 7ac425e

Browse files
committed
---
yaml --- r: 347189 b: refs/heads/master c: f01b166 h: refs/heads/master i: 347187: 3087d9d
1 parent 034fc18 commit 7ac425e

File tree

4 files changed

+144
-50
lines changed

4 files changed

+144
-50
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 42042b6e9ddeac21e1048a969bcdd85e73e8d5b7
2+
refs/heads/master: f01b166f3dcfc7230dcc3ecf45be3bb0cbd059dd
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/IRGen/IRGen.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -881,14 +881,11 @@ struct LLVMCodeGenThreads {
881881
#ifdef __APPLE__
882882
pthread_t threadId;
883883
#else
884-
std::thread *thread;
884+
std::thread thread;
885885
#endif
886886

887887
Thread(LLVMCodeGenThreads &parent, unsigned threadIndex)
888888
: parent(parent), threadIndex(threadIndex)
889-
#ifndef __APPLE__
890-
, thread(nullptr)
891-
#endif
892889
{}
893890

894891
/// Run llvm codegen.
@@ -952,7 +949,7 @@ struct LLVMCodeGenThreads {
952949
pthread_attr_destroy(&stackSizeAttribute);
953950
#else
954951
for (auto &thread : threads) {
955-
thread.thread = new std::thread(runThread, &thread);
952+
thread.thread = std::thread(runThread, &thread);
956953
}
957954
#endif
958955

@@ -969,8 +966,7 @@ struct LLVMCodeGenThreads {
969966
pthread_join(thread.threadId, 0);
970967
#else
971968
for (auto &thread: threads) {
972-
thread.thread->join();
973-
delete thread.thread;
969+
thread.thread.join();
974970
}
975971
#endif
976972
}

trunk/lib/IRGen/LoadableByAddress.cpp

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class LargeSILTypeMapper {
8181
ArrayRef<SILResultInfo> origResults,
8282
irgen::IRGenModule &Mod);
8383
bool shouldConvertBBArg(SILArgument *arg, irgen::IRGenModule &Mod);
84+
bool containsDifferentFunctionSignature(GenericEnvironment *genEnv,
85+
irgen::IRGenModule &Mod,
86+
SILType storageType,
87+
SILType newSILType);
8488

8589
private:
8690
// Cache of already computed type transforms
@@ -153,20 +157,44 @@ bool LargeSILTypeMapper::shouldTransformFunctionType(GenericEnvironment *env,
153157
return false;
154158
}
155159

156-
static bool containsFunctionSignature(GenericEnvironment *genEnv,
157-
irgen::IRGenModule &Mod,
158-
SILType storageType, SILType newSILType) {
159-
if (!isLargeLoadableType(genEnv, storageType, Mod) &&
160-
(newSILType != storageType)) {
160+
// Get the function type or the optional function type
161+
static CanSILFunctionType getInnerFunctionType(SILType storageType) {
162+
if (auto currSILFunctionType = storageType.getAs<SILFunctionType>()) {
163+
return currSILFunctionType;
164+
}
165+
if (auto optionalType = storageType.getOptionalObjectType()) {
166+
if (auto currSILFunctionType = optionalType.getAs<SILFunctionType>()) {
167+
return currSILFunctionType;
168+
}
169+
}
170+
return CanSILFunctionType();
171+
}
172+
173+
static SILType getNonOptionalType(SILType t) {
174+
SILType nonOptionalType = t;
175+
if (auto optType = t.getOptionalObjectType()) {
176+
nonOptionalType = optType;
177+
}
178+
return nonOptionalType;
179+
}
180+
181+
bool LargeSILTypeMapper::containsDifferentFunctionSignature(
182+
GenericEnvironment *genEnv, irgen::IRGenModule &Mod, SILType storageType,
183+
SILType newSILType) {
184+
if (storageType == newSILType) {
185+
return false;
186+
}
187+
if (getInnerFunctionType(storageType)) {
161188
return true;
162189
}
163-
if (auto origType = storageType.getAs<TupleType>()) {
164-
for (auto canElem : origType.getElementTypes()) {
165-
SILType objectType = SILType::getPrimitiveObjectType(canElem);
166-
if (auto optionalObject = objectType.getOptionalObjectType()) {
167-
objectType = optionalObject;
168-
}
169-
if (objectType.is<SILFunctionType>()) {
190+
SILType nonOptionalType = getNonOptionalType(storageType);
191+
if (nonOptionalType.getAs<TupleType>()) {
192+
auto origType = nonOptionalType.getAs<TupleType>();
193+
for (TupleTypeElt canElem : origType->getElements()) {
194+
auto origCanType = CanType(canElem.getRawType());
195+
auto elem = SILType::getPrimitiveObjectType(origCanType);
196+
auto newElem = getNewSILType(genEnv, elem, Mod);
197+
if (containsDifferentFunctionSignature(genEnv, Mod, elem, newElem)) {
170198
return true;
171199
}
172200
}
@@ -182,7 +210,8 @@ bool LargeSILTypeMapper::newResultsDiffer(GenericEnvironment *GenericEnv,
182210
SILType currResultTy = result.getSILStorageType();
183211
SILType newSILType = getNewSILType(GenericEnv, currResultTy, Mod);
184212
// We (currently) only care about function signatures
185-
if (containsFunctionSignature(GenericEnv, Mod, currResultTy, newSILType)) {
213+
if (containsDifferentFunctionSignature(GenericEnv, Mod, currResultTy,
214+
newSILType)) {
186215
return true;
187216
}
188217
}
@@ -218,16 +247,16 @@ LargeSILTypeMapper::getNewResults(GenericEnvironment *GenericEnv,
218247
for (auto result : origResults) {
219248
SILType currResultTy = result.getSILStorageType();
220249
SILType newSILType = getNewSILType(GenericEnv, currResultTy, Mod);
221-
// We (currently) only care about function signatures
222-
if (containsFunctionSignature(GenericEnv, Mod, currResultTy, newSILType)) {
223-
// Case (1) Above
224-
SILResultInfo newResult(newSILType.getASTType(), result.getConvention());
225-
newResults.push_back(newResult);
226-
} else if (modNonFuncTypeResultType(GenericEnv, fnType, Mod)) {
250+
if (modNonFuncTypeResultType(GenericEnv, fnType, Mod)) {
227251
// Case (2) Above
228252
SILResultInfo newSILResultInfo(newSILType.getASTType(),
229253
ResultConvention::Indirect);
230254
newResults.push_back(newSILResultInfo);
255+
} else if (containsDifferentFunctionSignature(GenericEnv, Mod, currResultTy,
256+
newSILType)) {
257+
// Case (1) Above
258+
SILResultInfo newResult(newSILType.getASTType(), result.getConvention());
259+
newResults.push_back(newResult);
231260
} else {
232261
newResults.push_back(result);
233262
}
@@ -259,19 +288,6 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env,
259288
return newFnType;
260289
}
261290

262-
// Get the function type or the optional function type
263-
static CanSILFunctionType getInnerFunctionType(SILType storageType) {
264-
if (auto currSILFunctionType = storageType.getAs<SILFunctionType>()) {
265-
return currSILFunctionType;
266-
}
267-
if (auto optionalType = storageType.getOptionalObjectType()) {
268-
if (auto currSILFunctionType = optionalType.getAs<SILFunctionType>()) {
269-
return currSILFunctionType;
270-
}
271-
}
272-
return CanSILFunctionType();
273-
}
274-
275291
SILType
276292
LargeSILTypeMapper::getNewOptionalFunctionType(GenericEnvironment *GenericEnv,
277293
SILType storageType,
@@ -540,6 +556,11 @@ struct StructLoweringState {
540556
return Mapper.getNewSILType(F->getGenericEnvironment(), type, Mod);
541557
}
542558

559+
bool containsDifferentFunctionSignature(SILType type) {
560+
return Mapper.containsDifferentFunctionSignature(
561+
F->getGenericEnvironment(), Mod, type, getNewSILType(type));
562+
}
563+
543564
bool hasLargeLoadableYields() {
544565
auto fnType = F->getLoweredFunctionType();
545566
if (!fnType->isCoroutine()) return false;
@@ -819,7 +840,8 @@ bool LargeSILTypeMapper::shouldConvertBBArg(SILArgument *arg,
819840
}
820841
SILType newSILType = getNewSILType(genEnv, storageType, Mod);
821842
// We (currently) only care about function signatures
822-
if (containsFunctionSignature(genEnv, Mod, storageType, newSILType)) {
843+
if (containsDifferentFunctionSignature(genEnv, Mod, storageType,
844+
newSILType)) {
823845
return true;
824846
}
825847
return false;
@@ -1347,15 +1369,16 @@ void LoadableStorageAllocation::insertIndirectReturnArgs() {
13471369
canType = genEnv->mapTypeIntoContext(canType)->getCanonicalType();
13481370
}
13491371
resultStorageType = SILType::getPrimitiveObjectType(canType);
1372+
auto newResultStorageType = pass.getNewSILType(resultStorageType);
13501373

13511374
auto &ctx = pass.F->getModule().getASTContext();
13521375
auto var = new (ctx) ParamDecl(
13531376
VarDecl::Specifier::InOut, SourceLoc(), SourceLoc(),
13541377
ctx.getIdentifier("$return_value"), SourceLoc(),
13551378
ctx.getIdentifier("$return_value"),
13561379
pass.F->getDeclContext());
1357-
pass.F->begin()->insertFunctionArgument(0, resultStorageType.getAddressType(),
1358-
ValueOwnershipKind::Any, var);
1380+
pass.F->begin()->insertFunctionArgument(
1381+
0, newResultStorageType.getAddressType(), ValueOwnershipKind::Any, var);
13591382
}
13601383

13611384
void LoadableStorageAllocation::convertIndirectFunctionArgs() {
@@ -1467,9 +1490,8 @@ void LoadableStorageAllocation::
14671490

14681491
for (SILArgument *arg : entry->getArguments()) {
14691492
SILType storageType = arg->getType();
1470-
GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
14711493
SILType newSILType = pass.getNewSILType(storageType);
1472-
if (containsFunctionSignature(genEnv, pass.Mod, storageType, newSILType)) {
1494+
if (pass.containsDifferentFunctionSignature(storageType)) {
14731495
auto *castInstr = argBuilder.createUncheckedBitCast(
14741496
RegularLocation(const_cast<ValueDecl *>(arg->getDecl())), arg,
14751497
newSILType);
@@ -1493,6 +1515,12 @@ void LoadableStorageAllocation::convertIndirectBasicBlockArgs() {
14931515
}
14941516
SILType storageType = arg->getType();
14951517
SILType newSILType = pass.getNewSILType(storageType);
1518+
// We don't change the type from object to address for function args:
1519+
// a tuple with both a large type and a function arg should remain
1520+
// as an object type for now
1521+
if (storageType.isObject()) {
1522+
newSILType = newSILType.getObjectType();
1523+
}
14961524
convertBBArgType(argBuilder, newSILType, arg);
14971525
}
14981526
}
@@ -2238,18 +2266,14 @@ static void rewriteFunction(StructLoweringState &pass,
22382266
// If it is a large type also return true - will be re-written later
22392267
// Returns true if the return argument needed re-writing
22402268
static bool rewriteFunctionReturn(StructLoweringState &pass) {
2241-
GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
22422269
auto loweredTy = pass.F->getLoweredFunctionType();
22432270
SILFunction *F = pass.F;
22442271
SILType resultTy = loweredTy->getAllResultsType();
22452272
SILType newSILType = pass.getNewSILType(resultTy);
22462273
// We (currently) only care about function signatures
22472274
if (pass.isLargeLoadableType(resultTy)) {
22482275
return true;
2249-
} else if (containsFunctionSignature(genEnv, pass.Mod, resultTy,
2250-
newSILType) &&
2251-
(resultTy != newSILType)) {
2252-
2276+
} else if (pass.containsDifferentFunctionSignature(resultTy)) {
22532277
llvm::SmallVector<SILResultInfo, 2> newSILResultInfo;
22542278
if (auto tupleType = newSILType.getAs<TupleType>()) {
22552279
auto originalResults = loweredTy->getResults();
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %swift -c -primary-file %s -enable-large-loadable-types -Xllvm -sil-print-after=loadable-address -sil-verify-all -o %t/big_types_generic.o 2>&1 | %FileCheck %s
3+
4+
struct Big<T> {
5+
var a0 : T
6+
var a1 : T
7+
var a2 : T
8+
var a3 : T
9+
var a4 : T
10+
var a5 : T
11+
var a6 : T
12+
var a7 : T
13+
var a8 : T
14+
init(_ t: T) {
15+
a0 = t
16+
a1 = t
17+
a2 = t
18+
a3 = t
19+
a4 = t
20+
a5 = t
21+
a6 = t
22+
a7 = t
23+
a8 = t
24+
}
25+
}
26+
27+
// CHECK-LABEL: sil hidden @$s17big_types_generic10nonGenericAA3BigVys5Int32VG_AGt_AGyctSgyF : $@convention(thin) () -> @out Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>
28+
// CHECK: bb0(%0 : $*Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>):
29+
// CHECK: [[ENUMCONSTRUCT:%.*]] = enum $Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>, #Optional.none!enumelt
30+
// CHECK: store [[ENUMCONSTRUCT]] to %0 : $*Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>
31+
// CHECK: return %{{.*}} : $()
32+
// CHECK-LABEL: } // end sil function '$s17big_types_generic10nonGenericAA3BigVys5Int32VG_AGt_AGyctSgyF'
33+
func nonGeneric() -> ((Big<Int32>, Big<Int32>), () -> Big<Int32>)? {
34+
return nil
35+
}
36+
37+
// CHECK-LABEL: sil hidden @$s17big_types_generic11nonGeneric2AA3BigVys5Int32VG_AGt_AGyctyF : $@convention(thin) () -> (Big<Int32>, Big<Int32>, @owned @callee_guaranteed () -> @out Big<Int32>)
38+
// CHECK: bb0:
39+
// CHECK: [[TUPLECONSTRUCT:%.*]] = tuple (%{{.*}} : $Big<Int32>, %{{.*}} : $Big<Int32>, %{{.*}} : $@callee_guaranteed () -> @out Big<Int32>)
40+
// CHECK: return [[TUPLECONSTRUCT]]
41+
// CHECK-LABEL: } // end sil function '$s17big_types_generic11nonGeneric2AA3BigVys5Int32VG_AGt_AGyctyF'
42+
func nonGeneric2() -> ((Big<Int32>, Big<Int32>), () -> Big<Int32>) {
43+
return ((Big(1), Big(2)), { return Big(1) })
44+
}
45+
46+
func generic<T>(_ t: T) -> ((Big<T>, Big<T>), () -> Big<T>)? {
47+
return nil
48+
}
49+
50+
func generic2<T>(_ t: T) -> ((Big<T>, Big<T>), () -> Big<T>) {
51+
return ((Big(t), Big(t)), { return Big(t) })
52+
}
53+
54+
// CHECK-LABEL: sil hidden @$s17big_types_generic8useStuffyyF : $@convention(thin) () -> ()
55+
// CHECK: bb0:
56+
// CHECK: switch_enum_addr %{{.*}} : $*Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>, case #Optional.some!enumelt.1: bb7, case #Optional.none!enumelt: bb1
57+
// CHECK: bb7:
58+
// CHECK: switch_enum_addr %{{.*}} : $*Optional<((Big<Int32>, Big<Int32>), @callee_guaranteed () -> @out Big<Int32>)>, case #Optional.some!enumelt.1: bb14, case #Optional.none!enumelt: bb8
59+
// CHECK: bb14:
60+
// CHECK: bb17(%{{.*}} : $Optional<((Big<Int>, Big<Int>), @callee_guaranteed () -> @out Big<Int>)>):
61+
// CHECK: switch_enum %{{.*}} : $Optional<((Big<Int>, Big<Int>), @callee_guaranteed () -> @out Big<Int>)>, case #Optional.some!enumelt.1: bb24, case #Optional.none!enumelt: bb18
62+
// CHECK: bb24(%{{.*}} : $((Big<Int>, Big<Int>), @callee_guaranteed () -> @out Big<Int>)):
63+
// CHECK: return %{{.*}} : $()
64+
// CHECK-LABEL: } // end sil function '$s17big_types_generic8useStuffyyF'
65+
func useStuff() {
66+
print(nonGeneric()!.0)
67+
print(nonGeneric()!.1)
68+
print(nonGeneric2().0)
69+
print(nonGeneric2().1)
70+
print(generic(1)!.0.0)
71+
print(generic(1)!.1)
72+
print(generic2(1).0)
73+
print(generic2(1).1)
74+
}

0 commit comments

Comments
 (0)