Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 6 additions & 147 deletions lib/SILGen/ArgumentSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,7 @@ RValue &ArgumentSource::peekRValue() & {
return Storage.get<RValueStorage>(StoredKind).Value;
}

void ArgumentSource::rewriteType(CanType newType) & {
switch (StoredKind) {
case Kind::Invalid:
llvm_unreachable("argument source is invalid");
case Kind::LValue:
llvm_unreachable("cannot rewrite type of l-value");
case Kind::Tuple:
llvm_unreachable("cannot rewrite type of tuple");
case Kind::RValue:
Storage.get<RValueStorage>(StoredKind).Value.rewriteType(newType);
return;
case Kind::Expr:
Expr *&expr = Storage.get<Expr*>(StoredKind);
CanType oldType = expr->getType()->getCanonicalType();

// Usually nothing is required.
if (oldType == newType) return;

// Sometimes we need to wrap the expression in a single-element tuple.
// This is only necessary because we don't break down the argument list
// when dealing with SILGenApply.
if (auto newTuple = dyn_cast<TupleType>(newType)) {
if (newTuple->getNumElements() == 1 &&
newTuple.getElementType(0) == oldType) {
expr = TupleExpr::create(newType->getASTContext(),
SourceLoc(), expr, {}, {}, SourceLoc(),
/*trailing closure*/ false,
/*implicit*/ true, newType);
return;
}
}

llvm_unreachable("unimplemented! hope it doesn't happen");
}
llvm_unreachable("bad kind");
}

bool ArgumentSource::requiresCalleeToEvaluate() const {
bool ArgumentSource::isShuffle() const {
switch (StoredKind) {
case Kind::Invalid:
llvm_unreachable("argument source is invalid");
Expand All @@ -85,28 +48,8 @@ bool ArgumentSource::requiresCalleeToEvaluate() const {
//
// It would be good to split up TupleShuffleExpr into these two
// cases, and simplify ArgEmitter since it no longer has to deal
// with re-ordering. However for now, SubscriptExpr emits the
// index argument via the RValueEmitter, so the RValueEmitter has
// to know about varargs, duplicating some of the logic in
// ArgEmitter.
//
// Once this is fixed, we can also consider allowing subscripts
// to have default arguments.
if (auto *shuffleExpr = dyn_cast<TupleShuffleExpr>(asKnownExpr())) {
for (auto index : shuffleExpr->getElementMapping()) {
if (index == TupleShuffleExpr::DefaultInitialize ||
index == TupleShuffleExpr::CallerDefaultInitialize ||
index == TupleShuffleExpr::Variadic)
return true;
}
}
return false;
case Kind::Tuple:
for (auto &source : Storage.get<TupleStorage>(StoredKind).Elements) {
if (source.requiresCalleeToEvaluate())
return true;
}
return false;
// with re-ordering.
return isa<TupleShuffleExpr>(asKnownExpr());
}
llvm_unreachable("bad kind");
}
Expand All @@ -121,46 +64,10 @@ RValue ArgumentSource::getAsRValue(SILGenFunction &SGF, SGFContext C) && {
return std::move(*this).asKnownRValue(SGF);
case Kind::Expr:
return SGF.emitRValue(std::move(*this).asKnownExpr(), C);
case Kind::Tuple:
return std::move(*this).getKnownTupleAsRValue(SGF, C);
}
llvm_unreachable("bad kind");
}

RValue
ArgumentSource::getKnownTupleAsRValue(SILGenFunction &SGF, SGFContext C) && {

return std::move(*this).withKnownTupleElementSources<RValue>(
[&](SILLocation loc, CanTupleType type,
MutableArrayRef<ArgumentSource> elements) {
// If there's a target initialization, and we can split it, do so.
if (auto init = C.getEmitInto()) {
if (init->canSplitIntoTupleElements()) {
// Split the tuple.
SmallVector<InitializationPtr, 4> scratch;
auto eltInits = init->splitIntoTupleElements(SGF, loc, type, scratch);

// Emit each element into the corresponding element initialization.
for (auto i : indices(eltInits)) {
std::move(elements[i]).forwardInto(SGF, eltInits[i].get());
}

// Finish initialization.
init->finishInitialization(SGF);

return RValue::forInContext();
}
}

// Otherwise, emit all of the elements into a single big r-value.
RValue result(type);
for (auto &element : elements) {
result.addElement(std::move(element).getAsRValue(SGF));
}
return result;
});
}

ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &SGF,
SGFContext C) && {
switch (StoredKind) {
Expand Down Expand Up @@ -191,13 +98,6 @@ ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &SGF,
return SGF.emitRValueAsSingleValue(e, C);
}
}
case Kind::Tuple: {
auto loc = getKnownTupleLocation();
auto rvalue = std::move(*this).getKnownTupleAsRValue(SGF, C);
if (rvalue.isInContext())
return ManagedValue::forInContext();
return std::move(rvalue).getAsSingleValue(SGF, loc);
}
}
llvm_unreachable("bad kind");
}
Expand All @@ -221,7 +121,6 @@ ManagedValue ArgumentSource::getConverted(SILGenFunction &SGF,
llvm_unreachable("cannot get converted l-value");
case Kind::RValue:
case Kind::Expr:
case Kind::Tuple:
return SGF.emitConvertedRValue(getLocation(), conversion, C,
[&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
return std::move(*this).getAsSingleValue(SGF, C);
Expand All @@ -246,13 +145,6 @@ void ArgumentSource::forwardInto(SILGenFunction &SGF, Initialization *dest) && {
SGF.emitExprInto(e, dest);
return;
}
case Kind::Tuple: {
auto loc = getKnownTupleLocation();
auto rvalue = std::move(*this).getKnownTupleAsRValue(SGF, SGFContext(dest));
if (!rvalue.isInContext())
std::move(rvalue).ensurePlusOne(SGF, loc).forwardInto(SGF, loc, dest);
return;
}
}
llvm_unreachable("bad kind");
}
Expand All @@ -276,10 +168,6 @@ ArgumentSource ArgumentSource::borrow(SILGenFunction &SGF) const & {
case Kind::Expr: {
llvm_unreachable("cannot borrow an expression");
}
case Kind::Tuple: {
// FIXME: We can if we check the sub argument sources.
llvm_unreachable("cannot borrow a tuple");
}
}
llvm_unreachable("bad kind");
}
Expand Down Expand Up @@ -374,16 +262,6 @@ void ArgumentSource::dump(raw_ostream &out, unsigned indent) const {
out << "LValue\n";
Storage.get<LValueStorage>(StoredKind).Value.dump(out, indent + 2);
return;
case Kind::Tuple: {
out << "Tuple\n";
auto &storage = Storage.get<TupleStorage>(StoredKind);
storage.SubstType.dump(out, indent + 2);
for (auto &elt : storage.Elements) {
elt.dump(out, indent + 2);
out << '\n';
}
return;
}
case Kind::RValue:
out << "RValue\n";
Storage.get<RValueStorage>(StoredKind).Value.dump(out, indent + 2);
Expand All @@ -397,7 +275,7 @@ void ArgumentSource::dump(raw_ostream &out, unsigned indent) const {
}

void PreparedArguments::emplaceEmptyArgumentList(SILGenFunction &SGF) {
emplace(CanType(TupleType::getEmpty(SGF.getASTContext())), /*scalar*/ false);
emplace({}, /*scalar*/ false);
assert(isValid());
}

Expand All @@ -406,7 +284,7 @@ PreparedArguments::copy(SILGenFunction &SGF, SILLocation loc) const {
if (isNull()) return PreparedArguments();

assert(isValid());
PreparedArguments result(getFormalType(), isScalar());
PreparedArguments result(getParams(), isScalar());
for (auto &elt : Arguments) {
assert(elt.isRValue());
result.add(elt.getKnownRValueLocation(),
Expand Down Expand Up @@ -445,17 +323,6 @@ bool ArgumentSource::isObviouslyEqual(const ArgumentSource &other) const {
return false; // TODO?
case Kind::Expr:
return false; // TODO?
case Kind::Tuple: {
auto &selfTuple = Storage.get<TupleStorage>(StoredKind);
auto &otherTuple = other.Storage.get<TupleStorage>(other.StoredKind);
if (selfTuple.Elements.size() != otherTuple.Elements.size())
return false;
for (auto i : indices(selfTuple.Elements)) {
if (!selfTuple.Elements[i].isObviouslyEqual(otherTuple.Elements[i]))
return false;
}
return true;
}
}
llvm_unreachable("bad kind");
}
Expand All @@ -465,7 +332,7 @@ PreparedArguments PreparedArguments::copyForDiagnostics() const {
return PreparedArguments();

assert(isValid());
PreparedArguments result(getFormalType(), isScalar());
PreparedArguments result(getParams(), isScalar());
for (auto &arg : Arguments) {
result.Arguments.push_back(arg.copyForDiagnostics());
}
Expand All @@ -483,14 +350,6 @@ ArgumentSource ArgumentSource::copyForDiagnostics() const {
return {getKnownRValueLocation(), asKnownRValue().copyForDiagnostics()};
case Kind::Expr:
return asKnownExpr();
case Kind::Tuple: {
auto &tuple = Storage.get<TupleStorage>(StoredKind);
SmallVector<ArgumentSource, 4> copiedElements;
for (auto &elt : tuple.Elements) {
copiedElements.push_back(elt.copyForDiagnostics());
}
return {tuple.Loc, tuple.SubstType, copiedElements};
}
}
llvm_unreachable("bad kind");
}
Loading