@@ -79,6 +79,38 @@ static bool canHandleOperand(SILValue operand, SmallVectorImpl<SILValue> &out) {
7979 return all_of (out, [](SILValue v) { return isa<SILFunctionArgument>(v); });
8080}
8181
82+ // Eliminate a copy of a borrowed value, if:
83+ //
84+ // 1. All of the copies users do not consume the copy (and thus can accept a
85+ // borrowed value instead).
86+ // 2. The copies's non-destroy_value users are strictly contained within the
87+ // scope of the borrowed value.
88+ //
89+ // Example:
90+ //
91+ // %0 = @guaranteed (argument or instruction)
92+ // %1 = copy_value %0
93+ // apply %f(%1) : $@convention(thin) (@guaranteed ...) ...
94+ // other_non_consuming_use %1
95+ // destroy_value %1
96+ // end_borrow %0 (if an instruction)
97+ //
98+ // =>
99+ //
100+ // %0 = @guaranteed (argument or instruction)
101+ // apply %f(%0) : $@convention(thin) (@guaranteed ...) ...
102+ // other_non_consuming_use %0
103+ // end_borrow %0 (if an instruction)
104+ //
105+ // NOTE: This means that the destroy_value technically can be after the
106+ // end_borrow. In practice, this will not be the case but we use this to avoid
107+ // having to reason about the ordering of the end_borrow and destroy_value.
108+ //
109+ // NOTE: Today we only perform this for guaranteed parameters since this enables
110+ // us to avoid doing the linear lifetime check to make sure that all destroys
111+ // are within the borrow scope.
112+ //
113+ // TODO: This needs a better name.
82114static bool performGuaranteedCopyValueOptimization (CopyValueInst *cvi) {
83115 SmallVector<SILValue, 16 > borrowIntroducers;
84116
0 commit comments