public inbox for crossgcc@sourceware.org
 help / color / mirror / Atom feed
* Disabling local optimizations with GCC
@ 2000-06-28 20:09 Christopher Bahns
  2000-06-28 20:49 ` Art Berggreen
  2000-06-29  6:50 ` SH-2 also -> " John Mills
  0 siblings, 2 replies; 5+ messages in thread
From: Christopher Bahns @ 2000-06-28 20:09 UTC (permalink / raw)
  To: crossgcc

Hello,

Anyone know how to take advantage of most of GCC's optimizations without
it performing certain local optimizations? I read through the -O and -f
options in the gcc manual and did not see anything specifically just for
local optimizations. There is the "-fgcse" (global common
subexpressions) but I guess this would not apply to commonizing
subexpressions locally within a function... don't really know. I did not
see any "-flcse" or similar option.

Here's my problem:
I'm using a cross-compiler under Windows 98/NT for an m68k-coff target
(MC68306). I have certain symbols mapped to specific hardware addresses
so that I can interact with the hardware (as I assume most would do it).
In some cases I assign different values to the same address in
succession, or intermixed with the assignment of values to other
addresses. It is important for all assignments to occur because each one
causes the hardware to perform a particular action, and all actions need
to occur in the order I've placed them in the C-language functions. The
problem is that with any GCC optimization level  (-O, -O1, -O2, or -O3),
it "optimizes" out all but the last assignment to a given location. This
causes my program not to work. Everything seems to be fine if I disable
all optimizations, but some parts of my program are time-critical and I
may need some of the optimizations for the program to work right.

Of course, I can choose to disable all optimizations except the ones
that I specify explicitly with "-f" options, but I'd prefer to have as
many enabled as possible without breaking my program.

Here is some example code:
_____________________________________________________________
/* duart's base i/o address */
#define IoPortAddr   ((BYTE*)0xa0001)

void InitDuart681(void)
{
   /* disable transmitter and receiver */
   IoPortAddr[DUCRA] = ((0x0 << 4) | (0x2 << 2) | 0x2);
   IoPortAddr[DUCRB] = ((0x0 << 4) | (0x2 << 2) | 0x2);

   /* reset UartA transmitter and receiver */
   IoPortAddr[DUCRA] = (0x2 << 4);
   IoPortAddr[DUCRA] = (0x3 << 4);

   /* make sure we're not in break */
   IoPortAddr[DUCRA] = (0x7 << 4);
   IoPortAddr[DUCRA] = (0x5 << 4);

   /* reset error status */
   IoPortAddr[DUCRA] = (0x4 << 4);

   /* set for no N81, normal operation */
   IoPortAddr[DUCRA] = (0x1 << 4);
   IoPortAddr[DUMRA] = 0x13;
   IoPortAddr[DUMRA] = 0x7;

   /* set port speed-- 9600 bps */
   IoPortAddr[DUCRA] = (0x1 << 4);
   IoPortAddr[DUACR] = (DUacr |= 0x80);
   IoPortAddr[DUCSRA] = 0xbb;

   /* init counter- counter mode, external clock source */
   IoPortAddr[DUACR] = (DUacr |= 0x30);
}
_____________________________________________________________

This is not the complete function, but you can see that it writes values
to the same location more than once, without ever accessing values from
that location. This tells the compiler that all assignments except the
last one (to a given location) are meaningless and can be discarded. I
have verified this by examining the assembler listing generated by GCC.

Any suggestions? I've gotta think someone else has run into this before.

Thanks for any help!
Chris

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

* Re: Disabling local optimizations with GCC
  2000-06-28 20:09 Disabling local optimizations with GCC Christopher Bahns
@ 2000-06-28 20:49 ` Art Berggreen
  2000-06-29  7:25   ` John Mills
  2000-06-29  6:50 ` SH-2 also -> " John Mills
  1 sibling, 1 reply; 5+ messages in thread
From: Art Berggreen @ 2000-06-28 20:49 UTC (permalink / raw)
  To: Christopher Bahns; +Cc: crossgcc

Christopher Bahns wrote:
> 
> Hello,
> 
> Anyone know how to take advantage of most of GCC's optimizations without
> it performing certain local optimizations? I read through the -O and -f
> options in the gcc manual and did not see anything specifically just for
> local optimizations. There is the "-fgcse" (global common
> subexpressions) but I guess this would not apply to commonizing
> subexpressions locally within a function... don't really know. I did not
> see any "-flcse" or similar option.
> 
> Here's my problem:
> I'm using a cross-compiler under Windows 98/NT for an m68k-coff target
> (MC68306). I have certain symbols mapped to specific hardware addresses
> so that I can interact with the hardware (as I assume most would do it).
> In some cases I assign different values to the same address in
> succession, or intermixed with the assignment of values to other
> addresses. It is important for all assignments to occur because each one
> causes the hardware to perform a particular action, and all actions need
> to occur in the order I've placed them in the C-language functions. The
> problem is that with any GCC optimization level  (-O, -O1, -O2, or -O3),
> it "optimizes" out all but the last assignment to a given location. This
> causes my program not to work. Everything seems to be fine if I disable
> all optimizations, but some parts of my program are time-critical and I
> may need some of the optimizations for the program to work right.
> 
> Of course, I can choose to disable all optimizations except the ones
> that I specify explicitly with "-f" options, but I'd prefer to have as
> many enabled as possible without breaking my program.
> 
> Here is some example code:
> _____________________________________________________________
> /* duart's base i/o address */
> #define IoPortAddr   ((BYTE*)0xa0001)
> 
> void InitDuart681(void)
> {
>    /* disable transmitter and receiver */
>    IoPortAddr[DUCRA] = ((0x0 << 4) | (0x2 << 2) | 0x2);
>    IoPortAddr[DUCRB] = ((0x0 << 4) | (0x2 << 2) | 0x2);
> 
>    /* reset UartA transmitter and receiver */
>    IoPortAddr[DUCRA] = (0x2 << 4);
>    IoPortAddr[DUCRA] = (0x3 << 4);
> 
>    /* make sure we're not in break */
>    IoPortAddr[DUCRA] = (0x7 << 4);
>    IoPortAddr[DUCRA] = (0x5 << 4);
> 
>    /* reset error status */
>    IoPortAddr[DUCRA] = (0x4 << 4);
> 
>    /* set for no N81, normal operation */
>    IoPortAddr[DUCRA] = (0x1 << 4);
>    IoPortAddr[DUMRA] = 0x13;
>    IoPortAddr[DUMRA] = 0x7;
> 
>    /* set port speed-- 9600 bps */
>    IoPortAddr[DUCRA] = (0x1 << 4);
>    IoPortAddr[DUACR] = (DUacr |= 0x80);
>    IoPortAddr[DUCSRA] = 0xbb;
> 
>    /* init counter- counter mode, external clock source */
>    IoPortAddr[DUACR] = (DUacr |= 0x30);
> }
> _____________________________________________________________
> 
> This is not the complete function, but you can see that it writes values
> to the same location more than once, without ever accessing values from
> that location. This tells the compiler that all assignments except the
> last one (to a given location) are meaningless and can be discarded. I
> have verified this by examining the assembler listing generated by GCC.
> 
> Any suggestions? I've gotta think someone else has run into this before.
> 
> Thanks for any help!
> Chris

Have you tried declaring your hardware variables as "volatile"?  This
tends to stop the compiler from many of these optimizations.
(i.e. try #define IoPortAddr   (volatile (BYTE*)0xa0001))

Art

------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com

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

* SH-2 also -> Re: Disabling local optimizations with GCC
  2000-06-28 20:09 Disabling local optimizations with GCC Christopher Bahns
  2000-06-28 20:49 ` Art Berggreen
@ 2000-06-29  6:50 ` John Mills
  1 sibling, 0 replies; 5+ messages in thread
From: John Mills @ 2000-06-29  6:50 UTC (permalink / raw)
  To: Christopher Bahns; +Cc: Dr. Joel Sherrill, Ralf Corsepius, Cross-GCC List

Cross-gcc'ers -

On Wed, 28 Jun 2000, Christopher Bahns wrote:

> Here's my problem:
> ... It is important for all assignments to occur because each one
> causes the hardware to perform a particular action, and all actions need
> to occur in the order I've placed them in the C-language functions. The
> problem is that with any GCC optimization level  (-O, -O1, -O2, or -O3),
> it "optimizes" out all but the last assignment to a given location. This
> causes my program not to work.

I have been banging against this problem with sh-hms (COFF) versions of
gcc and have not gotten it under control. At present, my
sh-hms-gcc(2.95.2)/newlib(1.8.[1|2]) tools will _not_ initialize on-chip
serial I/O properly, but 'gcc' and 'g++' built from the ecosSWtools-990319
(egcs-1.?) sources _do_ set them up: same SH-2 sources, same makefile.
Since the 'egcs' version is in WinNT/Cygwin and the 2.95.2 version is in
Linux, I can't yet work through selectively, module by module.

'sh-hms-gcc'-2.95.2 patched for RTEMS is successful or not, based on
optimization setting, but contrarily to what I would have expected: '-O4'
works; '-O0', '-O1', or no selection fails. (Not sure about other
choices.)

That last (RTEMS) compiler also emits code at some optimization levels
which cannot be assembled, apparently because it puts locals or pointers
out of range of the processor's allowable offset. That problem has the
[expected?] inverse relation to optimization: '-O0' causes emission of
assemblable code; other levels crash the assembler. Naturally this is down
in the middle of a complicated source tree, and I definitely need
optimization overall in order that some apps fit into on-chip FLASH in my
sh7045F.

I could adjust optimization level for individual branches (except with the
compiler from which I've not been able to get good code) but I haven't
gotten that to work properly with 'automake' and friends. I also worry
whether I'm getting reliable code at all, based on these observed
problems: what's there that I _haven't_ seen??

I am trying to dig out concise examples for knowledgable folks to look at,
but I haven't gotten there, yet.

Suggestions are naturally welcome.

   John Mills
   Sr. Software Engineer
   TGA Technologies, Inc.
   100 Pinnacle Way, Suite 140
   Norcross, GA 30071-3633
   e-mail: jmills@tga.com
   Phone: 770-441-2100 ext.124 (voice)
          770-449-7740 (FAX)





------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com

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

* Re: Disabling local optimizations with GCC
  2000-06-28 20:49 ` Art Berggreen
@ 2000-06-29  7:25   ` John Mills
  0 siblings, 0 replies; 5+ messages in thread
From: John Mills @ 2000-06-29  7:25 UTC (permalink / raw)
  To: Art Berggreen; +Cc: Christopher Bahns, crossgcc

Art -

On Wed, 28 Jun 2000, Art Berggreen wrote:
 
> Have you tried declaring your hardware variables as "volatile"?  This
> tends to stop the compiler from many of these optimizations.
> (i.e. try #define IoPortAddr   (volatile (BYTE*)0xa0001))

Thanks for the suggestion. At present, I'm using two types of
construction:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[...]
#define	EVB_BASE	0xFFFF0000      /* Register-block base address */

/* SCI0 Registers */

/* Serial mode ch 0 */
#define SCI0_SMR   (*(volatile unsigned char *)(EVB_BASE + 0x81a0))
/* Bit rate ch 0 */
#define SCI0_BRR   (*(volatile unsigned char *)(EVB_BASE + 0x81a1))
[...]

then I read or write from appropriately typed or cast variables
{
unsigned char tempch;
...
  tempch = SCI0_SMR | <modes_to_add>;
  SCI0_SMR = tempch;
...
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

and in other sources:

[...]
#define readb(addr) (*(volatile unsigned char *) (addr))
#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)

#define SCI0_SMR    (EVB_BASE + 0x81a0)

used as in:

{
...
unsigned char tempch;

  tempch = readb(SCI0_SMR);
  writeb((tempch | <modes_to_add>), SCI0_SMR);

...
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

The second approach is handy in that registers may be grouped as unions
and manipulated jointly or severally without duplicated variant names nor
in-line type-casts (or rather the type casting looks like functions, which
I find handy and readable - YMMV).

I haven't found any construction which seems to work or fail consistently,
but my 'C' coding skills are (to put it gently) 'limited'. I'll try the
formation you suggest and see how it works.

I am also concerned by the inconsistent results I seem to get from code
constructions which (_a_priori_) look acceptable to me.
  
Regards -

   John Mills
   Sr. Software Engineer
   TGA Technologies, Inc.
   100 Pinnacle Way, Suite 140
   Norcross, GA 30071-3633
   e-mail: jmills@tga.com
   Phone: 770-441-2100 ext.124 (voice)
          770-449-7740 (FAX)



------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com

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

* RE: SH-2 also -> Re: Disabling local optimizations with GCC
@ 2000-06-30  2:26 Christian Grebe
  0 siblings, 0 replies; 5+ messages in thread
From: Christian Grebe @ 2000-06-30  2:26 UTC (permalink / raw)
  To: crossgcc

Hello John,

we are working with SH1, SH2 and recently SH3. We have downloaded precompiled
Cygnus gcc, newlib and Insight, no debugging stub though, for sh-hms (COFF)
under Windows from the Hitachi ftp site. Works fine with the SH2. Our SH2 stub
is home-brewed from an older SH1 stub.

I tried to get in the ftp site today but could not get through. We have the
release 98R2. This version does not seem to be availible any more but you should
really check yourself. Here's the address of the directory:
ftp://ftp.hsa.hitachi.com/outgoing/tools/3rdparty . They _had_ a 99R1P1 release
there for the SH4 (sh-elf) that did not work with our SH3 project. Today I saw a
new DOS version of the 99R1 release for SH1-SH3. I think Insight will not be in
this package.

For a SH3 project we use the 2.95.2 gcc and 1.8.2 newlib and 5.0 Insight under
Windows that we built under Linux from source. Lots of problems with building
this tools. We gave up a build under WinNT because of problems with the Cygwin
1.1.1 environment. First tests seem to be ok with the 7708EVB. We are also
playing around with eCos in this project. Nothing running until now.

The older 98R2 compiler works flawless though with the SH1/2/3. We even have an
older 97R2 realease (same ftp source) that works fine with the SH1/2/3. Only
thing is we used O2 as the highest optimizer level.

If this is somehow helpful please stay in contact. It feels good talking to
another SH developer with similar problems since Hitachi support is poor over
here in Germany.

Greetings,

Christian Grebe

Dipl.-Ing.
ITK Dr. Kassen GmbH
Beim Eberacker 3
D-35633 Lahnau
Tel: +49 6441/6 50 05-14
Fax: +49 6441/6 50 05-29


------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com

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

end of thread, other threads:[~2000-06-30  2:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-28 20:09 Disabling local optimizations with GCC Christopher Bahns
2000-06-28 20:49 ` Art Berggreen
2000-06-29  7:25   ` John Mills
2000-06-29  6:50 ` SH-2 also -> " John Mills
2000-06-30  2:26 Christian Grebe

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).