Skip to content

Commit a24b17a

Browse files
committed
Swift Optimizer: add the dominator and post-dominator tree analysis
1 parent 4440beb commit a24b17a

File tree

7 files changed

+124
-1
lines changed

7 files changed

+124
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@
99
swift_compiler_sources(Optimizer
1010
AliasAnalysis.swift
1111
CalleeAnalysis.swift
12-
DeadEndBlocksAnalysis.swift)
12+
DeadEndBlocksAnalysis.swift
13+
DominatorTree.swift
14+
PostDominatorTree.swift)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- DominatorTree.swift - the dominator tree -------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
import OptimizerBridging
15+
16+
public struct DominatorTree {
17+
let bridged: BridgedDomTree
18+
}
19+
20+
extension BasicBlock {
21+
func dominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
22+
DominatorTree_dominates(domTree.bridged, self.bridged, other.bridged) != 0
23+
}
24+
25+
func strictlyDominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
26+
dominates(other, domTree) && self != other
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- PostDominatorTree.swift - the post dominator tree ----------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
import OptimizerBridging
15+
16+
public struct PostDominatorTree {
17+
let bridged: BridgedPostDomTree
18+
}
19+
20+
extension BasicBlock {
21+
func postDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
22+
PostDominatorTree_postDominates(pdomTree.bridged, self.bridged, other.bridged) != 0
23+
}
24+
25+
func strictlyPostDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
26+
postDominates(other, pdomTree) && self != other
27+
}
28+
}

SwiftCompilerSources/Sources/Optimizer/PassManager/PassUtils.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ struct PassContext {
4141
return DeadEndBlocksAnalysis(bridged: bridgeDEA)
4242
}
4343

44+
var dominatorTree: DominatorTree {
45+
let bridgedDT = PassContext_getDomTree(_bridged)
46+
return DominatorTree(bridged: bridgedDT)
47+
}
48+
49+
var postDominatorTree: PostDominatorTree {
50+
let bridgedPDT = PassContext_getPostDomTree(_bridged)
51+
return PostDominatorTree(bridged: bridgedPDT)
52+
}
53+
4454
func notifyInstructionsChanged() {
4555
PassContext_notifyChanges(_bridged, instructionsChanged)
4656
}

include/swift/SILOptimizer/Analysis/DominanceAnalysis.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class DominanceAnalysis : public FunctionAnalysisBase<DominanceInfo> {
3636
DominanceAnalysis(const DominanceAnalysis &) = delete;
3737
DominanceAnalysis &operator=(const DominanceAnalysis &) = delete;
3838

39+
static SILAnalysisKind getAnalysisKind() {
40+
return SILAnalysisKind::Dominance;
41+
}
42+
3943
static bool classof(const SILAnalysis *S) {
4044
return S->getKind() == SILAnalysisKind::Dominance;
4145
}
@@ -65,6 +69,10 @@ class PostDominanceAnalysis : public FunctionAnalysisBase<PostDominanceInfo> {
6569
PostDominanceAnalysis(const PostDominanceAnalysis &) = delete;
6670
PostDominanceAnalysis &operator=(const PostDominanceAnalysis &) = delete;
6771

72+
static SILAnalysisKind getAnalysisKind() {
73+
return SILAnalysisKind::PostDominance;
74+
}
75+
6876
static bool classof(const SILAnalysis *S) {
6977
return S->getKind() == SILAnalysisKind::PostDominance;
7078
}

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ typedef struct {
4343
void * _Nullable dea;
4444
} BridgedDeadEndBlocksAnalysis;
4545

46+
typedef struct {
47+
void * _Nullable dt;
48+
} BridgedDomTree;
49+
50+
typedef struct {
51+
void * _Nullable pdt;
52+
} BridgedPostDomTree;
53+
4654
typedef struct {
4755
void * _Nonnull opaquePtr;
4856
unsigned char kind;
@@ -92,6 +100,18 @@ PassContext_getDeadEndBlocksAnalysis(BridgedPassContext context);
92100
SwiftInt DeadEndBlocksAnalysis_isDeadEnd(BridgedDeadEndBlocksAnalysis debAnalysis,
93101
BridgedBasicBlock);
94102

103+
BridgedDomTree PassContext_getDomTree(BridgedPassContext context);
104+
105+
SwiftInt DominatorTree_dominates(BridgedDomTree domTree,
106+
BridgedBasicBlock dominating,
107+
BridgedBasicBlock dominated);
108+
109+
BridgedPostDomTree PassContext_getPostDomTree(BridgedPassContext context);
110+
111+
SwiftInt PostDominatorTree_postDominates(BridgedPostDomTree pdomTree,
112+
BridgedBasicBlock dominating,
113+
BridgedBasicBlock dominated);
114+
95115
BridgedSlab PassContext_getNextSlab(BridgedSlab slab);
96116
BridgedSlab PassContext_getPreviousSlab(BridgedSlab slab);
97117
BridgedSlab PassContext_allocSlab(BridgedPassContext passContext,

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
2424
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
2525
#include "swift/SILOptimizer/Analysis/FunctionOrder.h"
26+
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
2627
#include "swift/SILOptimizer/OptimizerBridging.h"
2728
#include "swift/SILOptimizer/PassManager/PrettyStackTrace.h"
2829
#include "swift/SILOptimizer/PassManager/Transforms.h"
@@ -1249,6 +1250,32 @@ PassContext_getDeadEndBlocksAnalysis(BridgedPassContext context) {
12491250
return {pm->getAnalysis<DeadEndBlocksAnalysis>(invocation->getFunction())};
12501251
}
12511252

1253+
BridgedDomTree PassContext_getDomTree(BridgedPassContext context) {
1254+
SwiftPassInvocation *invocation = castToPassInvocation(context);
1255+
SILPassManager *pm = invocation->getPassManager();
1256+
return {pm->getAnalysis<DominanceAnalysis>(invocation->getFunction())};
1257+
}
1258+
1259+
SwiftInt DominatorTree_dominates(BridgedDomTree domTree,
1260+
BridgedBasicBlock dominating,
1261+
BridgedBasicBlock dominated) {
1262+
DominanceInfo *di = static_cast<DominanceInfo *>(domTree.dt);
1263+
return di->dominates(castToBasicBlock(dominating), castToBasicBlock(dominated)) ? 1 : 0;
1264+
}
1265+
1266+
BridgedPostDomTree PassContext_getPostDomTree(BridgedPassContext context) {
1267+
SwiftPassInvocation *invocation = castToPassInvocation(context);
1268+
SILPassManager *pm = invocation->getPassManager();
1269+
return {pm->getAnalysis<PostDominanceAnalysis>(invocation->getFunction())};
1270+
}
1271+
1272+
SwiftInt PostDominatorTree_postDominates(BridgedPostDomTree pdomTree,
1273+
BridgedBasicBlock dominating,
1274+
BridgedBasicBlock dominated) {
1275+
auto *pdi = static_cast<PostDominanceInfo *>(pdomTree.pdt);
1276+
return pdi->dominates(castToBasicBlock(dominating), castToBasicBlock(dominated)) ? 1 : 0;
1277+
}
1278+
12521279
BridgedBasicBlockSet PassContext_allocBasicBlockSet(BridgedPassContext context) {
12531280
return {castToPassInvocation(context)->allocBlockSet()};
12541281
}

0 commit comments

Comments
 (0)