@@ -74,6 +74,70 @@ class MandatoryCombiner final
74
74
// / Base visitor that does not do anything.
75
75
SILInstruction *visitSILInstruction (SILInstruction *) { return nullptr ; }
76
76
77
+ // / \returns whether all the values are of trivial type in the provided
78
+ // / function.
79
+ template <typename Values>
80
+ static bool areAllValuesTrivial (Values values, SILFunction &function) {
81
+ return llvm::all_of (values, [&](SILValue value) -> bool {
82
+ return value->getType ().isTrivial (function);
83
+ });
84
+ }
85
+
86
+ SILInstruction *visitApplyInst (ApplyInst *instruction) {
87
+ // Apply this pass only to partial applies all of whose arguments are
88
+ // trivial.
89
+ auto calledValue = instruction->getCallee ();
90
+ if (calledValue == nullptr ) {
91
+ return nullptr ;
92
+ }
93
+ auto fullApplyCallee = calledValue->getDefiningInstruction ();
94
+ if (fullApplyCallee == nullptr ) {
95
+ return nullptr ;
96
+ }
97
+ auto partialApply = dyn_cast<PartialApplyInst>(fullApplyCallee);
98
+ if (partialApply == nullptr ) {
99
+ return nullptr ;
100
+ }
101
+ auto *function = partialApply->getCalleeFunction ();
102
+ if (function == nullptr ) {
103
+ return nullptr ;
104
+ }
105
+ ApplySite fullApplySite (instruction);
106
+ auto fullApplyArguments = fullApplySite.getArguments ();
107
+ if (!areAllValuesTrivial (fullApplyArguments, *function)) {
108
+ return nullptr ;
109
+ }
110
+ auto partialApplyArguments = ApplySite (partialApply).getArguments ();
111
+ if (!areAllValuesTrivial (partialApplyArguments, *function)) {
112
+ return nullptr ;
113
+ }
114
+
115
+ auto callee = partialApply->getCallee ();
116
+
117
+ ApplySite partialApplySite (partialApply);
118
+
119
+ SmallVector<SILValue, 8 > argsVec;
120
+ llvm::copy (fullApplyArguments, std::back_inserter (argsVec));
121
+ llvm::copy (partialApplyArguments, std::back_inserter (argsVec));
122
+
123
+ SILBuilderWithScope builder (instruction, &createdInstructions);
124
+ ApplyInst *replacement = builder.createApply (
125
+ /* Loc=*/ instruction->getDebugLocation ().getLocation (), /* Fn=*/ callee,
126
+ /* Subs=*/ partialApply->getSubstitutionMap (),
127
+ /* Args*/ argsVec,
128
+ /* isNonThrowing=*/ instruction->isNonThrowing (),
129
+ /* SpecializationInfo=*/ partialApply->getSpecializationInfo ());
130
+
131
+ worklist.replaceInstructionWithInstruction (instruction, replacement
132
+ #ifndef NDEBUG
133
+ ,
134
+ /* instructionDescription=*/ " "
135
+ #endif
136
+ );
137
+ tryDeleteDeadClosure (partialApply, instModCallbacks);
138
+ return nullptr ;
139
+ }
140
+
77
141
void addReachableCodeToWorklist (SILFunction &function) {
78
142
SmallBlotSetVector<SILBasicBlock *, 32 > blockWorklist;
79
143
SmallBlotSetVector<SILBasicBlock *, 32 > blocksVisited;
0 commit comments