Skip to content

Commit 458cf3e

Browse files
committed
Merging r155817:
------------------------------------------------------------------------ r155817 | void | 2012-04-30 03:44:54 -0700 (Mon, 30 Apr 2012) | 9 lines Second attempt at PR12573: Allow the "SplitCriticalEdge" function to split the edge to a landing pad. If the pass is *sure* that it thinks it knows what it's doing, then it may go ahead and specify that the landing pad can have its critical edge split. The loop unswitch pass is one of these passes. It will split the critical edges of all edges coming from a loop to a landing pad not within the loop. Doing so will retain important loop analysis information, such as loop simplify. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_31@155833 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b394a7b commit 458cf3e

File tree

4 files changed

+131
-14
lines changed

4 files changed

+131
-14
lines changed

include/llvm/Transforms/Utils/BasicBlockUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
110110
///
111111
BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
112112
Pass *P = 0, bool MergeIdenticalEdges = false,
113-
bool DontDeleteUselessPHIs = false);
113+
bool DontDeleteUselessPHIs = false,
114+
bool SplitLandingPads = false);
114115

115116
inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
116117
Pass *P = 0) {

lib/Transforms/Scalar/LoopUnswitch.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,8 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
687687

688688
// If either edge is critical, split it. This helps preserve LoopSimplify
689689
// form for enclosing loops.
690-
SplitCriticalEdge(BI, 0, this);
691-
SplitCriticalEdge(BI, 1, this);
690+
SplitCriticalEdge(BI, 0, this, false, false, true);
691+
SplitCriticalEdge(BI, 1, this, false, false, true);
692692
}
693693

694694
/// UnswitchTrivialCondition - Given a loop that has a trivial unswitchable

lib/Transforms/Utils/BreakCriticalEdges.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,31 +119,36 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
119119

120120
/// CreatePHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form
121121
/// may require new PHIs in the new exit block. This function inserts the
122-
/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB
122+
/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB
123123
/// is the new loop exit block, and DestBB is the old loop exit, now the
124124
/// successor of SplitBB.
125125
static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds,
126126
BasicBlock *SplitBB,
127127
BasicBlock *DestBB) {
128128
// SplitBB shouldn't have anything non-trivial in it yet.
129-
assert(SplitBB->getFirstNonPHI() == SplitBB->getTerminator() &&
130-
"SplitBB has non-PHI nodes!");
129+
assert((SplitBB->getFirstNonPHI() == SplitBB->getTerminator() ||
130+
SplitBB->isLandingPad()) && "SplitBB has non-PHI nodes!");
131131

132-
// For each PHI in the destination block...
132+
// For each PHI in the destination block.
133133
for (BasicBlock::iterator I = DestBB->begin();
134134
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
135135
unsigned Idx = PN->getBasicBlockIndex(SplitBB);
136136
Value *V = PN->getIncomingValue(Idx);
137+
137138
// If the input is a PHI which already satisfies LCSSA, don't create
138139
// a new one.
139140
if (const PHINode *VP = dyn_cast<PHINode>(V))
140141
if (VP->getParent() == SplitBB)
141142
continue;
143+
142144
// Otherwise a new PHI is needed. Create one and populate it.
143-
PHINode *NewPN = PHINode::Create(PN->getType(), Preds.size(), "split",
144-
SplitBB->getTerminator());
145+
PHINode *NewPN =
146+
PHINode::Create(PN->getType(), Preds.size(), "split",
147+
SplitBB->isLandingPad() ?
148+
SplitBB->begin() : SplitBB->getTerminator());
145149
for (unsigned i = 0, e = Preds.size(); i != e; ++i)
146150
NewPN->addIncoming(V, Preds[i]);
151+
147152
// Update the original PHI.
148153
PN->setIncomingValue(Idx, NewPN);
149154
}
@@ -168,7 +173,8 @@ static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds,
168173
///
169174
BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
170175
Pass *P, bool MergeIdenticalEdges,
171-
bool DontDeleteUselessPhis) {
176+
bool DontDeleteUselessPhis,
177+
bool SplitLandingPads) {
172178
if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0;
173179

174180
assert(!isa<IndirectBrInst>(TI) &&
@@ -371,10 +377,19 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
371377
// getUniqueExitBlocks above because that depends on LoopSimplify
372378
// form, which we're in the process of restoring!
373379
if (!Preds.empty() && HasPredOutsideOfLoop) {
374-
BasicBlock *NewExitBB =
375-
SplitBlockPredecessors(Exit, Preds, "split", P);
376-
if (P->mustPreserveAnalysisID(LCSSAID))
377-
CreatePHIsForSplitLoopExit(Preds, NewExitBB, Exit);
380+
if (!Exit->isLandingPad()) {
381+
BasicBlock *NewExitBB =
382+
SplitBlockPredecessors(Exit, Preds, "split", P);
383+
if (P->mustPreserveAnalysisID(LCSSAID))
384+
createPHIsForSplitLoopExit(Preds, NewExitBB, Exit);
385+
} else if (SplitLandingPads) {
386+
SmallVector<BasicBlock*, 8> NewBBs;
387+
SplitLandingPadPredecessors(Exit, Preds,
388+
".split1", ".split2",
389+
P, NewBBs);
390+
if (P->mustPreserveAnalysisID(LCSSAID))
391+
createPHIsForSplitLoopExit(Preds, NewBBs[0], Exit);
392+
}
378393
}
379394
}
380395
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
; RUN: opt < %s -basicaa -instcombine -inline -functionattrs -licm -loop-unswitch -gvn -verify
2+
; PR12573
3+
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
4+
target triple = "x86_64-apple-macosx10.7.0"
5+
6+
%class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379 = type { %class.C.23.43.67.103.139.159.179.199.239.243.247.251.263.295.303.339.347.376*, %class.B.21.41.65.101.137.157.177.197.237.241.245.249.261.293.301.337.345.378 }
7+
%class.C.23.43.67.103.139.159.179.199.239.243.247.251.263.295.303.339.347.376 = type { %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* }
8+
%class.B.21.41.65.101.137.157.177.197.237.241.245.249.261.293.301.337.345.378 = type { %class.A.20.40.64.100.136.156.176.196.236.240.244.248.260.292.300.336.344.377* }
9+
%class.A.20.40.64.100.136.156.176.196.236.240.244.248.260.292.300.336.344.377 = type { i8 }
10+
11+
define void @_Z23get_reconstruction_pathv() uwtable ssp {
12+
entry:
13+
%c = alloca %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379, align 8
14+
br label %for.cond
15+
16+
for.cond: ; preds = %for.end, %entry
17+
invoke void @_ZN1DptEv(%class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* %c)
18+
to label %invoke.cont unwind label %lpad
19+
20+
invoke.cont: ; preds = %for.cond
21+
invoke void @_ZN1C3endEv()
22+
to label %for.cond3 unwind label %lpad
23+
24+
for.cond3: ; preds = %invoke.cont6, %invoke.cont
25+
invoke void @_ZN1DptEv(%class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* %c)
26+
to label %invoke.cont4 unwind label %lpad
27+
28+
invoke.cont4: ; preds = %for.cond3
29+
invoke void @_ZN1C3endEv()
30+
to label %invoke.cont6 unwind label %lpad
31+
32+
invoke.cont6: ; preds = %invoke.cont4
33+
br i1 undef, label %for.cond3, label %for.end
34+
35+
lpad: ; preds = %for.end, %invoke.cont4, %for.cond3, %invoke.cont, %for.cond
36+
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
37+
cleanup
38+
resume { i8*, i32 } undef
39+
40+
for.end: ; preds = %invoke.cont6
41+
invoke void @_ZN1C13_M_insert_auxER1D()
42+
to label %for.cond unwind label %lpad
43+
}
44+
45+
define void @_ZN1DptEv(%class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* %this) uwtable ssp align 2 {
46+
entry:
47+
%this.addr = alloca %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379*, align 8
48+
store %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* %this, %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379** %this.addr, align 8, !tbaa !0
49+
%this1 = load %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379** %this.addr
50+
%px = getelementptr inbounds %class.D.22.42.66.102.138.158.178.198.238.242.246.250.262.294.302.338.346.379* %this1, i32 0, i32 0
51+
%0 = load %class.C.23.43.67.103.139.159.179.199.239.243.247.251.263.295.303.339.347.376** %px, align 8, !tbaa !0
52+
%tobool = icmp ne %class.C.23.43.67.103.139.159.179.199.239.243.247.251.263.295.303.339.347.376* %0, null
53+
br i1 %tobool, label %cond.end, label %cond.false
54+
55+
cond.false: ; preds = %entry
56+
call void @_Z10__assert13v() noreturn
57+
unreachable
58+
59+
cond.end: ; preds = %entry
60+
ret void
61+
}
62+
63+
declare i32 @__gxx_personality_v0(...)
64+
65+
declare void @_ZN1C3endEv()
66+
67+
define void @_ZN1C13_M_insert_auxER1D() uwtable ssp align 2 {
68+
entry:
69+
ret void
70+
}
71+
72+
define void @_ZN1DD1Ev() unnamed_addr uwtable inlinehint ssp align 2 {
73+
entry:
74+
ret void
75+
}
76+
77+
define void @_ZN1DD2Ev() unnamed_addr uwtable inlinehint ssp align 2 {
78+
entry:
79+
ret void
80+
}
81+
82+
define void @_ZN1BD1Ev() unnamed_addr uwtable ssp align 2 {
83+
entry:
84+
ret void
85+
}
86+
87+
define void @_ZN1BD2Ev() unnamed_addr uwtable ssp align 2 {
88+
entry:
89+
ret void
90+
}
91+
92+
define void @_ZN1BaSERS_() uwtable ssp align 2 {
93+
entry:
94+
unreachable
95+
}
96+
97+
declare void @_Z10__assert13v() noreturn
98+
99+
!0 = metadata !{metadata !"any pointer", metadata !1}
100+
!1 = metadata !{metadata !"omnipotent char", metadata !2}
101+
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}

0 commit comments

Comments
 (0)