Skip to content

Commit 9214c1f

Browse files
committed
[SILOptimizer] Combine partial apply applies always.
Adds a first transformation to MandatoryCombiner: transform applies of partial applies to applies of the underlying function and then attempt to eliminate the partial apply which was previously being applied. For now, this transform is only performed if all the arguments are trivial.
1 parent e9c8bb7 commit 9214c1f

File tree

3 files changed

+955
-1
lines changed

3 files changed

+955
-1
lines changed

lib/SILOptimizer/Mandatory/MandatoryCombine.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,70 @@ class MandatoryCombiner final
7474
/// Base visitor that does not do anything.
7575
SILInstruction *visitSILInstruction(SILInstruction *) { return nullptr; }
7676

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+
77141
void addReachableCodeToWorklist(SILFunction &function) {
78142
SmallBlotSetVector<SILBasicBlock *, 32> blockWorklist;
79143
SmallBlotSetVector<SILBasicBlock *, 32> blocksVisited;

test/IRGen/indirect_argument.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend %s -emit-ir | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize %s
1+
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=MandatoryCombine %s -emit-ir | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize %s
22
import Swift
33
import Builtin
44

0 commit comments

Comments
 (0)