17
17
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
18
18
#include " swift/SIL/SILArgument.h"
19
19
#include " swift/SIL/SILBuilder.h"
20
- #include " swift/SIL/CFG.h"
21
- #include " llvm/Support/GenericDomTree.h"
22
- #include " llvm/Support/GenericDomTreeConstruction.h"
23
20
#include " llvm/ADT/Statistic.h"
24
21
25
22
STATISTIC (NumStackPromoted, " Number of objects promoted to the stack" );
@@ -51,23 +48,9 @@ class StackPromoter {
51
48
SILFunction *F;
52
49
EscapeAnalysis::ConnectionGraph *ConGraph;
53
50
DominanceInfo *DT;
51
+ PostDominanceInfo *PDT;
54
52
EscapeAnalysis *EA;
55
53
56
- // We use our own post-dominator tree instead of PostDominatorAnalysis,
57
- // because we ignore unreachable blocks (actually all unreachable sub-graphs).
58
- // Example:
59
- // |
60
- // bb1
61
- // / \
62
- // unreachable bb2
63
- // \
64
- //
65
- // We want to get bb2 as immediate post-domiator of bb1. This is not the case
66
- // with the regualar post-dominator tree.
67
- llvm::DominatorTreeBase<SILBasicBlock> PostDomTree;
68
-
69
- bool PostDomTreeValid;
70
-
71
54
// Pseudo-functions for (de-)allocating array buffers on the stack.
72
55
73
56
SILFunction *BufferAllocFunc = nullptr ;
@@ -142,41 +125,25 @@ class StackPromoter {
142
125
}
143
126
144
127
bool strictlyPostDominates (SILBasicBlock *A, SILBasicBlock *B) {
145
- calculatePostDomTree ();
146
- return A != B && PostDomTree.dominates (A, B);
147
- }
148
-
149
- bool postDominates (SILBasicBlock *A, SILBasicBlock *B) {
150
- calculatePostDomTree ();
151
- return PostDomTree.dominates (A, B);
128
+ return A != B && PDT->dominates (A, B);
152
129
}
153
130
154
131
SILBasicBlock *getImmediatePostDom (SILBasicBlock *BB) {
155
- calculatePostDomTree ();
156
- auto *Node = PostDomTree.getNode (BB);
132
+ auto *Node = PDT->getNode (BB);
157
133
if (!Node)
158
134
return nullptr ;
159
135
auto *IDomNode = Node->getIDom ();
160
136
if (!IDomNode)
161
137
return nullptr ;
162
138
return IDomNode->getBlock ();
163
139
}
164
-
165
- void calculatePostDomTree () {
166
- if (!PostDomTreeValid) {
167
- // The StackPromoter acts as a "graph" for which the post-dominator-tree
168
- // is calculated.
169
- PostDomTree.recalculate (*this );
170
- PostDomTreeValid = true ;
171
- }
172
- }
173
140
174
141
public:
175
142
176
143
StackPromoter (SILFunction *F, EscapeAnalysis::ConnectionGraph *ConGraph,
177
- DominanceInfo *DT, EscapeAnalysis *EA) :
178
- F (F), ConGraph(ConGraph), DT(DT), EA(EA), PostDomTree( true ),
179
- PostDomTreeValid ( false ) { }
144
+ DominanceInfo *DT, PostDominanceInfo *PDT,
145
+ EscapeAnalysis *EA) :
146
+ F (F), ConGraph(ConGraph), DT(DT), PDT(PDT), EA(EA ) { }
180
147
181
148
// / What did the optimization change?
182
149
enum class ChangeState {
@@ -185,8 +152,6 @@ class StackPromoter {
185
152
Calls
186
153
};
187
154
188
- SILFunction *getFunction () const { return F; }
189
-
190
155
// / The main entry point for the optimization.
191
156
ChangeState promote ();
192
157
};
@@ -319,87 +284,6 @@ SILFunction *StackPromoter::getBufferDeallocFunc(SILFunction *OrigFunc,
319
284
return BufferDeallocFunc;
320
285
}
321
286
322
- namespace {
323
-
324
- // / Iterator which iterates over all basic blocks of a function which are not
325
- // / terminated by an unreachable inst.
326
- class NonUnreachableBlockIter :
327
- public std::iterator<std::forward_iterator_tag, SILBasicBlock, ptrdiff_t > {
328
-
329
- SILFunction::iterator BaseIterator;
330
- SILFunction::iterator End;
331
-
332
- void skipUnreachables () {
333
- while (true ) {
334
- if (BaseIterator == End)
335
- return ;
336
- if (!isa<UnreachableInst>(BaseIterator->getTerminator ()))
337
- return ;
338
- BaseIterator++;
339
- }
340
- }
341
-
342
- public:
343
- NonUnreachableBlockIter (SILFunction::iterator BaseIterator,
344
- SILFunction::iterator End) :
345
- BaseIterator (BaseIterator), End(End) {
346
- skipUnreachables ();
347
- }
348
-
349
- NonUnreachableBlockIter () = default ;
350
-
351
- SILBasicBlock &operator *() const { return *BaseIterator; }
352
- SILBasicBlock &operator ->() const { return *BaseIterator; }
353
-
354
- NonUnreachableBlockIter &operator ++() {
355
- BaseIterator++;
356
- skipUnreachables ();
357
- return *this ;
358
- }
359
-
360
- NonUnreachableBlockIter operator ++(int unused) {
361
- NonUnreachableBlockIter Copy = *this ;
362
- ++*this ;
363
- return Copy;
364
- }
365
-
366
- friend bool operator ==(NonUnreachableBlockIter lhs,
367
- NonUnreachableBlockIter rhs) {
368
- return lhs.BaseIterator == rhs.BaseIterator ;
369
- }
370
- friend bool operator !=(NonUnreachableBlockIter lhs,
371
- NonUnreachableBlockIter rhs) {
372
- return !(lhs == rhs);
373
- }
374
- };
375
- }
376
-
377
- namespace llvm {
378
-
379
- // / Use the StackPromoter as a wrapper for the function. It holds the list of
380
- // / basic blocks excluding all unreachable blocks.
381
- template <> struct GraphTraits <StackPromoter *>
382
- : public GraphTraits<swift::SILBasicBlock*> {
383
- typedef StackPromoter *GraphType;
384
-
385
- static NodeType *getEntryNode (GraphType SP) {
386
- return &SP->getFunction ()->front ();
387
- }
388
-
389
- typedef NonUnreachableBlockIter nodes_iterator;
390
- static nodes_iterator nodes_begin (GraphType SP) {
391
- return nodes_iterator (SP->getFunction ()->begin (), SP->getFunction ()->end ());
392
- }
393
- static nodes_iterator nodes_end (GraphType SP) {
394
- return nodes_iterator (SP->getFunction ()->end (), SP->getFunction ()->end ());
395
- }
396
- static unsigned size (GraphType SP) {
397
- return std::distance (nodes_begin (SP), nodes_end (SP));
398
- }
399
- };
400
-
401
- }
402
-
403
287
bool StackPromoter::canPromoteAlloc (SILInstruction *AI,
404
288
SILInstruction *&AllocInsertionPoint,
405
289
SILInstruction *&DeallocInsertionPoint) {
@@ -510,7 +394,7 @@ bool StackPromoter::canPromoteAlloc(SILInstruction *AI,
510
394
if (!Alloc)
511
395
return false ;
512
396
// This should always be the case, but let's be on the safe side.
513
- if (!postDominates (StartBlock, Alloc->getParent ()))
397
+ if (!PDT-> dominates (StartBlock, Alloc->getParent ()))
514
398
return false ;
515
399
AllocInsertionPoint = Alloc;
516
400
StackDepth++;
@@ -582,18 +466,20 @@ class StackPromotion : public SILFunctionTransform {
582
466
583
467
auto *EA = PM->getAnalysis <EscapeAnalysis>();
584
468
auto *DA = PM->getAnalysis <DominanceAnalysis>();
469
+ auto *PDA = PM->getAnalysis <PostDominanceAnalysis>();
585
470
586
471
SILFunction *F = getFunction ();
587
472
if (auto *ConGraph = EA->getConnectionGraph (F)) {
588
- StackPromoter promoter (F, ConGraph, DA->get (F), EA);
473
+ StackPromoter promoter (F, ConGraph, DA->get (F), PDA-> get (F), EA);
589
474
switch (promoter.promote ()) {
590
475
case StackPromoter::ChangeState::None:
591
476
break ;
592
477
case StackPromoter::ChangeState::Insts:
593
478
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
594
479
break ;
595
- case StackPromoter::ChangeState::Calls:
480
+ case StackPromoter::ChangeState::Calls: {
596
481
invalidateAnalysis (SILAnalysis::InvalidationKind::CallsAndInstructions);
482
+ }
597
483
break ;
598
484
}
599
485
}
0 commit comments