@@ -79,6 +79,38 @@ static bool canHandleOperand(SILValue operand, SmallVectorImpl<SILValue> &out) {
79
79
return all_of (out, [](SILValue v) { return isa<SILFunctionArgument>(v); });
80
80
}
81
81
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.
82
114
static bool performGuaranteedCopyValueOptimization (CopyValueInst *cvi) {
83
115
SmallVector<SILValue, 16 > borrowIntroducers;
84
116
0 commit comments