wolfgangp created this revision. wolfgangp added a subscriber: cfe-commits.
Currently nested if statements can generate empty BB's whose terminator simply branches unconditionally to its successor. These branches are not eliminated by LLVM (r154417) in order to help generate better line number information in certain cases, specifically empty breaks in switch statements (r154420). However, there is no need to keep the empty blocks that result from nested ifs around, as there is no corresponding source construct that would benefit from better line info. The patch proposes to remove such blocks when they result directly from nested ifs. Consider the following case: /************************** void func() {} int bar(int val) { if (val == 0) { func(); } else if (val == 1) { func(); // line 12 } return 0; } int main() { return bar(0); } //************************ The resulting IR for bar is ... define i32 @bar(i32 %val) #0 { entry: %retval = alloca i32, align 4 %val.addr = alloca i32, align 4 store i32 %val, i32* %val.addr, align 4 %0 = load i32, i32* %val.addr, align 4 %cmp = icmp eq i32 %0, 0 br i1 %cmp, label %if.then, label %if.else if.then: ; preds = %entry store i32 1, i32* %retval br label %return if.else: ; preds = %entry %1 = load i32, i32* %val.addr, align 4 %cmp1 = icmp eq i32 %1, 1 br i1 %cmp1, label %if.then.2, label %if.end if.then.2: ; preds = %if.else call void (...) @func() br label %if.end if.end: ; preds = %if.then.2, %if.else <============== br label %if.end.3 <============== if.end.3: ; preds = %if.end store i32 0, i32* %retval br label %return return: ; preds = %if.end.3, %if.then %2 = load i32, i32* %retval ret i32 %2 } ... if.end would be eliminated with the patch applied. The idea is that nested ifs with no else branches will generate an empty block, which can be eliminated at the outer level. http://reviews.llvm.org/D11360 Files: lib/CodeGen/CGStmt.cpp test/CodeGen/forwarding-blocks-if.c Index: test/CodeGen/forwarding-blocks-if.c =================================================================== --- test/CodeGen/forwarding-blocks-if.c +++ test/CodeGen/forwarding-blocks-if.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// Check that no empty blocks are generated for nested ifs. + +extern void func(); + +int f0(int val) +{ + if (val == 0) + { + func(); + } + else if (val == 1) + { + func(); + } + return 0; +} + +// CHECK-LABEL: define i32 @f0 +// CHECK: if.end{{.*:}} +// CHECK-NOT: br label +// CHECK: ret i32 + + +int f1(int val, int g) +{ + if (val == 0) + if (g == 1) + { + func(); + } + return 0; +} + +// CHECK-LABEL: define i32 @f1 +// CHECK: if.end{{.*:}} +// CHECK-NOT: br label +// CHECK: ret i32 Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -566,7 +566,12 @@ RunCleanupsScope ThenScope(*this); EmitStmt(S.getThen()); } - EmitBranch(ContBlock); + { + auto CurBlock = Builder.GetInsertBlock(); + EmitBranch(ContBlock); + if (CurBlock) + SimplifyForwardingBlocks(CurBlock); + } // Emit the 'else' code if present. if (const Stmt *Else = S.getElse()) { @@ -582,7 +587,10 @@ { // There is no need to emit line number for an unconditional branch. auto NL = ApplyDebugLocation::CreateEmpty(*this); + auto CurBlock = Builder.GetInsertBlock(); EmitBranch(ContBlock); + if (CurBlock) + SimplifyForwardingBlocks(CurBlock); } }
Index: test/CodeGen/forwarding-blocks-if.c =================================================================== --- test/CodeGen/forwarding-blocks-if.c +++ test/CodeGen/forwarding-blocks-if.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// Check that no empty blocks are generated for nested ifs. + +extern void func(); + +int f0(int val) +{ + if (val == 0) + { + func(); + } + else if (val == 1) + { + func(); + } + return 0; +} + +// CHECK-LABEL: define i32 @f0 +// CHECK: if.end{{.*:}} +// CHECK-NOT: br label +// CHECK: ret i32 + + +int f1(int val, int g) +{ + if (val == 0) + if (g == 1) + { + func(); + } + return 0; +} + +// CHECK-LABEL: define i32 @f1 +// CHECK: if.end{{.*:}} +// CHECK-NOT: br label +// CHECK: ret i32 Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -566,7 +566,12 @@ RunCleanupsScope ThenScope(*this); EmitStmt(S.getThen()); } - EmitBranch(ContBlock); + { + auto CurBlock = Builder.GetInsertBlock(); + EmitBranch(ContBlock); + if (CurBlock) + SimplifyForwardingBlocks(CurBlock); + } // Emit the 'else' code if present. if (const Stmt *Else = S.getElse()) { @@ -582,7 +587,10 @@ { // There is no need to emit line number for an unconditional branch. auto NL = ApplyDebugLocation::CreateEmpty(*this); + auto CurBlock = Builder.GetInsertBlock(); EmitBranch(ContBlock); + if (CurBlock) + SimplifyForwardingBlocks(CurBlock); } }
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits