From: Alex McDonald on
Betov wrote:
> Alex McDonald <alex_mcd(a)btopenworld.com> ýcrivait news:dfri9s$oj7$1
> @nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com:
>
>
>>Betov wrote:
>>
>>
>>>And, if i may add, anyone wishing to develop an Assembler
>>>doing Jumps Size Optimizations, - in one single and simple
>>>additional Computation, taking almost no time , instead of
>>>the traditional Multi-Passes -, can take a lesson from
>>>RosAsm Source.
>>>
>>
>>Backward jumps are trivial; the distance is known because the code has
>>been generated. But how do you assess the jump distance for forward
>>jumps without a second pass? This;
>>
>> jmp B
>> ...code...
>> jmp A
>> ...code...
>>B: ...code...
>>A: ...code...
>>
>>requires that the jump to B is dependant on the length of the jump to A
>>opcode. Can you describe how you optimise this in one pass?
>
>
>
> Before giving any kind of credit to the insanities of our
> famous swindler, Alex, you'd better take a look at how the
> things are implemented in RosAsm Source, by following, for
> example, the 'ShortenJumpsWanted' Flag, with the various
> Double-Click and Right-Click Features.

I'm afraid that I find the RosAsm syntax quite difficult, and I'm not
sure I know where to look in the source for the routine that does this.
I was looking for a brief description of how you did it, not the code
itself.

>
> You would then see that the Optimizations are done backward
> and forward.

More than one pass, then?

>
> You would also see that these optimizations apply upon the
> Jcc Instructions, which are, at a logical point of view, the
> only one where this kind of Optimization can have any real
> effect.

IF/THEN/ELSE generates one Jcc and one JMP instruction;

IF: test, jcc ELSE:
THEN section
JMP ENDIF
ELSE: ELSE section
ENDIF:...

Will either get optimised? The JMP ENDIF could be a short jump.

>
> Plus, if you knew a bit of 1) RosAsm Syntax,

No, not comfortable with it.

> and of 2) the
> PE format, you would know that the size of a PE cannot be
> reduced under the range of the File Alignment Sections,

The question was more about how RosAsm does it in one pass, not whether
it was worth doing from the perspective of size or performance.

> and
> that RosAsm _never_ implements Short Jumps on Plain Labels,
> which would not make any sense, but only on Local Labels.

What are plain labels and local labels?

--
Regards
Alex McDonald
From: randyhyde@earthlink.net on

Alex McDonald wrote:
>
> C: ...code...
> jmp A
> jmp B
> ...code...
> jmp B
> A: ...code...
> jmp C
> B: ...code...
> jmp A
>
> (The jumps could be jcc or jmp; I've just shown jmp.)
>
> Do you compact from top to bottom, or bottom to top?

I bet he doesn't even understand what you're talking about and why it
makes a difference.

>
> Any jump you didn't compact first time round might now be compactable;
> do you try to re-compact after the first pass? For instance, the first
> jmp B may be too far away first time, but close enough once other jumps
> later on have been compacted.

He doesn't seem to understand this.
Worse, wait until he learns that *optimal* code may require certain
jumps to be long, even though they jump only a short distance, in order
to minimize the size of several other jumps. Admittedly a rare case,
and mostly a degenerate case, but a case nonethless; few assemblers I'm
aware of handle this case [because this is the case that leads to
intractibility], but I still bet that he's not even aware that this
situation exists.


>
> Each time you compact a jump, the labels elsewhere in the code move. For
> instance, compacting the first jump causes A and B to move, and _all_
> the jumps need recaculated. The same is true of the second. How do you
> tell that A and B have moved? How do you recalculate the jump offsets?

He doesn't. That much is clear. With one pass he can optimize the jumps
whose displacements are immediately optimizable, and that's it. Unless
he doesn't understand what a "pass" is.

>
> >
> > Notice that, as far as i can know, this is one more innovation
> > coming with RosAsm, as i have never seen any Assembler doing
> > the JSO that way,
>
> The technique is not new; peephole optimisers that do this have been
> around for many years. It might be the only assembler that does this.

Not even the only assembler.
Gas works this way (though it does it correctly).

>
> You're not optimising fully, hence you don't hit the problem (as far as
> I can see) because of the limited optimisation you're doing.

Obviously he is not.
Cheers,
Randy Hyde

From: Betov on
Alex McDonald <alex_mcd(a)btopenworld.com> ýcrivait news:dfruf9$ojr$1
@nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com:

> Each time you compact a jump, the labels elsewhere in the code move.

Of course. Don't you understand the word 'emulating'?

There is no magic, in the method. The Multi-Pass is just
_emulated_ by the Tables calculations, and after one
"compacting" is done, the Map Table (where the Long
Displacements are "Flaged"), is scan again, for new
possible Long Jumps that could be made shorter, as it
says in:

While D$NumberOfLongToShort <> 0

.... Too bad that you can't read.

:))

Betov.

< http://rosasm.org >



From: Alex McDonald on
Betov wrote:
> Alex McDonald <alex_mcd(a)btopenworld.com> ýcrivait news:dfruf9$ojr$1
> @nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com:
>
>
>>Each time you compact a jump, the labels elsewhere in the code move.
>
>
> Of course. Don't you understand the word 'emulating'?

Yes. That was a statement. The questions were;

How do you tell that A and B have moved?
How do you recalculate the jump offsets?

I did have a spot of bother with the words below though;

>
> There is no magic, in the method. The Multi-Pass is just
> _emulated_ by the Tables calculations, and after one
> "compacting" is done, the Map Table (where the Long
> Displacements are "Flaged"), is scan again, for new
> possible Long Jumps that could be made shorter, as it
> says in:
>
> While D$NumberOfLongToShort <> 0

So it's "emulating" multi-pass? By doing more than one pass?

> ... Too bad that you can't read.

My reading's fine, thanks. What I'm trying to understand is how it does
it (the algorithm), not how it's implemented (RosAsm). You're
explanation isn't informative as a consequence. I'll try again;

RosAsm builds a parallel table to the code it's optimising (actually,
it's just a chunk of memory the same length as the generated code with
flags and branch offsets). This table contains information about the
jumps _only_. Meanwhile, somewhere in the symbol table are the labels.
They contain offsets or pointers into the generated code.

When the code generation is complete (presumably for a procedure only; I
don't think you can be globally optimising), there is interaction
between the parallel table and the symbol table.

Each time you compact a jump, the labels elsewhere in the code move. How
do you tell that A and B have moved? Do you update the symbol table? How
do you recalculate the jump offsets? Are they all recaculated on every
pass? Do you pass the table from bottom to top, or top to bottom?

--
Regards
Alex McDonald
From: Betov on
Alex McDonald <alex_mcd(a)btopenworld.com> ýcrivait news:dfs2sf$bcp$1
@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com:

>> ... Too bad that you can't read.
>
> My reading's fine, thanks. What I'm trying to understand is how it does
> it (the algorithm), not how it's implemented (RosAsm). You're
> explanation isn't informative as a consequence. I'll try again;
>
> RosAsm builds a parallel table to the code it's optimising (actually,
> it's just a chunk of memory the same length as the generated code with
> flags and branch offsets). This table contains information about the
> jumps _only_. Meanwhile, somewhere in the symbol table are the labels.
> They contain offsets or pointers into the generated code.
>
> When the code generation is complete (presumably for a procedure only;
I
> don't think you can be globally optimising), there is interaction
> between the parallel table and the symbol table.
>
> Each time you compact a jump, the labels elsewhere in the code move.
How
> do you tell that A and B have moved? Do you update the symbol table?
How
> do you recalculate the jump offsets? Are they all recaculated on every
> pass? Do you pass the table from bottom to top, or top to bottom?


Let me tell you that it sounds a bit strange to me, that you
could ask questions about the details of the Implementation,
whereas the Source is GPLed, extreemely readable, and offered
in the context of an IDE where pointing anything out is always
a matter of "Click"...

1) The Map Table (parallele to the Code Section) holds nothing
but 0 and 1. ['1' at each Location, where a Long Displacement
has been Encoded].

2) When Encoding, RosAsm manages several separated Tables. For
examples, the Labels Table, the Equates Table, and so on...
It also manages a References Table, that holds the various
references encounted while encoding the Instructions, and
the real Displacements are only written at the very end of
all computations (even later than the JSO thingies).

3) Therefore, analysing if a Long Jump could be made short
is just a matter of analysing the substraction of the
Evocation Reference by the Declaration (Label Table...)
Reference.

4) Yes, of course, in the "Multi-Pass-Emulation", all of
the Tables (and the Code Section, and all) are entirely
compacted, before scanning the Map Table again, in the
Main Loop, which is a trivial as:

JmpsOptimize:
call ScanShortenJmpsTable

While D$NumberOfLongToShort <> 0
call CompactLabelListAndCodeRef
call CompactCodeList

call CompactShortenJmpsTable

call ScanShortenJmpsTable
End_While
ret

But, maybe, you are going to ask me to discribe what is
called, exactely... For the one interrested by the method,
the Source is provided, and for the ones not able to read
RosAsm unified and simplified Syntax, go and play football.


Betov.

< http://rosasm.org >