Commit Graph

15 Commits

Author SHA1 Message Date
Stephen Heumann ccd653ddb9 Move some more code out of the blank segment to make space for static data. 2017-10-21 20:36:21 -05:00
Stephen Heumann 1502e48188 Fix bug causing incorrect code generation in programs that use the 'volatile' keyword.
This bug could both cause accesses to volatile variables to be omitted, and also cause other expressions to be erroneously optimized out in certain circumstances.

As an example, both the access of x and the call to bar() would be erroneously removed in the following program:

#pragma optimize 1
volatile int x;
int bar(void);
void foo(void)
{
    if(x) ;
    if(bar()) ;
}

Note that this patch disables even more optimizations than previously if the 'volatile' keyword is used anywhere in a translation unit. This is necessary for correctness given the current design of ORCA/C, but it means that care should be taken to avoid unnecessary use of 'volatile'.
2017-10-21 20:36:21 -05:00
Stephen Heumann 5c81d970b5 Fix issue where statically-evaluated conversions from floating-point values to some integer types could yield wrong values.
This occurred because the values were being rounded rather than truncated when converted to long, unsigned long, or unsigned int.

This was causing problems in the C6.2.3.5.CC test case when compiled with optimization.

The below program demonstrates the problem:

#pragma optimize 1
#include <stdio.h>
int main (void)
{
   long L;
   unsigned int ui;
   unsigned long ul;
   L = -1.5;
   ui = 1.5;
   ul = 1.5;
   printf("%li %u %lu\n", L, ui, ul); /* should print "-1 1 1" */
}
2017-10-21 20:36:21 -05:00
Stephen Heumann aa7084dada Fix problem where long basic blocks could lead to a crash due to stack overflow in common subexpression elimination.
The issue was that one of the procedures used for CSE would recursively call itself for every 'next' link in the code of the basic block. To avoid this, I made it loop back to the top instead (i.e. did a manual tail-call elimination transformation).

This problem could be observed with large switch statements as in the following example, although other codes with very large basic blocks might have triggered it too. Whether ORCA/C actually crashes will depend on the memory layout--in my testing, this example consistently caused it to crash when running under GNO:

#pragma optimize 16
int main (int argc, char **argv)
{
    switch (argc)
    {
        case 0:  case 1:  case 2:  case 3:  case 4:  case 5:  case 6:  case 7:
        case 8:  case 9:  case 10: case 11: case 12: case 13: case 14: case 15:
        case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
        case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
        case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39:
        case 40: case 41: case 42:
        case 262:
        ;
    }
}
2017-10-21 20:36:21 -05:00
Stephen Heumann 88279484af Generate better code when accessing structs and unions within other structures.
This cuts a few instructions from code like what is shown in commit affbe9. (It also works around the bug with that example, although that patch addresses the root cause of the problem.)
2017-10-21 20:36:20 -05:00
Stephen Heumann 953a7c36d5 Optimization to avoid generating unnecessary sign-extension code when converting UChar values to Long/ULong.
This ameliorates a performance regression due to promoting char to int instead of unsigned int.
2017-10-21 20:36:20 -05:00
Stephen Heumann cc75a9b12b Fix a problem where a conversion to a smaller type could be improperly omitted when followed by a conversion to a larger type.
This also fixes a logic error that may have permitted other conversions to be improperly omitted in some cases.

The following program demonstrates the problem (should print 211):

#pragma optimize 1
#include <stdio.h>
int main(void)
{
        unsigned int i = 1234;
        long l = (unsigned char)(i+1);
        printf("%li\n", l);
}
2017-10-21 20:36:20 -05:00
Stephen Heumann 0e82755334 Fix error that could happen when a function call was used in a comparison expression.
This resulted from the addition of the signed-to-unsigned comparison optimization. Specifically, it calls TypeOf for the expressions on each side of the comparison, and this did not handle function calls. That support has now been added, and will give the proper return type for direct and indirect calls to C functions. The IR for tool calls doesn't include the return type (just the number of bytes), so we return cgVoid for them. This is OK for the present use case.
2017-10-21 20:36:20 -05:00
Stephen Heumann dce39a851e Peephole optimization: fix some places where an expression with side effects could be removed during optimization.
Without this fix, an expression of the form "0 * exp" would be reduced to simply "0" unless exp contained a function call; other side effects of exp (such as assignments or increments) would be removed.

A similar issue could occur with additions that use the same expression on both sides of the "+": after optimization, it would only be evaluated once. I think the cases addressed here are all undefined behavior under the C standards, so the old behavior wasn't technically wrong, but the new behavior is still less confusing.
2017-10-21 20:36:20 -05:00
Stephen Heumann bd19465ab2 Fix so that reaching definitions are properly computed in loop optimization when there is unreachable code.
Specifically, this ensures that the depth-first numbering of basic blocks starts from 1, which is what ReachingDefinitions expects. Without this fix, reaching definitions wouldn't be correctly computed for functions that contain unreachable basic blocks (including the implicit one to return at the end). This could result in invalid hoisting of operations out of the loop.

This fixes the compca26.c test case.
2017-10-21 20:36:20 -05:00
Stephen Heumann 5ab7c7876b New optimization: Use unsigned rather than signed comparisons in some cases involving values that were originally unsigned bytes.
Specifically, convert signed word comparisons to unsigned if both sides were either unsigned byte values or non-negative constants. This is incorporated as part of intermediate code peephole optimization (bit 0).

This should alleviate some cases of performance regressions due to promoting char to int instead of unsigned int.
2017-10-21 20:36:20 -05:00
Stephen Heumann be91f1d1cc Disable an invalid optimization that would suppress stores of address values when they appeared to the left of the comma operator.
This fixes the compca22.c test case.

This optimization could be fixed and re-enabled, but to do so, you would have to check if the stored value is ever used subsequently, which is not information that's readily available in the peephole optimization pass. It would also be necessary to check if there are any stores to the same location within the right-side expression, which could kill the optimization.
2017-10-21 20:36:20 -05:00
Stephen Heumann b9446a28a7 Don't do common subexpression elimination for indirect accesses where there is an intervening operation that may write to the same location.
This fixes the bug in the compca05.c test case.
2017-10-21 20:36:20 -05:00
Stephen Heumann 46b6aa389f Change all text/source files to LF line endings. 2017-10-21 18:40:19 -05:00
mikew50 e72177985e ORCA/C 2.1.0 source from the Opus ][ CD 2017-10-01 17:47:47 -06:00