public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/54742] New: Switch elimination in FSM loop
@ 2012-09-29  3:16 joey.ye at arm dot com
  2012-09-29  3:21 ` [Bug tree-optimization/54742] " pinskia at gcc dot gnu.org
                   ` (39 more replies)
  0 siblings, 40 replies; 41+ messages in thread
From: joey.ye at arm dot com @ 2012-09-29  3:16 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54742

             Bug #: 54742
           Summary: Switch elimination in FSM loop
    Classification: Unclassified
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: joey.ye@arm.com


Following interesting case is reduced from a benchmark. It implements a FSM
with a loop and switch. There is opportunity to eliminate the switch since all
state transition is definite in compile time.


Source program:
---
int sum0, sum1, sum2, sum3;
int foo(const char * str)
{
    int state=0;
    const char *s=str;

    for (; *s; s++)
    {
        char c=*s;
        switch (state) {
            case 0:
                if (c == '+') state = 1;
                else if (c != '-') sum0+=c;
                break;
            case 1:
                if (c == '+') state = 2;
                else if (c == '-') state = 0;
                else sum1+=c;
                break;
            case 2:
                if (c == '+') state = 3;
                else if (c == '-') state = 1;
                else sum2+=c;
                break;
            case 3:
                if (c == '-') state = 2;
                else if (c != '+') sum3+=c;
                break;
            default:
                break;
        }
    }
    return state;
}
---
Say, instead of setting state=1 and loop back to switch head, it can be
optimized to setting state=1, check loop end condition and jump directly to the
label of case_1. Thus the overhead of switch (either if-then-else or jump
table) is eliminated. On machine without sophisticate branch prediction, such
an optimization is even more appealing.

GCC trunk 4.8 doesn't have such a optimization.

Expected tree output in source form:
---
int sum0, sum1, sum2, sum3;
int foo(const char * str)
{
    int state=0;
    const char *s=str;
    char c=*s;
    if (!c) goto end;
state_0:
    if (c == '+') {
        state = 1;
        if ((c=* (++s))!=0) goto state_1;   // Check loop end condition and go
directly to next state
        else goto end;
    }
    else if (c != '-') sum0+=c;
    if ((c=* (++s))!=0) goto state_0;
    goto end;

state_1:
    if (c == '+') {
        state = 2;
        if ((c=* (++s))!=0) goto state_2;
        else goto end;
    }
    else if (c == '-') {
        state = 0;
        if ((c=* (++s))!=0) goto state_0;
        else goto end;
    }
    else sum1+=c;
    if ((c=* (++s))!=0) goto state_1;
    goto end;

state_2:
    if (c == '+') {
        state = 3;
        if ((c=* (++s))!=0) goto state_3;
        else goto end;
    }
    else if (c == '-') {
        state = 1;
        if ((c=* (++s))!=0) goto state_1;
        else goto end;
    }
    else sum1+=c;
    if ((c=* (++s))!=0) goto state_2;
    goto end;

state_3:
    if (c == '-') {
        state = 2;
        if ((c=* (++s))!=0) goto state_2;
        else goto end;
    }
    else if (c != '+') sum3+=c;
    if ((c=* (++s))!=0) goto state_3;
end:
    return state;
}
---


^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2023-12-15 18:21 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-29  3:16 [Bug tree-optimization/54742] New: Switch elimination in FSM loop joey.ye at arm dot com
2012-09-29  3:21 ` [Bug tree-optimization/54742] " pinskia at gcc dot gnu.org
2012-10-01 10:19 ` rguenth at gcc dot gnu.org
2012-10-10  7:37 ` joey.ye at arm dot com
2013-02-19 10:27 ` rguenth at gcc dot gnu.org
2013-03-04  8:27 ` venkataramanan.kumar at amd dot com
2013-03-04  8:34 ` venkataramanan.kumar at amd dot com
2013-03-04 16:56 ` law at redhat dot com
2013-03-08  3:56 ` joey.ye at arm dot com
2013-05-02  0:11 ` sje at gcc dot gnu.org
2013-11-20  7:23 ` law at redhat dot com
2013-11-20  7:23 ` StaffLeavers at arm dot com
2013-11-20  7:24 ` StaffLeavers at arm dot com
2013-11-20  7:25 ` StaffLeavers at arm dot com
2013-11-20  7:26 ` StaffLeavers at arm dot com
2013-11-20  7:26 ` StaffLeavers at arm dot com
2013-11-20  7:26 ` StaffLeavers at arm dot com
2013-11-20  7:26 ` StaffLeavers at arm dot com
2013-11-20  7:27 ` StaffLeavers at arm dot com
2013-11-20  7:27 ` StaffLeavers at arm dot com
2013-11-20  7:28 ` StaffLeavers at arm dot com
2013-11-20  7:28 ` StaffLeavers at arm dot com
2013-11-20  7:28 ` StaffLeavers at arm dot com
2013-11-20  7:29 ` StaffLeavers at arm dot com
2013-11-20  7:31 ` StaffLeavers at arm dot com
2013-11-22 19:30 ` law at redhat dot com
2013-11-27 12:11 ` jgreenhalgh at gcc dot gnu.org
2013-11-27 12:15 ` jgreenhalgh at gcc dot gnu.org
2013-12-11 18:43 ` izamyatin at gmail dot com
2013-12-11 18:48 ` law at redhat dot com
2013-12-12 11:22 ` izamyatin at gmail dot com
2013-12-13 11:05 ` rguenth at gcc dot gnu.org
2013-12-25 13:48 ` izamyatin at gmail dot com
2014-02-17 10:07 ` joey.ye at arm dot com
2014-02-19 11:22 ` joey.ye at arm dot com
2014-06-28 15:45 ` spop at gcc dot gnu.org
2014-08-12 22:49 ` sje at gcc dot gnu.org
2014-12-06 19:20 ` spop at gcc dot gnu.org
2014-12-06 19:23 ` spop at gcc dot gnu.org
2015-01-14 10:23 ` yroux at gcc dot gnu.org
2023-12-15 18:21 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).