Skip to content

Commit fd98ce1

Browse files
committed
Update PassManager's function worklist for newly added SILFunctions
The PassManager should transform all functions in bottom up order. This is necessary because when optimizations like inlining looks at the callee function bodies to compute profitability, the callee functions should have already undergone optimizations to get better profitability estimates. The PassManager builds its function worklist based on bottom up order on initialization. However, newly created SILFunctions due to specialization etc, are simply appended to the function worklist. This can cause us to make bad inlining decisions due to inaccurate profitability estimates. This change now updates the function worklist such that, all the callees of the newly added SILFunction are proccessed before it by the PassManager. Fixes rdar://52202680
1 parent 37657d0 commit fd98ce1

File tree

5 files changed

+62
-21
lines changed

5 files changed

+62
-21
lines changed

include/swift/SILOptimizer/Analysis/FunctionOrder.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class BottomUpFunctionOrder {
3131
typedef TinyPtrVector<SILFunction *> SCC;
3232

3333
private:
34-
SILModule &M;
3534
llvm::SmallVector<SCC, 32> TheSCCs;
3635
llvm::SmallVector<SILFunction *, 32> TheFunctions;
3736

@@ -44,24 +43,29 @@ class BottomUpFunctionOrder {
4443
llvm::SmallSetVector<SILFunction *, 4> DFSStack;
4544

4645
public:
47-
BottomUpFunctionOrder(SILModule &M, BasicCalleeAnalysis *BCA)
48-
: M(M), BCA(BCA), NextDFSNum(0) {}
46+
BottomUpFunctionOrder(BasicCalleeAnalysis *BCA)
47+
: BCA(BCA), NextDFSNum(0) {}
48+
49+
/// DFS on 'F' to compute bottom up order
50+
void computeBottomUpOrder(SILFunction *F) {
51+
DFS(F);
52+
}
53+
54+
/// DFS on all functions in the module to compute bottom up order
55+
void computeBottomUpOrder(SILModule *M) {
56+
for (auto &F : *M)
57+
DFS(&F);
58+
}
4959

5060
/// Get the SCCs in bottom-up order.
5161
ArrayRef<SCC> getSCCs() {
52-
if (!TheSCCs.empty())
53-
return TheSCCs;
54-
55-
FindSCCs(M);
5662
return TheSCCs;
5763
}
5864

59-
/// Get a flattened view of all functions in all the SCCs in
60-
/// bottom-up order
61-
ArrayRef<SILFunction *> getFunctions() {
65+
/// Get a flattened view of all functions in all the SCCs in bottom-up order
66+
ArrayRef<SILFunction *> getBottomUpOrder() {
6267
if (!TheFunctions.empty())
6368
return TheFunctions;
64-
6569
for (auto SCC : getSCCs())
6670
for (auto *F : SCC)
6771
TheFunctions.push_back(F);
@@ -71,7 +75,6 @@ class BottomUpFunctionOrder {
7175

7276
private:
7377
void DFS(SILFunction *F);
74-
void FindSCCs(SILModule &M);
7578
};
7679

7780
} // end namespace swift

lib/SILOptimizer/Analysis/FunctionOrder.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,3 @@ void BottomUpFunctionOrder::DFS(SILFunction *Start) {
7474
}
7575
}
7676

77-
void BottomUpFunctionOrder::FindSCCs(SILModule &M) {
78-
for (auto &F : M)
79-
DFS(&F);
80-
}

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,9 @@ runFunctionPasses(unsigned FromTransIdx, unsigned ToTransIdx) {
491491
return;
492492

493493
BasicCalleeAnalysis *BCA = getAnalysis<BasicCalleeAnalysis>();
494-
BottomUpFunctionOrder BottomUpOrder(*Mod, BCA);
495-
auto BottomUpFunctions = BottomUpOrder.getFunctions();
494+
BottomUpFunctionOrder BottomUpOrder(BCA);
495+
BottomUpOrder.computeBottomUpOrder(Mod);
496+
auto BottomUpFunctions = BottomUpOrder.getBottomUpOrder();
496497

497498
assert(FunctionWorklist.empty() && "Expected empty function worklist!");
498499

@@ -545,6 +546,47 @@ runFunctionPasses(unsigned FromTransIdx, unsigned ToTransIdx) {
545546
++Entry.PipelineIdx;
546547
}
547548
clearRestartPipeline();
549+
550+
if (TailIdx == (FunctionWorklist.size() - 1)) {
551+
// No new functions to process
552+
continue;
553+
}
554+
555+
// Compute the bottom up order of the new functions and the callees in it
556+
BottomUpFunctionOrder SubBottomUpOrder(BCA);
557+
// Initialize BottomUpFunctionOrder with new functions
558+
for (auto It = FunctionWorklist.begin() + TailIdx + 1;
559+
It != FunctionWorklist.end(); It++) {
560+
SubBottomUpOrder.computeBottomUpOrder(It->F);
561+
}
562+
auto NewFunctionsBottomUp = SubBottomUpOrder.getBottomUpOrder();
563+
SmallPtrSet<SILFunction *, 8> NewBottomUpSet(NewFunctionsBottomUp.begin(),
564+
NewFunctionsBottomUp.end());
565+
566+
// Remove all the functions in the new bottom up order from FunctionWorklist
567+
llvm::DenseMap<SILFunction *, WorklistEntry> FunctionsToReorder;
568+
auto RemoveFn = [&FunctionsToReorder,
569+
&NewBottomUpSet](WorklistEntry Entry) {
570+
if (NewBottomUpSet.find(Entry.F) == NewBottomUpSet.end()) {
571+
return false;
572+
}
573+
FunctionsToReorder.insert(std::make_pair(Entry.F, Entry));
574+
return true;
575+
};
576+
std::remove_if(FunctionWorklist.begin(), FunctionWorklist.end(), RemoveFn);
577+
FunctionWorklist.erase((FunctionWorklist.begin() + FunctionWorklist.size() -
578+
FunctionsToReorder.size()),
579+
FunctionWorklist.end());
580+
581+
// Add back the functions in the new bottom up order to the FunctionWorklist
582+
for (auto it = NewFunctionsBottomUp.rbegin();
583+
it != NewFunctionsBottomUp.rend(); it++) {
584+
auto Entry = FunctionsToReorder.find(*it);
585+
if (Entry == FunctionsToReorder.end()) {
586+
continue;
587+
}
588+
FunctionWorklist.push_back((*Entry).second);
589+
}
548590
}
549591
}
550592

lib/SILOptimizer/UtilityPasses/FunctionOrderPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class FunctionOrderPrinterPass : public SILModuleTransform {
3535
/// The entry point to the transformation.
3636
void run() override {
3737
BCA = getAnalysis<BasicCalleeAnalysis>();
38-
auto &M = *getModule();
39-
BottomUpFunctionOrder Orderer(M, BCA);
38+
BottomUpFunctionOrder Orderer(BCA);
39+
Orderer.computeBottomUpOrder(getModule());
4040

4141
llvm::outs() << "Bottom up function order:\n";
4242
auto SCCs = Orderer.getSCCs();

test/DebugInfo/inlined-generics-basic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ public class C<R> {
9191
// IR-LABEL: ret void
9292

9393
// IR: ![[BOOL:[0-9]+]] = !DICompositeType({{.*}}name: "Bool"
94-
// IR: ![[LET_BOOL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[BOOL]])
9594
// IR: ![[INT:[0-9]+]] = !DICompositeType({{.*}}name: "Int"
9695
// IR: ![[LET_INT:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[INT]])
96+
// IR: ![[LET_BOOL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[BOOL]])
9797
// IR: ![[TAU_0_0:[0-9]+]] = {{.*}}DW_TAG_structure_type, name: "$sxD",
9898
// IR: ![[LET_TAU_0_0:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TAU_0_0]])
9999
// IR: ![[TAU_1_0:[0-9]+]] = {{.*}}DW_TAG_structure_type, name: "$sqd__D",

0 commit comments

Comments
 (0)