gnupic: improved banksel and pagsel
Subject:
Re: improved banksel and pagsel
From:
Scott Dattalo ####@####.####
Date:
24 Sep 2004 05:18:37 +0100
Message-Id: <Pine.LNX.4.60.0409232047390.32487@ruckus.brouhaha.com>
On Thu, 23 Sep 2004, Gabor Kiss [Bitman] wrote:
>> The banksel and pagesel directives in gputils have been improved for 12
>> bit and 14 bit devices. Before the directives manipulated all the bits
>> for 4 banks and 4 pages. Now they only manipulate the bits for the
>> pages and banks available on that device.
>
> Dear Craig,
>
> Is it possible to make some compile time optimizations with banksel? Now
> I had to write tricky macros that keeps current select bits in mind and
> changes the only the bits really necessary when I select a bank. (I.e.
> switching from bank0 to bank1 requires 1 "bsf" instruction only.)
>
> Yes, it is trivial, that principally there is no universal solution.
> However even a limited version of banksel optimizer could
> reduce code size and increase speed by omitting unnecessary
> bit set/clear instructions at the expense of final code size
> could not be strictly planned.
>
> What is your opinion?
Gabor,
Why stop with banksel's. To properly do what you want is not trivial. The
reason is that there are to many special cases. Consider for example:
banksel MyVar1
CLRF MyVar1
banksel MyVar2
CLRF MyVar2
If the two variables are in the same bank, then yeah, this is trivial to
optimize. But now suppose you have:
banksel MyVar1
MOVF MyVar1,W
MOVWF INDF
banksel MyVar2
CLRF MyVar2
If MyVar1 and MyVar2, is it safe to get rid of the second bank select?
Suppose FSR = 3?
Or how about this:
banksel MyVar1
MOVF MyVar1,W
A_label:
banksel MyVar2
CLRF MyVar2
While I admit these are contrived, I'll argue that they're not too
uncommon.
One way to implement what you're asking is with a flow analyzer. This is a
program that understands each instruction, knows where the labels are,
where the function boundaries are, etc. The flow analyzer can do things
like perform 'live rang analysis' and learn where certain registers are
valid (e.g. think about how you'd implement automatic overlays for
temporary variables). The flow analyzer can be made smart enough to detect
the cases I illustrated above and make a decision as to whether or not the
banksel's can be optimized.
While working on SDCC, I implemented flow optimizer that did this. Its
purpose was to mainly optimize the register allocation. However, I found
that it was possible to do things like automatic inlining, peephole
optimizing, tail optimizing etc. all within the same algorithmic
framework.
This is hardly trivial! Perhaps a more trivial approach is to define
regions that the assembler/linker can safely optimize:
banksel start
; the assembler will assume that all instructions will
; execute in one continuous stream. In addition, it's
; assumed that the status register is not manipulated
; through indirect operations
banksel end
All registers falling in the bracketed range could be banksel optimized.
Scott