Skip to content

Commit 7eb703b

Browse files
committed
Switch subscript index emission to use SILGenApply. NFC.
As always, most of the work here went into working around the AST representations of parameter and argument lists.
1 parent e312f8e commit 7eb703b

File tree

11 files changed

+437
-228
lines changed

11 files changed

+437
-228
lines changed

lib/SILGen/ArgumentSource.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,67 @@ void ArgumentSource::dump(raw_ostream &out, unsigned indent) const {
409409
}
410410
llvm_unreachable("bad kind");
411411
}
412+
413+
void PreparedArguments::emplaceEmptyArgumentList(SILGenFunction &SGF) {
414+
emplace(CanType(TupleType::getEmpty(SGF.getASTContext())), /*scalar*/ false);
415+
assert(isValid());
416+
}
417+
418+
PreparedArguments
419+
PreparedArguments::copy(SILGenFunction &SGF, SILLocation loc) const {
420+
if (isNull()) return PreparedArguments();
421+
422+
assert(isValid());
423+
PreparedArguments result(getFormalType(), isScalar());
424+
for (auto &elt : Arguments) {
425+
assert(elt.isRValue());
426+
result.add(elt.getKnownRValueLocation(),
427+
elt.asKnownRValue().copy(SGF, loc));
428+
}
429+
assert(isValid());
430+
return result;
431+
}
432+
433+
bool PreparedArguments::isObviouslyEqual(const PreparedArguments &other) const {
434+
if (isNull() != other.isNull())
435+
return false;
436+
if (isNull())
437+
return true;
438+
439+
assert(isValid() && other.isValid());
440+
if (Arguments.size() != other.Arguments.size())
441+
return false;
442+
for (auto i : indices(Arguments)) {
443+
if (!Arguments[i].isObviouslyEqual(other.Arguments[i]))
444+
return false;
445+
}
446+
return true;
447+
}
448+
449+
bool ArgumentSource::isObviouslyEqual(const ArgumentSource &other) const {
450+
if (StoredKind != other.StoredKind)
451+
return false;
452+
453+
switch (StoredKind) {
454+
case Kind::Invalid:
455+
llvm_unreachable("argument source is invalid");
456+
case Kind::RValue:
457+
return asKnownRValue().isObviouslyEqual(other.asKnownRValue());
458+
case Kind::LValue:
459+
return false; // TODO?
460+
case Kind::Expr:
461+
return false; // TODO?
462+
case Kind::Tuple: {
463+
auto &selfTuple = Storage.get<TupleStorage>(StoredKind);
464+
auto &otherTuple = other.Storage.get<TupleStorage>(other.StoredKind);
465+
if (selfTuple.Elements.size() != otherTuple.Elements.size())
466+
return false;
467+
for (auto i : indices(selfTuple.Elements)) {
468+
if (!selfTuple.Elements[i].isObviouslyEqual(otherTuple.Elements[i]))
469+
return false;
470+
}
471+
return true;
472+
}
473+
}
474+
llvm_unreachable("bad kind");
475+
}

lib/SILGen/ArgumentSource.h

Lines changed: 103 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ class ArgumentSource {
229229
RValue &&asKnownRValue(SILGenFunction &SGF) && {
230230
return std::move(Storage.get<RValueStorage>(StoredKind).Value);
231231
}
232-
232+
const RValue &asKnownRValue() const & {
233+
return Storage.get<RValueStorage>(StoredKind).Value;
234+
}
233235
SILLocation getKnownRValueLocation() const & {
234236
return Storage.get<RValueStorage>(StoredKind).Loc;
235237
}
@@ -239,6 +241,9 @@ class ArgumentSource {
239241
LValue &&asKnownLValue() && {
240242
return std::move(Storage.get<LValueStorage>(StoredKind).Value);
241243
}
244+
const LValue &asKnownLValue() const & {
245+
return Storage.get<LValueStorage>(StoredKind).Value;
246+
}
242247
SILLocation getKnownLValueLocation() const & {
243248
return Storage.get<LValueStorage>(StoredKind).Loc;
244249
}
@@ -310,30 +315,117 @@ class ArgumentSource {
310315
/// Whether this argument source requires the callee to evaluate.
311316
bool requiresCalleeToEvaluate() const;
312317

318+
bool isObviouslyEqual(const ArgumentSource &other) const;
319+
313320
void dump() const;
314321
void dump(raw_ostream &os, unsigned indent = 0) const;
315322

316323
private:
317324
/// Private helper constructor for delayed borrowed rvalues.
318325
ArgumentSource(SILLocation loc, RValue &&rv, Kind kind);
319326

320-
// Make the non-move accessors private to make it more difficult
327+
// Make this non-move accessor private to make it more difficult
321328
// to accidentally re-emit values.
322-
const RValue &asKnownRValue() const & {
323-
return Storage.get<RValueStorage>(StoredKind).Value;
329+
Expr *asKnownExpr() const & {
330+
return Storage.get<Expr*>(StoredKind);
324331
}
325332

326-
// Make the non-move accessors private to make it more difficult
327-
// to accidentally re-emit values.
328-
const LValue &asKnownLValue() const & {
329-
return Storage.get<LValueStorage>(StoredKind).Value;
333+
RValue getKnownTupleAsRValue(SILGenFunction &SGF, SGFContext C) &&;
334+
};
335+
336+
class PreparedArguments {
337+
// TODO: replace this formal type with an array of parameter types.
338+
CanType FormalType;
339+
std::vector<ArgumentSource> Arguments;
340+
bool IsScalar = false;
341+
public:
342+
PreparedArguments() {}
343+
PreparedArguments(CanType formalType, bool isScalar) {
344+
emplace(formalType, isScalar);
330345
}
331346

332-
Expr *asKnownExpr() const & {
333-
return Storage.get<Expr*>(StoredKind);
347+
// Move-only.
348+
PreparedArguments(const PreparedArguments &) = delete;
349+
PreparedArguments &operator=(const PreparedArguments &) = delete;
350+
351+
PreparedArguments(PreparedArguments &&other)
352+
: FormalType(other.FormalType), Arguments(std::move(other.Arguments)),
353+
IsScalar(other.IsScalar) {
354+
other.FormalType = CanType();
355+
}
356+
PreparedArguments &operator=(PreparedArguments &&other) {
357+
FormalType = other.FormalType;
358+
IsScalar = other.IsScalar;
359+
Arguments = std::move(other.Arguments);
360+
other.FormalType = CanType();
361+
return *this;
334362
}
335363

336-
RValue getKnownTupleAsRValue(SILGenFunction &SGF, SGFContext C) &&;
364+
/// Returns true if this is a null argument list. Note that this always
365+
/// indicates the total absence of an argument list rather than the
366+
/// possible presence of an empty argument list.
367+
bool isNull() const { return !FormalType; }
368+
369+
/// Returns true if this is a non-null and completed argument list.
370+
bool isValid() const {
371+
assert(!isNull());
372+
if (IsScalar) {
373+
return Arguments.size() == 1;
374+
} else if (auto tuple = dyn_cast<TupleType>(FormalType)) {
375+
return Arguments.size() == tuple->getNumElements();
376+
} else {
377+
return Arguments.size() == 1;
378+
}
379+
}
380+
381+
/// Return the formal type of this argument list.
382+
CanType getFormalType() const {
383+
assert(!isNull());
384+
return FormalType;
385+
}
386+
387+
/// Is this a single-argument list? Note that the argument might be a tuple.
388+
bool isScalar() const {
389+
assert(!isNull());
390+
return IsScalar;
391+
}
392+
393+
MutableArrayRef<ArgumentSource> getSources() && {
394+
assert(isValid());
395+
return Arguments;
396+
}
397+
398+
/// Emplace a (probably incomplete) argument list.
399+
void emplace(CanType formalType, bool isScalar) {
400+
assert(isNull());
401+
assert(!formalType->hasTypeParameter() && "should be a contextual type!");
402+
assert(isScalar || isa<TupleType>(formalType));
403+
FormalType = formalType;
404+
IsScalar = isScalar;
405+
}
406+
407+
/// Emplace an empty argument list.
408+
void emplaceEmptyArgumentList(SILGenFunction &SGF);
409+
410+
/// Add an emitted r-value argument to this argument list.
411+
void add(SILLocation loc, RValue &&arg) {
412+
assert(!isNull());
413+
Arguments.emplace_back(loc, std::move(arg));
414+
}
415+
416+
/// Add an arbitrary argument source to these arguments.
417+
///
418+
/// An argument list with an arbtrary argument source can't generally
419+
/// be copied.
420+
void addArbitrary(ArgumentSource &&arg) {
421+
assert(!isNull());
422+
Arguments.emplace_back(std::move(arg));
423+
}
424+
425+
/// Copy these prepared arguments. This propagates null.
426+
PreparedArguments copy(SILGenFunction &SGF, SILLocation loc) const;
427+
428+
bool isObviouslyEqual(const PreparedArguments &other) const;
337429
};
338430

339431
} // end namespace Lowering

lib/SILGen/LValue.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ class LogicalPathComponent : public PathComponent {
266266
struct AccessedStorage {
267267
AbstractStorageDecl *Storage;
268268
bool IsSuper;
269-
const RValue *Indices;
269+
const PreparedArguments *Indices;
270270
Expr *IndexExprForDiagnostics;
271271
};
272272

@@ -444,7 +444,7 @@ class LValue {
444444
bool isSuper,
445445
AccessStrategy accessStrategy,
446446
CanType formalRValueType,
447-
RValue &&indices,
447+
PreparedArguments &&indices,
448448
Expr *indexExprForDiagnostics);
449449

450450
void addMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
@@ -462,8 +462,8 @@ class LValue {
462462
bool isSuper,
463463
AccessStrategy accessStrategy,
464464
CanType formalRValueType,
465-
RValue &&indices,
466-
Expr *indexExprForDiagnostics = nullptr);
465+
PreparedArguments &&indices,
466+
Expr *indexExprForDiagnostics);
467467

468468
/// Add a subst-to-orig reabstraction component. That is, given
469469
/// that this l-value trafficks in values following the substituted

lib/SILGen/RValue.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static unsigned getTupleSize(CanType t) {
3939
return 1;
4040
}
4141

42-
static unsigned getRValueSize(AbstractionPattern pattern, CanType formalType) {
42+
unsigned RValue::getRValueSize(AbstractionPattern pattern, CanType formalType) {
4343
if (pattern.isTuple()) {
4444
unsigned count = 0;
4545
auto formalTupleType = cast<TupleType>(formalType);
@@ -54,7 +54,7 @@ static unsigned getRValueSize(AbstractionPattern pattern, CanType formalType) {
5454
}
5555

5656
/// Return the number of rvalue elements in the given canonical type.
57-
static unsigned getRValueSize(CanType type) {
57+
unsigned RValue::getRValueSize(CanType type) {
5858
if (auto tupleType = dyn_cast<TupleType>(type)) {
5959
unsigned count = 0;
6060
for (auto eltType : tupleType.getElementTypes())
@@ -367,7 +367,7 @@ static void copyOrInitValuesInto(Initialization *init,
367367
ManagedValue scalar = implodeTupleValues<KIND>(values, SGF, type, loc);
368368

369369
// This will have just used up the first values in the list, pop them off.
370-
values = values.slice(getRValueSize(type));
370+
values = values.slice(RValue::getRValueSize(type));
371371

372372
init->copyOrInitValueInto(SGF, loc, scalar, isInit);
373373
init->finishInitialization(SGF);
@@ -635,9 +635,10 @@ getElementRange(CanTupleType tupleType, unsigned eltIndex) {
635635
assert(eltIndex < tupleType->getNumElements());
636636
unsigned begin = 0;
637637
for (unsigned i = 0; i < eltIndex; ++i) {
638-
begin += getRValueSize(tupleType.getElementType(i));
638+
begin += RValue::getRValueSize(tupleType.getElementType(i));
639639
}
640-
unsigned end = begin + getRValueSize(tupleType.getElementType(eltIndex));
640+
unsigned end =
641+
begin + RValue::getRValueSize(tupleType.getElementType(eltIndex));
641642
return { begin, end };
642643
}
643644

lib/SILGen/RValue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ class RValue {
172172
static RValue forInContext() {
173173
return RValue(InContext);
174174
}
175+
176+
static unsigned getRValueSize(CanType substType);
177+
static unsigned getRValueSize(AbstractionPattern origType, CanType substType);
175178

176179
/// Create an RValue to which values will be subsequently added using
177180
/// addElement(), with the level of tuple expansion in the input specified

lib/SILGen/SILGen.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,9 @@ void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) {
12851285

12861286
if (!decl->exportsPropertyDescriptor())
12871287
return;
1288-
1288+
1289+
PrettyStackTraceDecl stackTrace("emitting property descriptor for", decl);
1290+
12891291
Type baseTy;
12901292
if (decl->getDeclContext()->isTypeContext()) {
12911293
// TODO: Static properties should eventually be referenceable as

0 commit comments

Comments
 (0)