Skip to content

Commit 4a0a2c1

Browse files
authored
Merge pull request #15728 from gottesmm/pr-0526c20d5d982f0b8125feae69de2dcc04ac60a9
[func-sig-opts] Extract out rest of helper functions from FunctionSig…
2 parents cd3d3e7 + ee79f06 commit 4a0a2c1

File tree

1 file changed

+138
-120
lines changed

1 file changed

+138
-120
lines changed

lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp

Lines changed: 138 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -165,17 +165,10 @@ class FunctionSignatureTransform {
165165
void OwnedToGuaranteedTransformFunctionParameters();
166166

167167
/// Find any owned to guaranteed opportunities.
168-
bool OwnedToGuaranteedAnalyze() {
169-
bool Result = OwnedToGuaranteedAnalyzeResults();
170-
bool Params = OwnedToGuaranteedAnalyzeParameters();
171-
return Params || Result;
172-
}
168+
bool OwnedToGuaranteedAnalyze();
173169

174170
/// Do the actual owned to guaranteed transformations.
175-
void OwnedToGuaranteedTransform() {
176-
OwnedToGuaranteedTransformFunctionResults();
177-
OwnedToGuaranteedTransformFunctionParameters();
178-
}
171+
void OwnedToGuaranteedTransform();
179172

180173
/// Set up epilogue work for the thunk result based in the given argument.
181174
void OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD,
@@ -203,25 +196,8 @@ class FunctionSignatureTransform {
203196
/// Every transformation must defines this interface. Default implementation
204197
/// simply passes it through.
205198
void addThunkArgument(ArgumentDescriptor &AD, SILBuilder &Builder,
206-
SILBasicBlock *BB,
207-
llvm::SmallVectorImpl<SILValue> &NewArgs) {
208-
// Dead argument.
209-
if (AD.IsEntirelyDead) {
210-
return;
211-
}
212-
213-
// Explode the argument.
214-
if (AD.Explode) {
215-
llvm::SmallVector<SILValue, 4> LeafValues;
216-
AD.ProjTree.createTreeFromValue(Builder, BB->getParent()->getLocation(),
217-
BB->getArgument(AD.Index), LeafValues);
218-
NewArgs.append(LeafValues.begin(), LeafValues.end());
219-
return;
220-
}
221-
222-
// All other arguments get pushed as what they are.
223-
NewArgs.push_back(BB->getArgument(AD.Index));
224-
}
199+
SILBasicBlock *BB,
200+
llvm::SmallVectorImpl<SILValue> &NewArgs);
225201

226202
/// Take ArgumentDescList and ResultDescList and create an optimized function
227203
/// based on the current function we are analyzing. This also has the side effect
@@ -247,105 +223,35 @@ class FunctionSignatureTransform {
247223
}
248224

249225
/// Run the optimization.
250-
bool run(bool hasCaller) {
251-
bool Changed = false;
252-
SILFunction *F = TransformDescriptor.OriginalFunction;
253-
254-
if (!hasCaller && canBeCalledIndirectly(F->getRepresentation())) {
255-
DEBUG(llvm::dbgs() << " function has no caller -> abort\n");
256-
return false;
257-
}
258-
259-
// Run OwnedToGuaranteed optimization.
260-
if (OwnedToGuaranteedAnalyze()) {
261-
Changed = true;
262-
DEBUG(llvm::dbgs() << " transform owned-to-guaranteed\n");
263-
OwnedToGuaranteedTransform();
264-
}
265-
266-
// Run DeadArgument elimination transformation. We only specialize
267-
// if this function has a caller inside the current module or we have
268-
// already created a thunk.
269-
if ((hasCaller || Changed) && DeadArgumentAnalyzeParameters()) {
270-
Changed = true;
271-
DEBUG(llvm::dbgs() << " remove dead arguments\n");
272-
DeadArgumentTransformFunction();
273-
}
274-
275-
// Run ArgumentExplosion transformation. We only specialize
276-
// if this function has a caller inside the current module or we have
277-
// already created a thunk.
278-
//
279-
// NOTE: we run argument explosion last because we've already initialized
280-
// the ArgumentDescList to have unexploded number of arguments. Exploding
281-
// it without changing the argument count is not going to help with
282-
// owned-to-guaranteed transformation.
283-
//
284-
// In order to not miss any opportunity, we send the optimized function
285-
// to the passmanager to optimize any opportunities exposed by argument
286-
// explosion.
287-
if ((hasCaller || Changed) && ArgumentExplosionAnalyzeParameters()) {
288-
Changed = true;
289-
}
290-
291-
// Check if generic signature of the function could be changed by
292-
// removed some unused generic arguments.
293-
if (F->getLoweredFunctionType()->isPolymorphic() &&
294-
createOptimizedSILFunctionType() != F->getLoweredFunctionType()) {
295-
Changed = true;
296-
}
297-
298-
// Create the specialized function and invalidate the old function.
299-
if (Changed) {
300-
createFunctionSignatureOptimizedFunction();
301-
}
302-
return Changed;
303-
}
226+
bool run(bool hasCaller);
304227

305228
/// Run dead argument elimination of partially applied functions.
229+
///
306230
/// After this optimization CapturePropagation can replace the partial_apply
307231
/// by a direct reference to the specialized function.
308-
bool removeDeadArgs(int minPartialAppliedArgs) {
309-
if (minPartialAppliedArgs < 1)
310-
return false;
311-
312-
if (!DeadArgumentAnalyzeParameters())
313-
return false;
314-
315-
SILFunction *F = TransformDescriptor.OriginalFunction;
316-
auto ArgumentDescList = TransformDescriptor.ArgumentDescList;
317-
318-
// Check if at least the minimum number of partially applied arguments
319-
// are dead. Otherwise no partial_apply can be removed anyway.
320-
unsigned Size = ArgumentDescList.size();
321-
for (unsigned Idx : range(Size)) {
322-
if (Idx < Size - minPartialAppliedArgs) {
323-
// Don't remove arguments other than the partial applied ones, even if
324-
// they are dead.
325-
ArgumentDescList[Idx].IsEntirelyDead = false;
326-
continue;
327-
}
328-
329-
// Is the partially applied argument dead?
330-
if (!ArgumentDescList[Idx].IsEntirelyDead)
331-
return false;
232+
bool removeDeadArgs(int minPartialAppliedArgs);
233+
};
332234

333-
// Currently we require that all dead parameters have trivial types. The
334-
// reason is that it's very hard to find places where we can release those
335-
// parameters (as a replacement for the removed partial_apply).
336-
//
337-
// TODO: Maybe we can skip this restriction when we have semantic ARC.
338-
if (ArgumentDescList[Idx].Arg->getType().isTrivial(F->getModule()))
339-
continue;
340-
return false;
341-
}
235+
void FunctionSignatureTransform::addThunkArgument(
236+
ArgumentDescriptor &AD, SILBuilder &Builder, SILBasicBlock *BB,
237+
llvm::SmallVectorImpl<SILValue> &NewArgs) {
238+
// Dead argument.
239+
if (AD.IsEntirelyDead) {
240+
return;
241+
}
342242

343-
DEBUG(llvm::dbgs() << " remove dead arguments for partial_apply\n");
344-
DeadArgumentTransformFunction();
345-
createFunctionSignatureOptimizedFunction();
346-
return true;
243+
// Explode the argument.
244+
if (AD.Explode) {
245+
llvm::SmallVector<SILValue, 4> LeafValues;
246+
AD.ProjTree.createTreeFromValue(Builder, BB->getParent()->getLocation(),
247+
BB->getArgument(AD.Index), LeafValues);
248+
NewArgs.append(LeafValues.begin(), LeafValues.end());
249+
return;
347250
}
348-
};
251+
252+
// All other arguments get pushed as what they are.
253+
NewArgs.push_back(BB->getArgument(AD.Index));
254+
}
349255

350256
} // end anonymous namespace
351257

@@ -798,6 +704,107 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
798704
assert(F->getDebugScope()->Parent != NewF->getDebugScope()->Parent);
799705
}
800706

707+
// Run the optimization.
708+
bool FunctionSignatureTransform::run(bool hasCaller) {
709+
bool Changed = false;
710+
SILFunction *F = TransformDescriptor.OriginalFunction;
711+
712+
if (!hasCaller && canBeCalledIndirectly(F->getRepresentation())) {
713+
DEBUG(llvm::dbgs() << " function has no caller -> abort\n");
714+
return false;
715+
}
716+
717+
// Run OwnedToGuaranteed optimization.
718+
if (OwnedToGuaranteedAnalyze()) {
719+
Changed = true;
720+
DEBUG(llvm::dbgs() << " transform owned-to-guaranteed\n");
721+
OwnedToGuaranteedTransform();
722+
}
723+
724+
// Run DeadArgument elimination transformation. We only specialize
725+
// if this function has a caller inside the current module or we have
726+
// already created a thunk.
727+
if ((hasCaller || Changed) && DeadArgumentAnalyzeParameters()) {
728+
Changed = true;
729+
DEBUG(llvm::dbgs() << " remove dead arguments\n");
730+
DeadArgumentTransformFunction();
731+
}
732+
733+
// Run ArgumentExplosion transformation. We only specialize
734+
// if this function has a caller inside the current module or we have
735+
// already created a thunk.
736+
//
737+
// NOTE: we run argument explosion last because we've already initialized
738+
// the ArgumentDescList to have unexploded number of arguments. Exploding
739+
// it without changing the argument count is not going to help with
740+
// owned-to-guaranteed transformation.
741+
//
742+
// In order to not miss any opportunity, we send the optimized function
743+
// to the passmanager to optimize any opportunities exposed by argument
744+
// explosion.
745+
if ((hasCaller || Changed) && ArgumentExplosionAnalyzeParameters()) {
746+
Changed = true;
747+
}
748+
749+
// Check if generic signature of the function could be changed by
750+
// removed some unused generic arguments.
751+
if (F->getLoweredFunctionType()->isPolymorphic() &&
752+
createOptimizedSILFunctionType() != F->getLoweredFunctionType()) {
753+
Changed = true;
754+
}
755+
756+
// Create the specialized function and invalidate the old function.
757+
if (Changed) {
758+
createFunctionSignatureOptimizedFunction();
759+
}
760+
return Changed;
761+
}
762+
763+
// Run dead argument elimination of partially applied functions.
764+
//
765+
// After this optimization CapturePropagation can replace the partial_apply by a
766+
// direct reference to the specialized function.
767+
bool FunctionSignatureTransform::removeDeadArgs(int minPartialAppliedArgs) {
768+
if (minPartialAppliedArgs < 1)
769+
return false;
770+
771+
if (!DeadArgumentAnalyzeParameters())
772+
return false;
773+
774+
SILFunction *F = TransformDescriptor.OriginalFunction;
775+
auto ArgumentDescList = TransformDescriptor.ArgumentDescList;
776+
777+
// Check if at least the minimum number of partially applied arguments
778+
// are dead. Otherwise no partial_apply can be removed anyway.
779+
unsigned Size = ArgumentDescList.size();
780+
for (unsigned Idx : range(Size)) {
781+
if (Idx < Size - minPartialAppliedArgs) {
782+
// Don't remove arguments other than the partial applied ones, even if
783+
// they are dead.
784+
ArgumentDescList[Idx].IsEntirelyDead = false;
785+
continue;
786+
}
787+
788+
// Is the partially applied argument dead?
789+
if (!ArgumentDescList[Idx].IsEntirelyDead)
790+
return false;
791+
792+
// Currently we require that all dead parameters have trivial types. The
793+
// reason is that it's very hard to find places where we can release those
794+
// parameters (as a replacement for the removed partial_apply).
795+
//
796+
// TODO: Maybe we can skip this restriction when we have semantic ARC.
797+
if (ArgumentDescList[Idx].Arg->getType().isTrivial(F->getModule()))
798+
continue;
799+
return false;
800+
}
801+
802+
DEBUG(llvm::dbgs() << " remove dead arguments for partial_apply\n");
803+
DeadArgumentTransformFunction();
804+
createFunctionSignatureOptimizedFunction();
805+
return true;
806+
}
807+
801808
//===----------------------------------------------------------------------===//
802809
// Dead Argument Elimination
803810
//===----------------------------------------------------------------------===//
@@ -1084,6 +1091,17 @@ OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD, SILBuilder &Builder,
10841091
}
10851092
}
10861093

1094+
bool FunctionSignatureTransform::OwnedToGuaranteedAnalyze() {
1095+
bool Result = OwnedToGuaranteedAnalyzeResults();
1096+
bool Params = OwnedToGuaranteedAnalyzeParameters();
1097+
return Params || Result;
1098+
}
1099+
1100+
void FunctionSignatureTransform::OwnedToGuaranteedTransform() {
1101+
OwnedToGuaranteedTransformFunctionResults();
1102+
OwnedToGuaranteedTransformFunctionParameters();
1103+
}
1104+
10871105
//===----------------------------------------------------------------------===//
10881106
// Argument Explosion Transformation
10891107
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)