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

Reply via email to