Skip to content

[sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. #12285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2017

Conversation

gottesmm
Copy link
Contributor

@gottesmm gottesmm commented Oct 5, 2017

[sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}.

rdar://31521023


I am just trying to get feedback started while I wait for @rjmccall to finish looking at the other PR.

@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 5, 2017

@swift-ci smoke test

@gottesmm gottesmm force-pushed the multiple-value-inst branch from b1f91d7 to 200fc55 Compare October 5, 2017 03:56
@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 5, 2017

@swift-ci smoke test

1 similar comment
@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 5, 2017

@swift-ci smoke test

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better!


/// An instruction which always produces a fixed list of values.
class MultipleValueInstruction : public SILInstruction {
// *NOTE* THis is just a stub since we do not currently have any multiple
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capital H.

unsigned getIndexOfResult(const MultipleValueInstructionResult *R) const {
assert(((&Results.front() <= R) && (&Results.back() >= R)) &&
"Passed in result is not a result of this MultipleValueInstruction");
return unsigned(uintptr_t(R) - uintptr_t(&Results.front()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a byte offset instead of an index?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your right. I forgot to divide by the size.

const MultipleValueInstruction *MVI)
: Pointer(), Size(1) {
// We can perform a straight reinterpret_cast.
Pointer = reinterpret_cast<const uint8_t *>(MVI);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not reinterpret_cast<const void *>? We never want to read uint8_t values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, should not be a reinterpret_cast at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea... that is what I was saying via IM. Brain wires got crossed.

// *NOTE* In the case where we have a single instruction, Index will always
// necessarily be 0 implying that it is safe for us to just multiple Index by
// sizeof(MultipleValueInstructionResult).
size_t Offset = sizeof(MultipleValueInstructionResult) * Index;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this reinterpret_casting is code smell. It makes more sense to me for Pointer to be an opaque pointer type.
The most self-documenting way to express this is:

if (Index == 0)
  return static_cast<ValueBase*>(Pointer);

return static_cast<const MultipleValueInstructionResult*>(Pointer)[Index];

If you don't like the branch, you can just speculatively cast from void * to MultipleValueInstructionResult* with a comment about your cleverness.

If static_cast and reinterpret_cast are giving you different pointer adjustments, then I think you're already in serious trouble.

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have been submitted with my previous review.

Copy link
Contributor Author

@gottesmm gottesmm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making fixes!

unsigned getIndexOfResult(const MultipleValueInstructionResult *R) const {
assert(((&Results.front() <= R) && (&Results.back() >= R)) &&
"Passed in result is not a result of this MultipleValueInstruction");
return unsigned(uintptr_t(R) - uintptr_t(&Results.front()));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your right. I forgot to divide by the size.

const MultipleValueInstruction *MVI)
: Pointer(), Size(1) {
// We can perform a straight reinterpret_cast.
Pointer = reinterpret_cast<const uint8_t *>(MVI);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea... that is what I was saying via IM. Brain wires got crossed.

@gottesmm gottesmm force-pushed the multiple-value-inst branch from 200fc55 to 03cb3c9 Compare October 5, 2017 20:27
@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 5, 2017

Just to get feedback together (and to show how the two passes fit together), I am including the destructure_value impl here.

@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 5, 2017

*two passes == two patches.

@gottesmm gottesmm changed the title [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. [WIP] [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. DON'T MERGE Oct 5, 2017
@gottesmm gottesmm force-pushed the multiple-value-inst branch from 03cb3c9 to 2e610f0 Compare October 8, 2017 19:05
@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 8, 2017

@swift-ci test

1 similar comment
@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 8, 2017

@swift-ci test

@gottesmm
Copy link
Contributor Author

gottesmm commented Oct 8, 2017

The gardening commit is being committed in #12336.

@gottesmm
Copy link
Contributor Author

@rjmccall ping!

@gottesmm
Copy link
Contributor Author

(the conflict is just a module format issue, I can fix that).

@gottesmm
Copy link
Contributor Author

(But it shouldn't affect your ability to review since it is just a ModuleFormat increment).

@ematejska ematejska requested a review from rjmccall October 10, 2017 19:44
@gottesmm gottesmm changed the title [WIP] [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. DON'T MERGE [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. DON'T MERGE Oct 10, 2017
@@ -44,15 +44,21 @@ class DeclRefExpr;
class FloatLiteralExpr;
class FuncDecl;
class IntegerLiteralExpr;
class Projection;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to be used.

static bool classof(const SILInstruction *) = delete;
static bool classof(const SILUndef *) = delete;
static bool classof(const SILNode *node) {
return node->getKind() == SILNodeKind::MultipleValueInstructionResult;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping that this would be an abstract node, actually, so that you could do things like cast<DestructureInstResult>(value).

You should static_assert that all of the subclasses have the same size, of course.

/// natural clear way to derive the ValueOwnershipKind for all potential
/// multiple value instructions. This contrasts with the index of our result
/// in the parent array.
ValueOwnershipKind Kind;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please pull this up into the spare bits of the ValueBase node. I think you could just give SILNode a protected SubclassData field, LLVM-style.


/// An ArrayRef of Result objects. We assume that our child classes's will
/// allocate this for us on memory that will be placement newed.
ArrayRef<MultipleValueInstructionResult> Results;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think MultipleValueInstruction actually needs to store this directly. It can be dispatched to the various MultiValueInstruction subclasses (from the main SILInstruction implementation) just like getOperands() is. Going from a MultipleValueInstruction to its results is probably not a very common operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean.


MultipleValueInstruction *getParent() const { return Parent; }

unsigned getIndex() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My recommendation would have been to store the index in the SubclassData (which should have a completely reasonable number of bits, even with the ValueOwnershipKind) and then store the parent-instruction pointer at the beginning of the array. That might make it more difficult to use llvm::TrailingObjects, but I think it'll be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rjmccall What do you mean by the beginning of the array? Which array? It can't be in the MultipleValueInstruction parent since we can't access that. Or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess since I have the index, I can walk backwards assuming that I store the parent pointer. TBH though, couldn't I just not store the parent pointer at all and walk back using index and then walk back by an additional sizeof(MultipleValueInstruction)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you would need to know the subclass as well. Hmmm... let me look at this a bit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. My point is that you can always get back to the start of the array of MultiValueInstructionResults with just the current index, so you can store the parent pointer there without having to do any other instruction-specific dispatch. But I guess you could also use instruction-specific dispatch if the start of the MultiValueInstructionResult array is always at a static offset (which would require it to always be the first trailing object).

if (auto value = dyn_cast<ValueBase>(node)) {
// This allows for multiple return values.
llvm::SmallVector<SILValue, 8> values;
if (auto *value = dyn_cast<ValueBase>(node)) {
// The base pointer of the ultimate ArrayRef here is just the
// ValueBase; we aren't forming a reference to a temporary array.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is now stale with this change.

case SILNodeKind::MultipleValueInstructionResult:
// We do not print anything for multiple value instruction result since we
// print out the result when we print out various instructions.
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. This may only happen in debugging paths, but just like the SILArgument case, you do need to handle that — this is what will be called if someone calls dump() on a SILValue that happens to be a MultipleValueInstructionResult.

I think the appropriate debug-printing is something like printing the instruction with a special emphasis on the appropriate result, like

  %1 = destructure ...
  (%2, **%3**, %4) = destructure ...

// we'll assign the same ID to both the instruction and the
// first result.
for (auto result : results) {
ValueToIDMap[result] = idx++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change just a de-indenting? It looks fine to me, but I think it's probably unnecessarily confusing to do in the same patch as a bunch of multi-result compatibility fixes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I committed this separately. I just need to rebase.

return DefiningInstructionResult{ inst, 0 };
// TODO: MultiValueInstruction
if (auto *result = dyn_cast<MultipleValueInstructionResult>(this))
return DefiningInstructionResult{result->getParent(), result->getIndex()};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The style immediately above is to put spaces after the {; you should be consistent one way or the other.

}

if (auto *MVIR = dyn_cast<MultipleValueInstructionResult>(this)) {
return MVIR->getCanonicalSILNodeInObject();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getParent()

@gottesmm gottesmm force-pushed the multiple-value-inst branch from 2e610f0 to 6387352 Compare October 13, 2017 01:36
@gottesmm gottesmm force-pushed the multiple-value-inst branch 7 times, most recently from 53dbf2c to f8aaa54 Compare October 23, 2017 18:46
@gottesmm
Copy link
Contributor Author

Hmm... looks like I lost a part of a commit while rebasing...

@gottesmm
Copy link
Contributor Author

@swift-ci test

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci test

@gottesmm
Copy link
Contributor Author

@swift-ci Please Test OS X Source Compatibility

@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

@gottesmm
Copy link
Contributor Author

@rjmccall This is ready for review.

friend class Operand;

/// A 32 bit field of data that we provide for abstract subclasses to use.
uint32_t SubclassData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this in the base class. Why not putting the info in MultipleValueInstructionResult?
@rjmccall maybe a question to you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the space is already there in the base class because of alignment padding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a follow on commit, I will add some static_asserts/comments that says this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er, wait, I was assuming you would add this to SILNode. It is not using spare bits when you add it to ValueBase like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I read the first part of your previous comment where you were talking about putting this in the spare bits of ValueBase. For whatever reason I didn't grok the 2nd part of the sentence. I will fix this.

docs/SIL.rst Outdated
@@ -784,8 +784,12 @@ Basic Blocks
sil-label ::= sil-identifier ('(' sil-argument (',' sil-argument)* ')')? ':'
sil-argument ::= sil-value-name ':' sil-type

sil-instruction-def ::= (sil-value-name '=')? sil-instruction
(',' sil-loc)? (',' sil-scope-ref)?
sil-instruction-result ::= sil-value-name '='
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these should end in a '=', since you've made that part of sil-instruction-def.

docs/SIL.rst Outdated
(',' sil-loc)? (',' sil-scope-ref)?
sil-instruction-result ::= sil-value-name '='
sil-instruction-result ::= '(' sil-value-name? ')'
sil-instruction-result ::= '(' sil-value-name (',' sil-value-name)* ')'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sil-value-name (',' sil-value-name)*)? is cleaner and doesn't create a formal ambiguity. It's how we specify e.g. the arguments to apply.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense to me. You are not specifying the '(' and ')' that you need (unless I am missing something).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant for the contents of the parens. I'm just suggesting how to solve the "problem" that '(' sil-value-name ')' technically matches both of those productions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand now. Thank you.

docs/SIL.rst Outdated
// %eltN must have the type $EltNTy

Given a tuple value, split the value into its constituant elements. The reason
why we provide this is to ensure that +1 tuple can be split at one time into +1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"constituent"

You don't need to include a rationale here.

docs/SIL.rst Outdated

Given a struct, split the struct into its constituant fields. The
reason why we provide this is to ensure that +1 struct can be split at one time
into +1 subobjects.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for destructure_tuple.

class MultipleValueInstructionResult : public ValueBase {
// Bits 0-2 of the first byte of SubclassData is used for the
// ValueOwnershipKind.
static constexpr unsigned NumBitsForOwnershipKind = 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The normal naming convention for this would be something like NumOwnershipKindBits, and it should probably be declared next to ValueOwnershipKind instead of being defined here.

friend class Operand;

/// A 32 bit field of data that we provide for abstract subclasses to use.
uint32_t SubclassData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er, wait, I was assuming you would add this to SILNode. It is not using spare bits when you add it to ValueBase like this.


MutableArrayRef<uint8_t> getSubclassData() {
return {reinterpret_cast<uint8_t *>(&SubclassData), sizeof(SubclassData)};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just trying to provide a nice wrapper. I can't do this anyways, once I pack into a bitfield in SILNode.

@@ -922,6 +921,12 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
case SILNodeKind::SILUndef:
printSILUndef(cast<SILUndef>(node));
return;

#define MULTIPLE_VALUE_INST_RESULT(ID, PARENT) case SILNodeKind::ID:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pattern in this file is to put the case on the following line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this was git-clang-format I think.


// Now, we /must/ have a guaranteed subobject, so lets assert that the
// user
// is actually guaranteed and add the subobject's users to our worklist.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"let's", word wrap.

assert(hasMultipleSILNodes(getKind()));
return &static_cast<const SILInstruction &>(
static_cast<const SingleValueInstruction &>(
static_cast<const ValueBase &>(*this)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the old indentation pattern looked nicer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did git-clang-format.

@gottesmm gottesmm force-pushed the multiple-value-inst branch from 5530fbb to b6f3599 Compare October 24, 2017 23:14
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm gottesmm force-pushed the multiple-value-inst branch from b6f3599 to 69d7227 Compare October 24, 2017 23:19
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

@gottesmm
Copy link
Contributor Author

@rjmccall This is ready for another round. If it is possible, I would like to do further changes in separate PRs as long as the high level functionality is correct.

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'm fine with these comments being fixed in a follow-up patch.

}

LLVM_ATTRIBUTE_ALWAYS_INLINE
SILNodeKind getKind() const {
return SILNodeKind(Kind);
}

/// Return the SILNodeKind of this node's canonical SILNode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"representative"

}

LLVM_ATTRIBUTE_ALWAYS_INLINE
SILNodeKind getKind() const {
return SILNodeKind(Kind);
}

/// Return the SILNodeKind of this node's canonical SILNode.
///
/// TODO: Find a better name for this.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this name is good enough that we don't need this TODO anymore.

const unsigned Kind : NumKindBits;
const unsigned StorageLoc : NumStorageLocBits;
const unsigned IsRepresentativeNode : NumIsRepresentativeBits;
uint64_t SubclassData : NumSubclassDataBits;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to pack these effectively on all platforms, please make them all uint64_t.

Instruction
static constexpr unsigned NumKindBits = NumSILNodeKindBits;
static constexpr unsigned NumStorageLocBits = 1;
static constexpr unsigned NumIsRepresentativeBits = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three ought to be private.

static bool hasMultipleSILNodes(SILNodeKind kind) {
public:
/// Does the given kind of node inherit from multiple multiple SILNode base
/// classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a question, it should end in a question mark.

return const_cast<MultipleValueInstructionResult *>(this)->getParent();
}

unsigned getIndex() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be implemented inline, right? It's important enough to make sure it can be inlined even in non-WMO builds.

ValueOwnershipKind getOwnershipKind() const;

SILNode *getCanonicalSILNodeInObject();
const SILNode *getCanonicalSILNodeInObject() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why you have these overrides in subclasses, but they have the wrong name now.

"the SILInstruction subobject is always canonical");
return static_cast<SILInstruction*>(this);
}
const SILNode *getCanonicalSILNodeInObject() const {
assert(SILInstruction::isCanonicalSILNodeInObject() &&
assert(SILInstruction::isRepresentativeSILNodeInObject() &&
"the SILInstruction subobject is always canonical");
return static_cast<const SILInstruction*>(this);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These have the wrong name now, if they're really needed at all.

"the SILInstruction subobject is always canonical");
return this;
}
const SILNode *getCanonicalSILNodeInObject() const {
assert(isCanonicalSILNodeInObject() &&
assert(isRepresentativeSILNodeInObject() &&
"the SILInstruction subobject is always canonical");
return this;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These have the wrong name now, if they're really needed at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was cargo-culting your design from other places. I will remove them.

return;
auto *DataPtr = this->template getTrailingObjects<DerivedResult>();
for (unsigned i : range(NumResults))
DataPtr[i].~DerivedResult();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth leaving a comment that this is just for the assertion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no assertion here. Can you elaborate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the rest of the changes here: #12612. Once you elaborate, I'll take care of this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion in ~ValueBase().

@gottesmm
Copy link
Contributor Author

Thanks John!

@gottesmm gottesmm merged commit 36a8d0d into swiftlang:master Oct 25, 2017
@gottesmm gottesmm deleted the multiple-value-inst branch October 25, 2017 01:36
@gottesmm gottesmm changed the title [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. DON'T MERGE [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}. Oct 25, 2017
@eeckstein
Copy link
Contributor

nice work!

@gottesmm
Copy link
Contributor Author

= ). I also want to give thanks to John for his great review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants