[PATCH] D14122: [SimplifyCFG] Trim duplicate basic blocks in switch cases
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 28 17:00:59 PDT 2015
sanjoy requested changes to this revision.
This revision now requires changes to proceed.
================
Comment at: include/llvm/IR/BasicBlock.h:318
@@ -317,1 +317,3 @@
+ /// Checks if the bodies of two basic blocks are identical.
+ bool isIdenticalTo(const BasicBlock &Other) const;
----------------
Prefix the sentence with a `\brief` like in the other methods.
================
Comment at: lib/IR/BasicBlock.cpp:453
@@ +452,3 @@
+ assert(Cur1 == this->end() && Cur2 == Other.end() &&
+ "we should've handled this earlier");
+
----------------
Nit: spacing.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3411
@@ +3410,3 @@
+static bool EliminateDuplicateSwitchSuccessors(SwitchInst *SI, AssumptionCache *AC,
+ const DataLayout &DL) {
+
----------------
Why do you need `AC` and `DL`?
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3462
@@ -3418,3 +3461,3 @@
BasicBlock::iterator I = Succ->begin();
while (PHINode *PHI = dyn_cast<PHINode>(I++)) {
int Idx = PHI->getBasicBlockIndex(BB);
----------------
dylanmckay wrote:
> Does it really have a new incoming block? The block that contains the switch statement will still be the successor because all case statements are apart of the same basic block?
>
> It is highly likely that I am misunderstanding, however.
PHI nodes have to have an entry for each incoming edge -- if multiple
edges come from the same predecessor then you need multiple entries in
the PHI node for that predecessor (all of which should have the same
incoming value).
So if you start with
```
declare void @foo()
define void @main(i1 %c) {
entry:
br i1 %c, label %match_case2, label %sw
sw:
%value = alloca i32
store i32 5, i32* %value
%val = load i32, i32* %value
switch i32 %val, label %join [
i32 1, label %match_case
i32 48, label %match_case1
i32 92, label %match_case2
i32 23, label %match_case3
]
match_case:
call void @foo()
unreachable
match_case1:
call void @foo()
unreachable
match_case2:
%x = phi i32 [ 10, %entry ], [ 20, %sw ]
call void @foo()
unreachable
match_case3:
call void @foo()
unreachable
join:
ret void
}
```
transforming it to
```
declare void @foo()
define void @main(i1 %c) {
entry:
br i1 %c, label %match_case2, label %sw
sw:
%value = alloca i32
store i32 5, i32* %value
%val = load i32, i32* %value
switch i32 %val, label %join [
i32 1, label %match_case
i32 48, label %match_case1
i32 92, label %match_case2
i32 23, label %match_case2 ;; change here
]
match_case:
call void @foo()
unreachable
match_case1:
call void @foo()
unreachable
match_case2:
%x = phi i32 [ 10, %entry ], [ 20, %sw ]
call void @foo()
unreachable
match_case3:
call void @foo()
unreachable
join:
ret void
}
```
is incorrect (i.e. you'll fail verification) -- you also need to update `%x` to be `phi i32 [ 10, %entry ], [ 20, %sw ], [ 20, %sw ]`.
http://reviews.llvm.org/D14122
More information about the llvm-commits
mailing list