Skip to content

Commit b9b4196

Browse files
Merge pull request #27239 from nate-chandler/39957093-argument-explosion-heuristic
[SILOptimizer] Alter FSO arg explosion heuristic.
2 parents 8ff1dac + 9567bd4 commit b9b4196

17 files changed

+3156
-358
lines changed

include/swift/SIL/Projection.h

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
#ifndef SWIFT_SIL_PROJECTION_H
2323
#define SWIFT_SIL_PROJECTION_H
2424

25+
#include "swift/AST/TypeAlignments.h"
2526
#include "swift/Basic/NullablePtr.h"
2627
#include "swift/Basic/PointerIntEnum.h"
27-
#include "swift/AST/TypeAlignments.h"
28-
#include "swift/SIL/SILValue.h"
28+
#include "swift/Basic/STLExtras.h"
2929
#include "swift/SIL/SILInstruction.h"
30+
#include "swift/SIL/SILValue.h"
3031
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
3132
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
3233
#include "llvm/ADT/Hashing.h"
@@ -751,15 +752,17 @@ class ProjectionTreeNode {
751752
~ProjectionTreeNode() = default;
752753
ProjectionTreeNode(const ProjectionTreeNode &) = default;
753754

754-
llvm::ArrayRef<unsigned> getChildProjections() {
755-
return llvm::makeArrayRef(ChildProjections);
755+
bool isLeaf() const { return ChildProjections.empty(); }
756+
757+
ArrayRef<unsigned> getChildProjections() const {
758+
return llvm::makeArrayRef(ChildProjections);
756759
}
757760

758-
llvm::Optional<Projection> &getProjection() { return Proj; }
761+
Optional<Projection> &getProjection() { return Proj; }
759762

760-
llvm::SmallVector<Operand *, 4> getNonProjUsers() const {
761-
return NonProjUsers;
762-
};
763+
const ArrayRef<Operand *> getNonProjUsers() const {
764+
return llvm::makeArrayRef(NonProjUsers);
765+
}
763766

764767
SILType getType() const { return NodeType; }
765768

@@ -914,6 +917,24 @@ class ProjectionTree {
914917
return false;
915918
}
916919

920+
void getAllLeafTypes(llvm::SmallVectorImpl<SILType> &outArray) const {
921+
llvm::SmallVector<const ProjectionTreeNode *, 32> worklist;
922+
worklist.push_back(getRoot());
923+
924+
while (!worklist.empty()) {
925+
auto *node = worklist.pop_back_val();
926+
// If we have a leaf node, add its type.
927+
if (node->isLeaf()) {
928+
outArray.push_back(node->getType());
929+
continue;
930+
}
931+
932+
// Otherwise, add the nodes children to the worklist.
933+
transform(node->getChildProjections(), std::back_inserter(worklist),
934+
[&](unsigned idx) { return getNode(idx); });
935+
}
936+
}
937+
917938
void getLiveLeafTypes(llvm::SmallVectorImpl<SILType> &OutArray) const {
918939
for (unsigned LeafIndex : LiveLeafIndices) {
919940
const ProjectionTreeNode *Node = getNode(LeafIndex);
@@ -940,7 +961,9 @@ class ProjectionTree {
940961
void
941962
replaceValueUsesWithLeafUses(SILBuilder &B, SILLocation Loc,
942963
llvm::SmallVectorImpl<SILValue> &Leafs);
943-
964+
965+
void getUsers(SmallPtrSetImpl<SILInstruction *> &users) const;
966+
944967
private:
945968
void createRoot(SILType BaseTy) {
946969
assert(ProjectionTreeNodes.empty() &&

include/swift/SILOptimizer/Analysis/ARCAnalysis.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,17 @@ class ConsumedArgToEpilogueReleaseMatcher {
332332
return completeList.getValue();
333333
}
334334

335+
Optional<ArrayRef<SILInstruction *>>
336+
getPartiallyPostDomReleaseSet(SILArgument *arg) const {
337+
auto iter = ArgInstMap.find(arg);
338+
if (iter == ArgInstMap.end())
339+
return None;
340+
auto partialList = iter->second.getPartiallyPostDomReleases();
341+
if (!partialList)
342+
return None;
343+
return partialList;
344+
}
345+
335346
ArrayRef<SILInstruction *> getReleasesForArgument(SILValue value) const {
336347
auto *arg = dyn_cast<SILArgument>(value);
337348
if (!arg)

include/swift/SILOptimizer/Analysis/CallerAnalysis.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ class CallerAnalysis::FunctionInfo {
278278
/// visibility of a protocol conformance or class.
279279
bool mayHaveIndirectCallers : 1;
280280

281+
/// Whether the function is sufficiently visible to be called by a different
282+
/// module.
283+
bool mayHaveExternalCallers : 1;
284+
281285
public:
282286
FunctionInfo(SILFunction *f);
283287

@@ -289,7 +293,8 @@ class CallerAnalysis::FunctionInfo {
289293
/// function (e.g. a specialized function) without needing to introduce a
290294
/// thunk since we can rewrite all of the callers to call the new function.
291295
bool foundAllCallers() const {
292-
return hasOnlyCompleteDirectCallerSets() && !mayHaveIndirectCallers;
296+
return hasOnlyCompleteDirectCallerSets() && !mayHaveIndirectCallers &&
297+
!mayHaveExternalCallers;
293298
}
294299

295300
/// Returns true if this function has at least one direct caller.

lib/SIL/Projection.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,3 +1514,11 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
15141514
NewNodes.clear();
15151515
}
15161516
}
1517+
1518+
void ProjectionTree::getUsers(SmallPtrSetImpl<SILInstruction *> &users) const {
1519+
for (auto *node : ProjectionTreeNodes) {
1520+
for (auto *op : node->getNonProjUsers()) {
1521+
users.insert(op->getUser());
1522+
}
1523+
}
1524+
}

lib/SILOptimizer/Analysis/CallerAnalysis.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ CallerAnalysis::FunctionInfo::FunctionInfo(SILFunction *f)
3333
// TODO: Make this more aggressive by considering
3434
// final/visibility/etc.
3535
mayHaveIndirectCallers(f->getDynamicallyReplacedFunction() ||
36-
canBeCalledIndirectly(f->getRepresentation())) {}
36+
canBeCalledIndirectly(f->getRepresentation())),
37+
mayHaveExternalCallers(f->isPossiblyUsedExternally() ||
38+
f->isAvailableExternally()) {}
3739

3840
//===----------------------------------------------------------------------===//
3941
// CallerAnalysis::ApplySiteFinderVisitor

0 commit comments

Comments
 (0)