Skip to content

Commit 019043e

Browse files
committed
Merge remote-tracking branch 'github/master' into HEAD
2 parents c8c04fa + 66e8572 commit 019043e

38 files changed

+541
-208
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ First, create a directory for all of the Swift sources:
165165
**Note:** This is important since update-checkout (see below) checks out
166166
repositories next to the Swift source directory. This means that if one clones
167167
Swift and has other unrelated repositories, update-checkout may not clone those
168-
repositories and will update them instead. Additionally, ensure Python 2.7 is being
169-
used for this step, whether via conda environment or other means.
168+
repositories and will update them instead. Be aware that `update-checkout`
169+
currently does not support paths with non-ASCII characters. If such characters
170+
are present in the path to `swift-source`, `update-checkout` will fail.
170171

171172
**TensorFlow Support:** To build with TensorFlow support, the `tensorflow`
172173
scheme must be specified when cloning sources. The `tensorflow` scheme pins

docs/DebuggingTheCompiler.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,17 @@ it's quite easy to do this manually:
548548

549549
a. Add the compiler option ``-Xllvm -sil-opt-pass-count=<n>``, where ``<n>``
550550
is the number of optimizations to run.
551-
b. Bisect: find n where the executable crashes, but does not crash with n-1.
552-
Note that n can be quite large, e.g. > 100000 (just try
553-
n = 10, 100, 1000, 10000, etc. to find an upper bound).
554-
c. Add another option ``-Xllvm -sil-print-pass-name``. The output can be
551+
552+
b. Bisect: find n where the executable crashes, but does not crash
553+
with n-1. First just try n = 10, 100, 1000, 10000, etc. to find
554+
an upper bound). Then can either bisect the invocation by hand or
555+
place the invocation into a script and use
556+
``./llvm-project/llvm/utils/bisect`` to automatically bisect
557+
based on the scripts error code. Example invocation::
558+
559+
bisect --start=0 --end=10000 ./invoke_swift_passing_N.sh "%(count)s"
560+
561+
c. Once one finds ``n``, Add another option ``-Xllvm -sil-print-pass-name``. The output can be
555562
large, so it's best to redirect stderr to a file (``2> output``).
556563
In the output search for the last pass before ``stage Address Lowering``.
557564
It should be the ``Run #<n-1>``. This line tells you the name of the bad

docs/DevelopmentTips.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,25 @@ Given the size of artifacts generated, you might also want to bump the cache siz
4141
You can run some compiles to see if it is actually doing something by running `sccache --show-stats`. Depending on the exact compilation task you're running, you might see very different cache hit rates. For example, `sccache` is particularly effective if you're rebuilding LLVM, which doesn't change so frequently from the Swift compiler's perspective. On the other hand, if you're changing the compiler's AST, the cache hit rate is likely to be much lower.
4242

4343
One known issue with `sccache` is that you might occassionally get an "error: Connection to server timed out", even though you didn't stop the server. Simply re-running the build command usually works.
44+
45+
## Memory usage
46+
47+
When building Swift, peak memory usage happens during the linking phases that produce llvm and swift executables. In case your build fails because a process ran out of RAM, you can use one or more of the following techniques to reduce the peak memory usage.
48+
49+
### Reduce the amount of debug symbols
50+
51+
We can use debug symbols for only the part of the project we intend to work on. For example, when working on the compiler itself, we can build with debug symbols enabled only for the compiler:
52+
53+
```
54+
build-script --release --debug-swift
55+
```
56+
57+
### Reduce the number of parallel link jobs
58+
59+
By default, `build-script` will spawn as many parallel compile / link jobs as there are CPUs in the machine. We can reduce the number of parallel link jobs by setting the `LLVM_PARALLEL_LINK_JOBS` and `SWIFT_PARALLEL_LINK_JOBS` CMake properties. We can set them through the `--llvm-cmake-options` and `--swift-cmake-options` arguments to `build-script`.
60+
61+
For example, to have `build-script` spawn only one link job at a time, we can invoke it as:
62+
63+
```
64+
build-script --llvm-cmake-options==-DLLVM_PARALLEL_LINK_JOBS=1 --swift-cmake-options=-DSWIFT_PARALLEL_LINK_JOBS=1
65+
```

include/swift/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5266,7 +5266,7 @@ class VarDecl : public AbstractStorageDecl {
52665266
///
52675267
/// \code
52685268
/// @Lazy var i = 17
5269-
/// \end
5269+
/// \endcode
52705270
///
52715271
/// Or when there is no initializer but each composed property wrapper has
52725272
/// a suitable `init(wrappedValue:)`.

include/swift/AST/Expr.h

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4041,7 +4041,61 @@ class OpaqueValueExpr : public Expr {
40414041
SourceRange getSourceRange() const { return Range; }
40424042

40434043
static bool classof(const Expr *E) {
4044-
return E->getKind() == ExprKind::OpaqueValue;
4044+
return E->getKind() == ExprKind::OpaqueValue;
4045+
}
4046+
};
4047+
4048+
/// A placeholder to substitute with a \c wrappedValue initialization expression
4049+
/// for a property with an attached property wrapper.
4050+
///
4051+
/// Wrapped value placeholder expressions are injected around the
4052+
/// \c wrappedValue argument in a synthesized \c init(wrappedValue:)
4053+
/// call. This injection happens for properties with attached property wrappers
4054+
/// that can be initialized out-of-line with a wrapped value expression, rather
4055+
/// than calling \c init(wrappedValue:) explicitly.
4056+
///
4057+
/// Wrapped value placeholders store the original initialization expression
4058+
/// if one exists, along with an opaque value placeholder that can be bound
4059+
/// to a different wrapped value expression.
4060+
class PropertyWrapperValuePlaceholderExpr : public Expr {
4061+
SourceRange Range;
4062+
OpaqueValueExpr *Placeholder;
4063+
Expr *WrappedValue;
4064+
4065+
PropertyWrapperValuePlaceholderExpr(SourceRange Range, Type Ty,
4066+
OpaqueValueExpr *placeholder,
4067+
Expr *wrappedValue)
4068+
: Expr(ExprKind::PropertyWrapperValuePlaceholder, /*Implicit=*/true, Ty),
4069+
Range(Range), Placeholder(placeholder), WrappedValue(wrappedValue) {}
4070+
4071+
public:
4072+
static PropertyWrapperValuePlaceholderExpr *
4073+
create(ASTContext &ctx, SourceRange range, Type ty, Expr *wrappedValue);
4074+
4075+
/// The original wrappedValue initialization expression provided via
4076+
/// \c = on a proprety with attached property wrappers.
4077+
Expr *getOriginalWrappedValue() const {
4078+
return WrappedValue;
4079+
}
4080+
4081+
void setOriginalWrappedValue(Expr *value) {
4082+
WrappedValue = value;
4083+
}
4084+
4085+
/// An opaque value placeholder that will be used to substitute in a
4086+
/// different wrapped value expression for out-of-line initialization.
4087+
OpaqueValueExpr *getOpaqueValuePlaceholder() const {
4088+
return Placeholder;
4089+
}
4090+
4091+
void setOpaqueValuePlaceholder(OpaqueValueExpr *placeholder) {
4092+
Placeholder = placeholder;
4093+
}
4094+
4095+
SourceRange getSourceRange() const { return Range; }
4096+
4097+
static bool classof(const Expr *E) {
4098+
return E->getKind() == ExprKind::PropertyWrapperValuePlaceholder;
40454099
}
40464100
};
40474101

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ EXPR(VarargExpansion, Expr)
126126
EXPR(DynamicType, Expr)
127127
EXPR(RebindSelfInConstructor, Expr)
128128
EXPR(OpaqueValue, Expr)
129+
EXPR(PropertyWrapperValuePlaceholder, Expr)
129130
EXPR(DefaultArgument, Expr)
130131
EXPR(BindOptional, Expr)
131132
EXPR(OptionalEvaluation, Expr)

include/swift/AST/PropertyWrappers.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ struct PropertyWrapperBackingPropertyInfo {
141141
///
142142
/// \code
143143
/// @Lazy var i = 17
144-
/// \end
144+
/// \endcode
145145
///
146146
/// This is the specified initial value (\c 17), which is suitable for
147147
/// embedding in the expression \c initializeFromOriginal.
@@ -190,12 +190,13 @@ void simple_display(
190190
llvm::raw_ostream &out,
191191
const PropertyWrapperBackingPropertyInfo &backingInfo);
192192

193-
/// Given the initializer for the given property with an attached property
194-
/// wrapper, dig out the original initialization expression.
193+
/// Given the initializer for a property with an attached property wrapper,
194+
/// dig out the wrapped value placeholder for the original initialization
195+
/// expression.
195196
///
196-
/// Cannot just dig out the getOriginalInit() value because this function checks
197-
/// types, etc. Erroneous code won't return a result from here.
198-
Expr *findOriginalPropertyWrapperInitialValue(VarDecl *var, Expr *init);
197+
/// \note The wrapped value placeholder is injected for properties that can
198+
/// be initialized out-of-line using an expression of the wrapped property type.
199+
PropertyWrapperValuePlaceholderExpr *findWrappedValuePlaceholder(Expr *init);
199200

200201
} // end namespace swift
201202

lib/AST/ASTDumper.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2511,6 +2511,18 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25112511
PrintWithColorRAII(OS, ParenthesisColor) << ')';
25122512
}
25132513

2514+
void visitPropertyWrapperValuePlaceholderExpr(
2515+
PropertyWrapperValuePlaceholderExpr *E) {
2516+
printCommon(E, "property_wrapper_value_placeholder_expr");
2517+
OS << '\n';
2518+
printRec(E->getOpaqueValuePlaceholder());
2519+
if (auto *value = E->getOriginalWrappedValue()) {
2520+
OS << '\n';
2521+
printRec(value);
2522+
}
2523+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2524+
}
2525+
25142526
void visitDefaultArgumentExpr(DefaultArgumentExpr *E) {
25152527
printCommon(E, "default_argument_expr");
25162528
OS << " default_args_owner=";

lib/AST/ASTWalker.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,23 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
508508

509509
Expr *visitOpaqueValueExpr(OpaqueValueExpr *E) { return E; }
510510

511+
Expr *visitPropertyWrapperValuePlaceholderExpr(
512+
PropertyWrapperValuePlaceholderExpr *E) {
513+
if (auto *placeholder = doIt(E->getOpaqueValuePlaceholder()))
514+
E->setOpaqueValuePlaceholder(dyn_cast<OpaqueValueExpr>(placeholder));
515+
else
516+
return nullptr;
517+
518+
if (E->getOriginalWrappedValue()) {
519+
if (auto *newValue = doIt(E->getOriginalWrappedValue()))
520+
E->setOriginalWrappedValue(newValue);
521+
else
522+
return nullptr;
523+
}
524+
525+
return E;
526+
}
527+
511528
Expr *visitDefaultArgumentExpr(DefaultArgumentExpr *E) { return E; }
512529

513530
Expr *visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E) {

lib/AST/Decl.cpp

Lines changed: 10 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -6408,105 +6408,27 @@ void ParamDecl::setDefaultArgumentCaptureInfo(CaptureInfo captures) {
64086408
DefaultValueAndFlags.getPointer()->Captures = captures;
64096409
}
64106410

6411-
/// Return nullptr if there is no property wrapper
6412-
Expr *swift::findOriginalPropertyWrapperInitialValue(VarDecl *var,
6413-
Expr *init) {
6414-
auto *PBD = var->getParentPatternBinding();
6415-
if (!PBD)
6416-
return nullptr;
6417-
6418-
// If there is no '=' on the pattern, there was no initial value.
6419-
if (PBD->getEqualLoc(0).isInvalid() && !PBD->isDefaultInitializable())
6420-
return nullptr;
6421-
6422-
ASTContext &ctx = var->getASTContext();
6423-
auto dc = var->getInnermostDeclContext();
6424-
const auto wrapperAttrs = var->getAttachedPropertyWrappers();
6425-
if (wrapperAttrs.empty())
6426-
return nullptr;
6427-
auto innermostAttr = wrapperAttrs.back();
6428-
auto innermostNominal = evaluateOrDefault(
6429-
ctx.evaluator, CustomAttrNominalRequest{innermostAttr, dc}, nullptr);
6430-
if (!innermostNominal)
6431-
return nullptr;
6432-
6433-
// Walker
6411+
PropertyWrapperValuePlaceholderExpr *
6412+
swift::findWrappedValuePlaceholder(Expr *init) {
64346413
class Walker : public ASTWalker {
64356414
public:
6436-
NominalTypeDecl *innermostNominal;
6437-
Expr *initArg = nullptr;
6438-
6439-
Walker(NominalTypeDecl *innermostNominal)
6440-
: innermostNominal(innermostNominal) { }
6415+
PropertyWrapperValuePlaceholderExpr *placeholder = nullptr;
64416416

64426417
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
6443-
if (initArg)
6418+
if (placeholder)
64446419
return { false, E };
64456420

6446-
if (auto call = dyn_cast<CallExpr>(E)) {
6447-
ASTContext &ctx = innermostNominal->getASTContext();
6448-
6449-
// We're looking for an implicit call.
6450-
if (!call->isImplicit())
6451-
return { true, E };
6452-
6453-
// ... which may call the constructor of another property
6454-
// wrapper if there are multiple wrappers attached to the
6455-
// property.
6456-
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
6457-
if (tuple->getNumElements() > 0) {
6458-
for (unsigned i : range(tuple->getNumElements())) {
6459-
if (tuple->getElementName(i) == ctx.Id_wrappedValue ||
6460-
tuple->getElementName(i) == ctx.Id_initialValue) {
6461-
auto elem = tuple->getElement(i)->getSemanticsProvidingExpr();
6462-
6463-
// Look through autoclosures.
6464-
if (auto autoclosure = dyn_cast<AutoClosureExpr>(elem))
6465-
elem = autoclosure->getSingleExpressionBody();
6466-
6467-
if (elem->isImplicit() && isa<CallExpr>(elem)) {
6468-
return { true, E };
6469-
}
6470-
}
6471-
}
6472-
}
6473-
}
6474-
6475-
// ... producing a value of the same nominal type as the
6476-
// innermost property wrapper.
6477-
if (!call->getType() ||
6478-
call->getType()->getAnyNominal() != innermostNominal)
6479-
return { false, E };
6480-
6481-
// Find the implicit initialValue/wrappedValue argument.
6482-
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
6483-
for (unsigned i : range(tuple->getNumElements())) {
6484-
if (tuple->getElementName(i) == ctx.Id_wrappedValue ||
6485-
tuple->getElementName(i) == ctx.Id_initialValue) {
6486-
initArg = tuple->getElement(i);
6487-
return { false, E };
6488-
}
6489-
}
6490-
}
6421+
if (auto *value = dyn_cast<PropertyWrapperValuePlaceholderExpr>(E)) {
6422+
placeholder = value;
6423+
return { false, value };
64916424
}
64926425

64936426
return { true, E };
64946427
}
6495-
} walker(innermostNominal);
6428+
} walker;
64966429
init->walk(walker);
64976430

6498-
Expr *initArg = walker.initArg;
6499-
if (initArg) {
6500-
initArg = initArg->getSemanticsProvidingExpr();
6501-
if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
6502-
if (!var->isInnermostPropertyWrapperInitUsesEscapingAutoClosure()) {
6503-
// Remove the autoclosure part only for non-escaping autoclosures
6504-
initArg =
6505-
autoclosure->getSingleExpressionBody()->getSemanticsProvidingExpr();
6506-
}
6507-
}
6508-
}
6509-
return initArg;
6431+
return walker.placeholder;
65106432
}
65116433

65126434
/// Writes a tuple expression where each element is either `nil` or another such
@@ -6605,7 +6527,7 @@ ParamDecl::getDefaultValueStringRepresentation(
66056527
}
66066528

66076529
auto init =
6608-
findOriginalPropertyWrapperInitialValue(original, parentInit);
6530+
findWrappedValuePlaceholder(parentInit)->getOriginalWrappedValue();
66096531
return extractInlinableText(getASTContext().SourceMgr, init, scratch);
66106532
}
66116533
}

lib/AST/Expr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
311311
PASS_THROUGH_REFERENCE(RebindSelfInConstructor, getSubExpr);
312312

313313
NO_REFERENCE(OpaqueValue);
314+
NO_REFERENCE(PropertyWrapperValuePlaceholder);
314315
NO_REFERENCE(DefaultArgument);
315316

316317
PASS_THROUGH_REFERENCE(BindOptional, getSubExpr);
@@ -624,6 +625,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
624625

625626
case ExprKind::RebindSelfInConstructor:
626627
case ExprKind::OpaqueValue:
628+
case ExprKind::PropertyWrapperValuePlaceholder:
627629
case ExprKind::DefaultArgument:
628630
case ExprKind::BindOptional:
629631
case ExprKind::OptionalEvaluation:
@@ -1403,6 +1405,17 @@ static ValueDecl *getCalledValue(Expr *E) {
14031405
return nullptr;
14041406
}
14051407

1408+
PropertyWrapperValuePlaceholderExpr *
1409+
PropertyWrapperValuePlaceholderExpr::create(ASTContext &ctx, SourceRange range,
1410+
Type ty, Expr *wrappedValue) {
1411+
auto *placeholder =
1412+
new (ctx) OpaqueValueExpr(range, ty, /*isPlaceholder=*/true);
1413+
1414+
return new (ctx) PropertyWrapperValuePlaceholderExpr(range, ty,
1415+
placeholder,
1416+
wrappedValue);
1417+
}
1418+
14061419
const ParamDecl *DefaultArgumentExpr::getParamDecl() const {
14071420
return getParameterAt(DefaultArgsOwner.getDecl(), ParamIndex);
14081421
}

lib/LLVMPasses/LLVMMergeFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ bool SwiftMergeFunctions::replaceDirectCallers(Function *Old, Function *New,
11261126
cast<PointerType>(New->getType())->getAddressSpace());
11271127

11281128
Value *Callee = ConstantExpr::getBitCast(New, FPtrType);
1129-
CallInst *NewCI = Builder.CreateCall(Callee, NewArgs);
1129+
CallInst *NewCI = Builder.CreateCall(FType, Callee, NewArgs);
11301130
NewCI->setCallingConv(CI->getCallingConv());
11311131
// Don't transfer attributes from the function to the callee. Function
11321132
// attributes typically aren't relevant to the calling convention or ABI.

0 commit comments

Comments
 (0)