From: <pa...@pj...> - 2002-02-25 00:13:22
|
>In the mean time I would recommend using the small model & selectively >declaring variables to be in "xdata" space. I can not do this. There are many functions that call other functions, so the allocation for all those parameters quickly overruns the 8051's internal RAM space, and the overlay of the leaf functions does very little to help. I thought about using reentrant, but the problem is similar with the limited stack space (and printf hogs a lot of that). This is not a problem unique to my project. Nearly any large C program will not be able to use small model, because the function parameters are allocated to "data" space. 128 bytes of internal memory gets burned up quickly by all these (and sloc's and "data" variables). Using large model, my current code uses all but 18 bytes of DSEG. There just isn't any room for allocating function parameters. I was hoping it'd be easy to do the same smart register usage in large model. I can dream, can't I ?? The compiled code does work, just not so efficiently, so this really is more of a feature request than a bug. Paul |
From: <pa...@pj...> - 2002-02-25 19:25:56
|
>It just seems that SDCC has matured >quite a bit over the last year. We're seeing more feature requests >regarding new types of optimizations. I think the pCode can efficiently >address these. This one was my fault. It _seemed_ like it'd be easy, not knowing the finer points of how small and large memory model are handled. It is true that SDCC has really started to mature and most of the bugs are nowadays are crashes and annoyances instead of generating wrong output. While I'd like a perfectly stable compiler, I think it's worth taking a few risks to someday get better optimizations. I wonder how many other sizable projects are depending on SDCC at this stage of its development?? Paul |
From: Sandeep D. <sa...@wi...> - 2002-02-25 05:33:00
|
Hi Paul, I recently added a new option --parms-in-bank1 (I think) . This uses the reg bank 1 area to pass parameters. This might help the problem a little bit (but you would loose bank1).. the interrupt functions will save and restore these registers . I have been using this option in my DS390 option and it seems to be working okay .. When this option is used the first parameter is passed in DPTR:b:a as usual then 8 more bytes are passed in RB1_0 .. RB1_7. In the meantime I will take a look into the allocator, cannot promise much though .... I might be able to fit some locals in registers in simple cases .. will see what I can do. Sandeep > -----Original Message----- > From: pa...@pj... [mailto:pa...@pj...] > Sent: Sunday, February 24, 2002 4:13 PM > To: sa...@wi...; sdc...@li... > Subject: RE: [sdcc-devel] [ sdcc-Bugs-521500 ] Available registers not > utilited > > > >In the mean time I would recommend using the small model & > selectively > >declaring variables to be in "xdata" space. > > I can not do this. There are many functions that call other > functions, > so the allocation for all those parameters quickly overruns the 8051's > internal RAM space, and the overlay of the leaf functions does very > little to help. I thought about using reentrant, but the problem is > similar with the limited stack space (and printf hogs a lot of that). > > This is not a problem unique to my project. Nearly any large > C program > will not be able to use small model, because the function parameters > are allocated to "data" space. 128 bytes of internal memory > gets burned > up quickly by all these (and sloc's and "data" variables). > Using large > model, my current code uses all but 18 bytes of DSEG. There > just isn't > any room for allocating function parameters. > > I was hoping it'd be easy to do the same smart register usage in large > model. I can dream, can't I ?? The compiled code does work, just not > so efficiently, so this really is more of a feature request > than a bug. > > > Paul > > > |
From: Scott D. <sc...@da...> - 2002-02-25 17:10:42
|
On Sun, 24 Feb 2002, Sandeep Dutta wrote: > Hi Paul, > > I recently added a new option --parms-in-bank1 (I think) . This > uses the reg bank 1 area to pass parameters. This might help the > problem a little bit (but you would loose bank1).. the interrupt > functions will save and restore these registers . I have been > using this option in my DS390 option and it seems to be working > okay .. When this option is used the first parameter is passed > in DPTR:b:a as usual then 8 more bytes are passed in RB1_0 .. RB1_7. > > In the meantime I will take a look into the allocator, cannot promise > much though .... I might be able to fit some locals in registers in simple > cases .. will see what I can do. Sandeep, This is what I did for the PIC port. Since the PIC has no DPTR or data stack I created a "psuedo stack" for passing parameters. It sounds similar to your RB1_0 .. RB1_7 buffer except that in my case the size can grow (or shrink) to whatever is needed. Also in my case, the live range of the parameters exist just across the call boundary. In some instances this leads to unnecessary register bloating (e.g. a parameter is copied off of the psuedo stack and into a local [albeit dynamically allocated] register). Now there are two optimizations that I desparately want to implement. One is collapsing the duplicate use of the registers (e.g. there's no reason to pass a parameter on the psuedo stack and then copy it into a local unless the receiving function makes another call that requires passing more parameters on the psuedo stack). The other optimization is automatic inlining of functions. In this case, parameter passing can be ommitted altogether and the CALL/RET overhead is removed. As far as the banking issue, the PIC port has a register locator routine for placing registers into banks. I currently only use it to place the "fixed" registers, i.e. the ones declared by "data at address ...". All other registers are "relocatable". At the very last step I assign these registers to a fixed address and then pass through the flow one more time to fix the bank selection registers. There's no clever algorithm in place right now to optimize the registers' bank locating, so the PIC port would suffer with the same problem that Paul describes. OTOH, it would be fairly straight forward in the PIC port to create as the final optimization pass a "register banking pressure relief" step. ------------ This leads to another topic however... By the end of March I intend to release what I call the "beta version of the PIC port of SDCC". (To be honest, it's really more like an alpha, though). As many of you know, the PIC port has a completely different backend than other ports (it uses something I call "pCode" which is analogous to iCode in the SDCC core). I think it's about time to port some of this into the main SDCC code base. This change however, would be even more drastic than Johan's proposal of splitting SDCC. OTOH, it allows us to perform flow analysis on the generated assembly code. So issues like "register banking" can be handled during a post optimization phase instead of up front. The bad news is that the code I've written has a definite PIC bias. So to be useful for the other ports, we'll need to redesign portions of the whole backend. When I first implement the PIC pCode, I started with gen.c and converted each emitCode into a emitpCode that would emit unintelligent text strings. Inother words, they had no flow information. Then eventually I changed the text into pCode opcode objects. Once all of the code was converted to pCode objects, I started with the flow analysis and register optimization stuff. This two step process allowed a fairly seamless transistion from no pCode to pure pCode. Anyway, sorry for the long message. It just seems that SDCC has matured quite a bit over the last year. We're seeing more feature requests regarding new types of optimizations. I think the pCode can efficiently address these. Scott |
From: Sandeep D. <sa...@wi...> - 2002-02-25 18:49:10
|
Hi Scott, > > Now there are two optimizations that I desparately want to > implement. One > is collapsing the duplicate use of the registers (e.g. > there's no reason > to pass a parameter on the psuedo stack and then copy it into a local > unless the receiving function makes another call that requires passing > more parameters on the psuedo stack). The other optimization > is automatic > inlining of functions. In this case, parameter passing can be ommitted > altogether and the CALL/RET overhead is removed. > The first optimization already exists (kinda). In the (incomplete) AVR port .. r16-r23 are used to pass the first 8 bytes of parameters, there is a special pass in the register allocator that tries to keep the live ranges in the same registers if it can, it essentially will keep it in the same register iff it does not cross a call boundary and is not used in a parameter send. I think you can use the same method to prevent popping them off the psuedo stack. The second one can be done, but have no plans or schedule for it. I have been meaning to take a look at pCode for a while .. but have a couple of projects I want to finish before I get into it. The psuedo stack concept is nice .. the --use-xstack option is something similar but is broken .. I should take a look at that and fix it up .. Sandeep |
From: Sandeep D. <sa...@wi...> - 2002-02-25 16:13:12
|
Paul, Here is another way you can avoid filling up the internal ram. You can specify storage class for a parameter in small-model e.g. int test (int a, xdata int b) { return a+b; } The second parameter 'b' will be allocated into the external ram. I'm not sure how this will interact with overlaying .... Sandeep > -----Original Message----- > From: pa...@pj... [mailto:pa...@pj...] > Sent: Sunday, February 24, 2002 4:13 PM > To: sa...@wi...; sdc...@li... > Subject: RE: [sdcc-devel] [ sdcc-Bugs-521500 ] Available registers not > utilited > > > >In the mean time I would recommend using the small model & > selectively > >declaring variables to be in "xdata" space. > > I can not do this. There are many functions that call other > functions, > so the allocation for all those parameters quickly overruns the 8051's > internal RAM space, and the overlay of the leaf functions does very > little to help. I thought about using reentrant, but the problem is > similar with the limited stack space (and printf hogs a lot of that). > > This is not a problem unique to my project. Nearly any large > C program > will not be able to use small model, because the function parameters > are allocated to "data" space. 128 bytes of internal memory > gets burned > up quickly by all these (and sloc's and "data" variables). > Using large > model, my current code uses all but 18 bytes of DSEG. There > just isn't > any room for allocating function parameters. > > I was hoping it'd be easy to do the same smart register usage in large > model. I can dream, can't I ?? The compiled code does work, just not > so efficiently, so this really is more of a feature request > than a bug. > > > Paul > > > |