The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
Strange Things with your Optimizer! (help)
Discuss Strange Things with your Optimizer! (help) in the C Programming forum on Dev Shed. Strange Things with your Optimizer! (help) C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

May 7th, 2012, 09:10 PM
|
|
Registered User
|
|
Join Date: Mar 2012
Posts: 18
Time spent in forums: 4 h 17 m 30 sec
Reputation Power: 0
|
|
|
Strange Things with your Optimizer! (help)
Have you ever had problems with the way your compiler optimize your code?
I have very strange things happening to my code and I suspect is the optimizer
(I am programming with HEW for a SuperH architecture)
For example a function like this:
Code:
static char bintochar(const int num)
{
char ch;
int elnum;
elnum=num&0x0F;
//num &= 0x0F;
if (0 <= elnum && elnum <= 9)
ch = '0' + elnum;
else if (10 <= elnum && elnum <= 15)
ch = 'A' + elnum - 10;
return ch;
}
originally it only used num (not elnum). Since it is passed by value it is supposed that num wouldnt change even if its copy were modified inside the function. Well, it changed!
Then I put the const (as above) and used another variable (elnum) so as to assure that num would not change but the optimizer eliminated my variable and again made the parameter (passed by value) changed! Isnt that against all rules in C?!
Another example
Code:
static void afunction(const int media)
{
int i;
char buf[16];
unsigned long *mc;
unsigned char uc;
unsigned long mcd;
mc = (unsigned long*) 0xa00000F0;
mcd = *mc; //HERE!!!!
buf[0] = 'M';
if(media==1)
//more code
else
//more code
//....more code
}
I debugged the code and found out that the optimizer made that the local variable mcd and the parameter media share the same memory region! (in fact the same register! therefore when I assign "mcd=*mc" not only mcd changes but media also changes!
I am finding all kinds of these strange things. Anyone has any idea why this is happening?
Thanks a lot in advance
Kansai
|

May 7th, 2012, 11:34 PM
|
 |
Contributing User
|
|
|
|
Have you tried various optimization levels?
And no. Your example does not violate every rule in c.
About your code, since elnum is a positive integer less than 16 why do you test to make sure it is bigger than or equal to 0?
if (0 <= elnum && elnum <= 9)
And if the previous condition failed is it possible for this condition to fail?
else if (10 <= elnum && elnum <= 15)
No, so don't bother with the tests.
But if both tests failed, then you'd return ch as an uninitialized data.
And that's just wrong.
How about
Code:
static char bintochar(const int num) {
return "0123456789ABCDEF"[num&0xF];
}
__________________
[code] Code tags[/code] are essential for python code!
|

May 8th, 2012, 12:10 AM
|
 |
Contributed User
|
|
|
|
|
> Anyone has any idea why this is happening?
Yes, your code is likely to broken somewhere.
Post a complete example which breaks when optimised. We can't tell anything from uncompilable snippets.
> (I am programming with HEW for a SuperH architecture)
It could be a compiler bug since you're using an embedded compiler. I've found a few myself when turning on optimisations.
But if it is a compiler bug, you should focus on producing a really simple test case you can send back to them.
|

May 8th, 2012, 12:55 AM
|
|
Registered User
|
|
Join Date: Mar 2012
Posts: 18
Time spent in forums: 4 h 17 m 30 sec
Reputation Power: 0
|
|
Thanks for your replies
Well, I found what was the mistake. Apparently it was one of these simple to make hard to find errors once you make them.
I was comparing the parameter "media" to see if it was one of two values but in the middle I mixed the values (0 or 1) which threw off the optimizer.
So I defined two values
Code:
#define FIRSTV 0
#define SECONDV 1
and use those instead of 0 and 1 consistently. This corrected the bug I had created. Guess I should have listened to people who says never to use just numbers but well defined constants instead... 
|

May 8th, 2012, 01:10 AM
|
 |
Contributed User
|
|
|
|
|

May 8th, 2012, 02:06 AM
|
|
Registered User
|
|
Join Date: Mar 2012
Posts: 18
Time spent in forums: 4 h 17 m 30 sec
Reputation Power: 0
|
|
Thank you but that does not qualify as a crosspost.
A crosspost is for example posting the same question in DevShed C forum and Java Forum.
Being that your post and this one is off-topic, that is the last I will say about this.
Thanks for your help again 
|

May 8th, 2012, 02:22 PM
|
 |
Contributing User
|
|
Join Date: Aug 2003
Location: UK
|
|
Quote: | Originally Posted by KansaiRobot Have you ever had problems with the way your compiler optimize your code? |
If the optimizer changes the behaviour of your code it is likley that your code is flawed or uses undefined behaviour. The most comon cause of failure when using an optimiser in embedded systems is failure to correctly declare variables volatile when necessary.
Quote: | Originally Posted by KansaiRobot Isnt that against all rules in C?! | No, not at all. The const is an indication by you to the compiler that the function will not explicitly modify the variable. If you write code that does that, the compiler will complain. However the optimizer performs abstract analysis to mathematically prove the redundancy of any variable allowing it to be eliminated entirely. If it does not change the semantics of the code, it is allowed.
Quote: | Originally Posted by KansaiRobot found out that the optimizer made that the local variable mcd and the parameter media share the same memory region! (in fact the same register! therefore when I assign "mcd=*mc" not only mcd changes but media also changes! | Optimisers are clever and complex things, and will eliminate variables, reorder code and re-use memory in ways that are hard to fathom. Attempting to step optimised code even at the assembler level in a debugger is seldom profitable for any purpose other than debugging the optimiser, and at the source level it is unlikely to make any sense whatsoever - debuggers cannot usually cope with optimised code in any meaningful manner.
The only test that is valid is whether the function generates the correct result for all valid input. If it does then your analysis of the optimiser behaviour is incomplete, if it does not then there either the code is semantically flawed or uses undefined behaviour, or possible, but least likely; the optimiser has a bug.
To get a feel for the complexity of optimisation take a look at this overview for example.
|

May 8th, 2012, 03:51 PM
|
|
|
Quote: | Originally Posted by KansaiRobot Thank you but that does not qualify as a crosspost.
A crosspost is for example posting the same question in DevShed C forum and Java Forum. |
Go home and dry behind your ears.
Cross Posting
|

May 8th, 2012, 07:38 PM
|
|
Registered User
|
|
Join Date: Mar 2012
Posts: 18
Time spent in forums: 4 h 17 m 30 sec
Reputation Power: 0
|
|
Thank you for your answer.
As you said, the code was flawed. (I indicated the flaw as well: by using numbers instead of constants, I have mistakenly mixed the two of them. Corrected it by using properly defined constants).
Since this is a forum for developers, I was hoping that someone would have had a similar experience, and would have indicated a likely mistake as you did. Thanks again.
(I am having another strange behaviour in a function in which some memory is being modified instead of another, but I suppose that is some other flaw somewhere...)
Quote: | Originally Posted by clifford If the optimizer changes the behaviour of your code it is likley that your code is flawed or uses undefined behaviour. The most comon cause of failure when using an optimiser in embedded systems is failure to correctly declare variables volatile when necessary.
No, not at all. The const is an indication by you to the compiler that the function will not explicitly modify the variable. If you write code that does that, the compiler will complain. However the optimizer performs abstract analysis to mathematically prove the redundancy of any variable allowing it to be eliminated entirely. If it does not change the semantics of the code, it is allowed.
Optimisers are clever and complex things, and will eliminate variables, reorder code and re-use memory in ways that are hard to fathom. Attempting to step optimised code even at the assembler level in a debugger is seldom profitable for any purpose other than debugging the optimiser, and at the source level it is unlikely to make any sense whatsoever - debuggers cannot usually cope with optimised code in any meaningful manner.
The only test that is valid is whether the function generates the correct result for all valid input. If it does then your analysis of the optimiser behaviour is incomplete, if it does not then there either the code is semantically flawed or uses undefined behaviour, or possible, but least likely; the optimiser has a bug.
To get a feel for the complexity of optimisation take a look at this overview for example. |
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|