Skip to content

Commit ebf5cc6

Browse files
committed
[sil] Move PostOrderFunctionInfo from SILOptimizer/Analysis/PostOrderAnalysis => SIL/PostOrder.h.
There is already precedence for doing this via DominanceInfo. The reason I am doing this is that I need the ownership verifier to be able to be run in Raw SIL before no return folding has run. This means I need to be able to ignore unreachable code resulting from SILGen not inserting unreachables after no return functions. The reason why SILGen does this is to preserve the source information of the unreachable code so that we can emit nice errors about unreachable code. rdar://29791263
1 parent d539b67 commit ebf5cc6

File tree

2 files changed

+103
-62
lines changed

2 files changed

+103
-62
lines changed

include/swift/SIL/PostOrder.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===--- PostOrder.h --------------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
#ifndef SWIFT_SIL_POSTORDER_H
14+
#define SWIFT_SIL_POSTORDER_H
15+
16+
#include "swift/Basic/Range.h"
17+
#include "swift/SIL/CFG.h"
18+
#include "swift/SIL/SILBasicBlock.h"
19+
#include "swift/SIL/SILFunction.h"
20+
#include "swift/SILOptimizer/Analysis/Analysis.h"
21+
#include "llvm/ADT/DenseMap.h"
22+
#include "llvm/ADT/PostOrderIterator.h"
23+
#include "llvm/ADT/iterator_range.h"
24+
#include <vector>
25+
26+
namespace swift {
27+
28+
class PostOrderFunctionInfo {
29+
std::vector<SILBasicBlock *> PostOrder;
30+
llvm::DenseMap<SILBasicBlock *, unsigned> BBToPOMap;
31+
32+
public:
33+
PostOrderFunctionInfo(SILFunction *F) {
34+
for (auto *BB : make_range(po_begin(F), po_end(F))) {
35+
BBToPOMap[BB] = PostOrder.size();
36+
PostOrder.push_back(BB);
37+
}
38+
}
39+
40+
using iterator = decltype(PostOrder)::iterator;
41+
using const_iterator = decltype(PostOrder)::const_iterator;
42+
using reverse_iterator = decltype(PostOrder)::reverse_iterator;
43+
using const_reverse_iterator = decltype(PostOrder)::const_reverse_iterator;
44+
45+
using range = iterator_range<iterator>;
46+
using const_range = iterator_range<const_iterator>;
47+
using reverse_range = iterator_range<reverse_iterator>;
48+
using const_reverse_range = iterator_range<const_reverse_iterator>;
49+
50+
range getPostOrder() {
51+
return make_range(PostOrder.begin(), PostOrder.end());
52+
}
53+
const_range getPostOrder() const {
54+
return make_range(PostOrder.begin(), PostOrder.end());
55+
}
56+
reverse_range getReversePostOrder() {
57+
return make_range(PostOrder.rbegin(), PostOrder.rend());
58+
}
59+
const_reverse_range getReversePostOrder() const {
60+
return make_range(PostOrder.rbegin(), PostOrder.rend());
61+
}
62+
63+
const_reverse_range getReversePostOrder(SILBasicBlock *StartBlock) const {
64+
unsigned RPONumber = getRPONumber(StartBlock).getValue();
65+
return getReversePostOrder(RPONumber);
66+
}
67+
68+
const_reverse_range getReversePostOrder(unsigned RPONumber) const {
69+
return make_range(std::next(PostOrder.rbegin(), RPONumber),
70+
PostOrder.rend());
71+
}
72+
73+
using enumerated_range = EnumeratorRange<decltype(PostOrder)::iterator>;
74+
enumerated_range getEnumeratedPostOrder() { return enumerate(PostOrder); }
75+
using reverse_enumerated_range =
76+
EnumeratorRange<decltype(PostOrder)::reverse_iterator>;
77+
reverse_enumerated_range getEnumeratedReversePostOrder() {
78+
return enumerate(PostOrder.rbegin(), PostOrder.rend());
79+
}
80+
81+
unsigned size() const { return PostOrder.size(); }
82+
83+
Optional<unsigned> getPONumber(SILBasicBlock *BB) const {
84+
auto Iter = BBToPOMap.find(BB);
85+
if (Iter != BBToPOMap.end())
86+
return Iter->second;
87+
return None;
88+
}
89+
90+
Optional<unsigned> getRPONumber(SILBasicBlock *BB) const {
91+
auto Iter = BBToPOMap.find(BB);
92+
if (Iter != BBToPOMap.end())
93+
return PostOrder.size() - Iter->second - 1;
94+
return None;
95+
}
96+
};
97+
98+
} // end swift namespace
99+
100+
#endif

include/swift/SILOptimizer/Analysis/PostOrderAnalysis.h

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,81 +13,22 @@
1313
#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_POSTORDERANALYSIS_H
1414
#define SWIFT_SILOPTIMIZER_ANALYSIS_POSTORDERANALYSIS_H
1515

16-
#include "swift/SILOptimizer/Analysis/Analysis.h"
1716
#include "swift/Basic/Range.h"
1817
#include "swift/SIL/CFG.h"
18+
#include "swift/SIL/PostOrder.h"
1919
#include "swift/SIL/SILBasicBlock.h"
2020
#include "swift/SIL/SILFunction.h"
21+
#include "swift/SILOptimizer/Analysis/Analysis.h"
22+
#include "llvm/ADT/DenseMap.h"
2123
#include "llvm/ADT/PostOrderIterator.h"
2224
#include "llvm/ADT/iterator_range.h"
23-
#include "llvm/ADT/DenseMap.h"
2425
#include <vector>
2526

2627
namespace swift {
2728

2829
class SILBasicBlock;
2930
class SILFunction;
3031

31-
class PostOrderFunctionInfo {
32-
std::vector<SILBasicBlock *> PostOrder;
33-
llvm::DenseMap<SILBasicBlock *, unsigned> BBToPOMap;
34-
35-
public:
36-
PostOrderFunctionInfo(SILFunction *F) {
37-
for (auto *BB : make_range(po_begin(F), po_end(F))) {
38-
BBToPOMap[BB] = PostOrder.size();
39-
PostOrder.push_back(BB);
40-
}
41-
}
42-
43-
using iterator = decltype(PostOrder)::iterator;
44-
using const_iterator = decltype(PostOrder)::const_iterator;
45-
using reverse_iterator = decltype(PostOrder)::reverse_iterator;
46-
using const_reverse_iterator = decltype(PostOrder)::const_reverse_iterator;
47-
48-
using range = iterator_range<iterator>;
49-
using const_range = iterator_range<const_iterator>;
50-
using reverse_range = iterator_range<reverse_iterator>;
51-
using const_reverse_range = iterator_range<const_reverse_iterator>;
52-
53-
range getPostOrder() {
54-
return make_range(PostOrder.begin(), PostOrder.end());
55-
}
56-
const_range getPostOrder() const {
57-
return make_range(PostOrder.begin(), PostOrder.end());
58-
}
59-
reverse_range getReversePostOrder() {
60-
return make_range(PostOrder.rbegin(), PostOrder.rend());
61-
}
62-
const_reverse_range getReversePostOrder() const {
63-
return make_range(PostOrder.rbegin(), PostOrder.rend());
64-
}
65-
66-
using enumerated_range = EnumeratorRange<decltype(PostOrder)::iterator>;
67-
enumerated_range getEnumeratedPostOrder() { return enumerate(PostOrder); }
68-
using reverse_enumerated_range =
69-
EnumeratorRange<decltype(PostOrder)::reverse_iterator>;
70-
reverse_enumerated_range getEnumeratedReversePostOrder() {
71-
return enumerate(PostOrder.rbegin(), PostOrder.rend());
72-
}
73-
74-
unsigned size() const { return PostOrder.size(); }
75-
76-
Optional<unsigned> getPONumber(SILBasicBlock *BB) const {
77-
auto Iter = BBToPOMap.find(BB);
78-
if (Iter != BBToPOMap.end())
79-
return Iter->second;
80-
return None;
81-
}
82-
83-
Optional<unsigned> getRPONumber(SILBasicBlock *BB) const {
84-
auto Iter = BBToPOMap.find(BB);
85-
if (Iter != BBToPOMap.end())
86-
return PostOrder.size() - Iter->second - 1;
87-
return None;
88-
}
89-
};
90-
9132
/// This class is a simple wrapper around the POT iterator provided by LLVM. It
9233
/// lazily re-evaluates the post order when it is invalidated so that we do not
9334
/// reform the post order over and over again (it can be expensive).

0 commit comments

Comments
 (0)