[cow] Teach uniqueness check hoisting how to ignore guaranteed calls to ArraySemantic functions.

We ignore calls to ArraySemantic functions when we hoist uniqueness checks. With
+0 self, this is disrupted by the release that now is in the caller instead of
the callee.

This patch fixes that problem by teaching COWArrayOpts about "guaranteed call
sequences". This is the following pattern:

retain(x)
... nothing that decrements reference counts ...
call f1(@guaranteed_self x)
... nothing that decrements or uses ref counts ...
call f2(@guaranteed_self x)
... nothing that decrements or uses ref counts ...
...
... nothing that decrements or uses ref counts ...
call f$(n-1)(@guaranteed_self x)
... nothing that decrements or uses ref counts ...
call fn(@guaranteed_self x)
... nothing that uses ref counts ...
release(x)

This pattern is created when there are a bunch of guaranteed calls together in a
row (which seems to happen at the "semantic" SIL level). We pattern match the
sequence and then verify that all of the calls are semantic calls. If the
verification succeeds, we can hoist the uniqueness check.

rdar://20340699

Swift SVN r26835
This commit is contained in:
Michael Gottesman
2015-04-01 23:30:03 +00:00
parent 7b065529a9
commit 2c1aed9b27
7 changed files with 391 additions and 38 deletions

View File

@@ -56,10 +56,10 @@ public:
: ArraySemanticsCall(V, SemanticStr, false) {}
/// Can we hoist this call.
bool canHoist(SILInstruction *To, DominanceInfo *DT);
bool canHoist(SILInstruction *To, DominanceInfo *DT) const;
/// Determine which kind of array semantics call this is.
ArrayCallKind getKind();
ArrayCallKind getKind() const;
/// Does this semantic call has a self argument.
///
@@ -73,19 +73,19 @@ public:
bool hasGuaranteedSelf() const;
/// Get the self argument.
SILValue getSelf();
SILValue getSelf() const;
/// Get the self argument operand.
Operand &getSelfOperand();
Operand &getSelfOperand() const;
/// Get the index for operations that have one.
SILValue getIndex();
SILValue getIndex() const;
/// Get the array.props.isNative argument.
SILValue getArrayPropertyIsNative();
SILValue getArrayPropertyIsNative() const;
/// Get the array.props.needsElementTypeCheck argument.
SILValue getArrayPropertyNeedsTypeCheck();
SILValue getArrayPropertyNeedsTypeCheck() const;
/// Remove the semantics call replacing it by a release of any @owned
/// parameter.
@@ -102,10 +102,15 @@ public:
}
/// Get the semantics call as an ApplyInst.
operator ApplyInst *() { return SemanticsCall; }
operator ApplyInst *() const { return SemanticsCall; }
/// Is this an semantics call.
operator bool() { return SemanticsCall != nullptr; }
operator bool() const { return SemanticsCall != nullptr; }
/// Does this array semantic call touch globals or ivars in a manner that
/// causes its effect on reference counts to not be described solely by its
/// signature.
bool isNoCapture() const;
protected:
/// Validate the signature of this call.
@@ -116,5 +121,6 @@ protected:
ApplyInst *hoistOrCopy(SILInstruction *InsertBefore, DominanceInfo *DT,
bool LeaveOriginal);
};
} // End namespace swift.
#endif