Skip to content

Commit ad6e111

Browse files
authored
---
yaml --- r: 349117 b: refs/heads/master c: 443d6f7 h: refs/heads/master i: 349115: 0b1b2ee
1 parent 8412047 commit ad6e111

File tree

18 files changed

+411
-17
lines changed

18 files changed

+411
-17
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: d6fe1e9d39c99fb5dfc5411ab5c7e82344ecc180
2+
refs/heads/master: 443d6f7c300d0bfa1a215669e41bc5411f935c42
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/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,10 @@ option(SWIFT_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING
377377
"Build stdlibCore with exclusivity checking enabled"
378378
FALSE)
379379

380+
option(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING
381+
"Enable experimental Swift differentiable programming features"
382+
FALSE)
383+
380384
#
381385
# End of user-configurable options.
382386
#

trunk/benchmark/single-source/UTF8Decode.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ public let UTF8Decode = [
4242
name: "UTF8Decode_InitFromBytes_ascii",
4343
runFunction: run_UTF8Decode_InitFromBytes_ascii,
4444
tags: [.validation, .api, .String]),
45+
BenchmarkInfo(
46+
name: "UTF8Decode_InitFromData_ascii_as_ascii",
47+
runFunction: run_UTF8Decode_InitFromData_ascii_as_ascii,
48+
tags: [.validation, .api, .String]),
49+
BenchmarkInfo(
50+
name: "UTF8Decode_InitDecoding_ascii_as_ascii",
51+
runFunction: run_UTF8Decode_InitDecoding_ascii_as_ascii,
52+
tags: [.validation, .api, .String]),
53+
BenchmarkInfo(
54+
name: "UTF8Decode_InitFromBytes_ascii_as_ascii",
55+
runFunction: run_UTF8Decode_InitFromBytes_ascii_as_ascii,
56+
tags: [.validation, .api, .String]),
4557
]
4658

4759
// 1-byte sequences
@@ -129,4 +141,26 @@ public func run_UTF8Decode_InitFromBytes_ascii(_ N: Int) {
129141
}
130142
}
131143

144+
@inline(never)
145+
public func run_UTF8Decode_InitFromData_ascii_as_ascii(_ N: Int) {
146+
let input = asciiData
147+
for _ in 0..<1_000*N {
148+
blackHole(String(data: input, encoding: .ascii))
149+
}
150+
}
151+
@inline(never)
152+
public func run_UTF8Decode_InitDecoding_ascii_as_ascii(_ N: Int) {
153+
let input = asciiBytes
154+
for _ in 0..<1_000*N {
155+
blackHole(String(decoding: input, as: Unicode.ASCII.self))
156+
}
157+
}
158+
@inline(never)
159+
public func run_UTF8Decode_InitFromBytes_ascii_as_ascii(_ N: Int) {
160+
let input = asciiBytes
161+
for _ in 0..<1_000*N {
162+
blackHole(String(bytes: input, encoding: .ascii))
163+
}
164+
}
165+
132166

trunk/cmake/modules/AddSwift.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,10 @@ function(_add_variant_swift_compile_flags
422422
list(APPEND result "-D" "SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS")
423423
endif()
424424

425+
if(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING)
426+
list(APPEND result "-D" "SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING")
427+
endif()
428+
425429
set("${result_var_name}" "${result}" PARENT_SCOPE)
426430
endfunction()
427431

trunk/include/swift/SIL/SILConstants.h

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct DerivedAddressValue;
3333
struct EnumWithPayloadSymbolicValue;
3434
struct SymbolicValueMemoryObject;
3535
struct UnknownSymbolicValue;
36+
struct SymbolicClosure;
3637

3738
extern llvm::cl::opt<unsigned> ConstExprLimit;
3839

@@ -261,6 +262,9 @@ class SymbolicValue {
261262

262263
/// This represents an array.
263264
RK_Array,
265+
266+
/// This represents a closure.
267+
RK_Closure,
264268
};
265269

266270
union {
@@ -305,7 +309,7 @@ class SymbolicValue {
305309
/// information about the memory object and access path of the access.
306310
DerivedAddressValue *derivedAddress;
307311

308-
// The following fields are for representing an Array.
312+
// The following two fields are for representing an Array.
309313
//
310314
// In Swift, an array is a non-trivial struct that stores a reference to an
311315
// internal storage: _ContiguousArrayStorage. Though arrays have value
@@ -329,6 +333,10 @@ class SymbolicValue {
329333
/// When this symbolic value is of an "Array" kind, this stores a memory
330334
/// object that contains a SymbolicArrayStorage value.
331335
SymbolicValueMemoryObject *array;
336+
337+
/// When this symbolic value is of "Closure" kind, store a pointer to the
338+
/// symbolic representation of the closure.
339+
SymbolicClosure *closure;
332340
} value;
333341

334342
RepresentationKind representationKind : 8;
@@ -384,6 +392,9 @@ class SymbolicValue {
384392
/// This represents an array value.
385393
Array,
386394

395+
/// This represents a closure.
396+
Closure,
397+
387398
/// These values are generally only seen internally to the system, external
388399
/// clients shouldn't have to deal with them.
389400
UninitMemory
@@ -533,6 +544,22 @@ class SymbolicValue {
533544
/// Return the type of this array symbolic value.
534545
Type getArrayType() const;
535546

547+
/// Create and return a symbolic value that represents a closure.
548+
/// \param target SILFunction corresponding the target of the closure.
549+
/// \param capturedArguments an array consisting of SILValues of captured
550+
/// arguments along with their symbolic values when available.
551+
/// \param allocator the allocator to use for storing the contents of this
552+
/// symbolic value.
553+
static SymbolicValue makeClosure(
554+
SILFunction *target,
555+
ArrayRef<std::pair<SILValue, Optional<SymbolicValue>>> capturedArguments,
556+
SymbolicValueAllocator &allocator);
557+
558+
SymbolicClosure *getClosure() const {
559+
assert(getKind() == Closure);
560+
return value.closure;
561+
}
562+
536563
//===--------------------------------------------------------------------===//
537564
// Helpers
538565

@@ -607,6 +634,57 @@ struct SymbolicValueMemoryObject {
607634
SymbolicValueMemoryObject(const SymbolicValueMemoryObject &) = delete;
608635
void operator=(const SymbolicValueMemoryObject &) = delete;
609636
};
637+
638+
using SymbolicClosureArgument = std::pair<SILValue, Optional<SymbolicValue>>;
639+
640+
/// Representation of a symbolic closure. A symbolic closure consists of a
641+
/// SILFunction and an array of SIL values, corresponding to the captured
642+
/// arguments, and (optional) symbolic values representing the constant values
643+
/// of the captured arguments. The symbolic values are optional as it is not
644+
/// necessary for every captured argument to be a constant, which enables
645+
/// representing closures whose captured arguments are not compile-time
646+
/// constants.
647+
struct SymbolicClosure final
648+
: private llvm::TrailingObjects<SymbolicClosure, SymbolicClosureArgument> {
649+
650+
friend class llvm::TrailingObjects<SymbolicClosure, SymbolicClosureArgument>;
651+
652+
private:
653+
654+
SILFunction *target;
655+
656+
// The number of SIL values captured by the closure.
657+
unsigned numCaptures;
658+
659+
// True iff there exists captured arguments whose constant value is not known.
660+
bool hasNonConstantCaptures = true;
661+
662+
SymbolicClosure() = delete;
663+
SymbolicClosure(const SymbolicClosure &) = delete;
664+
SymbolicClosure(SILFunction *callee, unsigned numArguments,
665+
bool nonConstantCaptures)
666+
: target(callee), numCaptures(numArguments),
667+
hasNonConstantCaptures(nonConstantCaptures) {}
668+
669+
public:
670+
static SymbolicClosure *create(SILFunction *callee,
671+
ArrayRef<SymbolicClosureArgument> args,
672+
SymbolicValueAllocator &allocator);
673+
674+
ArrayRef<SymbolicClosureArgument> getCaptures() const {
675+
return {getTrailingObjects<SymbolicClosureArgument>(), numCaptures};
676+
}
677+
678+
// This is used by the llvm::TrailingObjects base class.
679+
size_t numTrailingObjects(OverloadToken<SymbolicClosureArgument>) const {
680+
return numCaptures;
681+
}
682+
683+
SILFunction *getTarget() {
684+
return target;
685+
}
686+
};
687+
610688
} // end namespace swift
611689

612690
#endif

trunk/lib/SIL/SILConstants.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,29 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
126126
case RK_Array: {
127127
os << getArrayType() << ": \n";
128128
getStorageOfArray().print(os, indent);
129+
return;
130+
}
131+
case RK_Closure: {
132+
SymbolicClosure *clo = getClosure();
133+
SILFunction *target = clo->getTarget();
134+
std::string targetName = target->getName();
135+
os << "closure: target: " << targetName;
136+
ArrayRef<SymbolicClosureArgument> args = clo->getCaptures();
137+
os << " captures [\n";
138+
for (SymbolicClosureArgument closureArg : args) {
139+
os.indent(indent + 2) << closureArg.first << "\n";
140+
}
141+
os.indent(indent) << "] values: [\n";
142+
for (SymbolicClosureArgument closureArg : args) {
143+
Optional<SymbolicValue> value = closureArg.second;
144+
if (!value.hasValue()) {
145+
os.indent(indent + 2) << "nil\n";
146+
continue;
147+
}
148+
value->print(os, indent + 2);
149+
}
150+
os.indent(indent) << "]\n";
151+
return;
129152
}
130153
}
131154
}
@@ -162,6 +185,8 @@ SymbolicValue::Kind SymbolicValue::getKind() const {
162185
return ArrayStorage;
163186
case RK_Array:
164187
return Array;
188+
case RK_Closure:
189+
return Closure;
165190
}
166191
llvm_unreachable("covered switch");
167192
}
@@ -219,6 +244,11 @@ SymbolicValue::cloneInto(SymbolicValueAllocator &allocator) const {
219244
SymbolicValue clonedStorage = getStorageOfArray().cloneInto(allocator);
220245
return getArray(getArrayType(), clonedStorage, allocator);
221246
}
247+
case RK_Closure: {
248+
SymbolicClosure *clo = getClosure();
249+
ArrayRef<SymbolicClosureArgument> closureArgs = clo->getCaptures();
250+
return SymbolicValue::makeClosure(clo->getTarget(), closureArgs, allocator);
251+
}
222252
}
223253
llvm_unreachable("covered switch");
224254
}
@@ -661,6 +691,44 @@ Type SymbolicValue::getArrayType() const {
661691
return value.array->getType();
662692
}
663693

694+
//===----------------------------------------------------------------------===//
695+
// Symbolic Closure
696+
//===----------------------------------------------------------------------===//
697+
698+
SymbolicValue SymbolicValue::makeClosure(SILFunction *target,
699+
ArrayRef<SymbolicClosureArgument> args,
700+
SymbolicValueAllocator &allocator) {
701+
auto clo = SymbolicClosure::create(target, args, allocator);
702+
SymbolicValue result;
703+
result.representationKind = RK_Closure;
704+
result.value.closure = clo;
705+
return result;
706+
}
707+
708+
SymbolicClosure *SymbolicClosure::create(SILFunction *target,
709+
ArrayRef<SymbolicClosureArgument> args,
710+
SymbolicValueAllocator &allocator) {
711+
// Determine whether there are captured arguments without a symbolic value.
712+
bool hasNonConstantCapture = false;
713+
for (SymbolicClosureArgument closureArg : args) {
714+
if (!closureArg.second) {
715+
hasNonConstantCapture = true;
716+
break;
717+
}
718+
}
719+
720+
auto byteSizeOfArgs =
721+
SymbolicClosure::totalSizeToAlloc<SymbolicClosureArgument>(args.size());
722+
auto rawMem = allocator.allocate(byteSizeOfArgs, alignof(SymbolicClosure));
723+
// Placement initialize the object.
724+
auto closure = ::new (rawMem)
725+
SymbolicClosure(target, args.size(), hasNonConstantCapture);
726+
std::uninitialized_copy(
727+
args.begin(), args.end(),
728+
closure->getTrailingObjects<SymbolicClosureArgument>());
729+
return closure;
730+
}
731+
664732
//===----------------------------------------------------------------------===//
665733
// Higher level code
666734
//===----------------------------------------------------------------------===//

trunk/lib/SILOptimizer/Utils/ConstExpr.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,36 @@ ConstExprFunctionState::evaluateFlowSensitive(SILInstruction *inst) {
16301630
injectEnumInst->getOperand());
16311631
}
16321632

1633+
if (auto *papply = dyn_cast<PartialApplyInst>(inst)) {
1634+
SILValue calleeOperand = papply->getOperand(0);
1635+
SymbolicValue calleeValue = getConstantValue(calleeOperand);
1636+
if (!calleeValue.isConstant())
1637+
return calleeValue;
1638+
if (calleeValue.getKind() != SymbolicValue::Function) {
1639+
return getUnknown(evaluator, (SILInstruction *)papply,
1640+
UnknownReason::InvalidOperandValue);
1641+
}
1642+
1643+
SILFunction *target = calleeValue.getFunctionValue();
1644+
assert(target != nullptr);
1645+
1646+
// Arguments to this partial-apply instruction are the captures of the
1647+
// closure.
1648+
SmallVector<SymbolicClosureArgument, 4> captures;
1649+
for (SILValue argument : papply->getArguments()) {
1650+
SymbolicValue argumentValue = getConstantValue(argument);
1651+
if (!argumentValue.isConstant()) {
1652+
captures.push_back({ argument, None });
1653+
continue;
1654+
}
1655+
captures.push_back({ argument, argumentValue });
1656+
}
1657+
auto closureVal = SymbolicValue::makeClosure(target, captures,
1658+
evaluator.getAllocator());
1659+
setValue(papply, closureVal);
1660+
return None;
1661+
}
1662+
16331663
// If the instruction produces a result, try computing it, and fail if the
16341664
// computation fails.
16351665
if (auto *singleValueInst = dyn_cast<SingleValueInstruction>(inst)) {
@@ -1934,6 +1964,8 @@ ConstExprStepEvaluator::skipByMakingEffectsNonConstant(
19341964
constKind == SymbolicValue::Aggregate ||
19351965
constKind == SymbolicValue::Enum ||
19361966
constKind == SymbolicValue::EnumWithPayload ||
1967+
constKind == SymbolicValue::Array ||
1968+
constKind == SymbolicValue::Closure ||
19371969
constKind == SymbolicValue::UninitMemory);
19381970

19391971
if (constKind != SymbolicValue::Address) {

trunk/lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/ExistentialLayout.h"
2121
#include "swift/AST/GenericEnvironment.h"
2222
#include "swift/AST/GenericSignature.h"
23+
#include "swift/AST/Initializer.h"
2324
#include "swift/AST/ParameterList.h"
2425
#include "swift/AST/PropertyWrappers.h"
2526
#include "swift/AST/ProtocolConformance.h"
@@ -4864,7 +4865,19 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
48644865
// reasonable choice.
48654866
auto addChoice = [&](OverloadChoice candidate) {
48664867
auto decl = candidate.getDecl();
4867-
4868+
4869+
// In a pattern binding initializer, immediately reject all of its bound
4870+
// variables. These would otherwise allow circular references.
4871+
if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC)) {
4872+
if (auto *VD = dyn_cast<VarDecl>(decl)) {
4873+
if (PBI->getBinding() == VD->getParentPatternBinding()) {
4874+
result.addUnviable(candidate,
4875+
MemberLookupResult::UR_InstanceMemberOnType);
4876+
return;
4877+
}
4878+
}
4879+
}
4880+
48684881
// If the result is invalid, skip it.
48694882
// FIXME(InterfaceTypeRequest): isInvalid() should be based on the interface type.
48704883
(void)decl->getInterfaceType();

trunk/stdlib/public/core/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ set(SWIFTLIB_ESSENTIAL_GYB_SOURCES
196196
UnsafeRawBufferPointer.swift.gyb
197197
)
198198

199+
# Compile differentiable programming sources only if enabled.
200+
set(SWIFTLIB_DIFFERENTIABLE_PROGRAMMING_SOURCES)
201+
if(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING)
202+
# TODO: Add `_Differentiable` protocol.
203+
message(STATUS "Differentiable programming standard library additions enabled.")
204+
endif()
205+
199206
# The complete list of sources in the core standard library. Includes
200207
# all the essential sources listed above.
201208
set(SWIFTLIB_SOURCES
@@ -214,6 +221,7 @@ set(SWIFTLIB_SOURCES
214221
VarArgs.swift
215222
Zip.swift
216223
"${SWIFT_SOURCE_DIR}/stdlib/linker-support/magic-symbols-for-install-name.c"
224+
${SWIFTLIB_DIFFERENTIABLE_PROGRAMMING_SOURCES}
217225
)
218226

219227
set(SWIFTLIB_GYB_SOURCES

0 commit comments

Comments
 (0)