This is an archive of the discontinued LLVM Phabricator instance.

Proposed patch to prevent the creation of empty (forwarding) blocks resulting from nested ifs.
ClosedPublic

Authored by wolfgangp on Jul 20 2015, 11:07 AM.

Details

Summary

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.

Diff Detail

Event Timeline

wolfgangp updated this revision to Diff 30168.Jul 20 2015, 11:07 AM
wolfgangp retitled this revision from to Proposed patch to prevent the creation of empty (forwarding) blocks resulting from nested ifs..
wolfgangp updated this object.
wolfgangp added a subscriber: cfe-commits.
wolfgangp updated this revision to Diff 61987.Jun 27 2016, 11:36 AM

Updating this patch against a recent revision.

mehdi_amini added inline comments.Jul 5 2016, 3:57 PM
lib/CodeGen/CGStmt.cpp
614

Document

634

Document

test/CodeGen/forwarding-blocks-if.c
18

Any reason to not stick with LLVM coding convention here?

wolfgangp updated this revision to Diff 62916.Jul 6 2016, 11:09 AM

Addressed review comments: documented changes and clang-formatted the test case.

test/CodeGen/forwarding-blocks-if.c
18

No reason, thanks for pointing this out.

mehdi_amini accepted this revision.Jul 7 2016, 6:15 PM
mehdi_amini added a reviewer: mehdi_amini.

LGTM.

This revision is now accepted and ready to land.Jul 7 2016, 6:15 PM
wolfgangp closed this revision.Jul 13 2016, 5:01 PM

This is committed r275115 for the record.

Phabricator will automatically close it if the last line is "Differential Revision: ..." (You put "Differential review: ..." instead).