Bug 70

Summary: Proposal for EQUR on steroids
Product: RMAC Reporter: ggn <ggnkua>
Component: CoreAssignee: Shamus Hammons <jlhamm>
Status: CONFIRMED ---    
Severity: enhancement CC: jlhamm, linkovitch
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: All   

Description ggn 2015-12-31 14:35:50 CST
We had a discussion with dml and he came up with the following design. Basically it's EQUR with automated register assignment.

super mini example of open naming and reallocation via input constraints:

	rin	a0,fred
	rin	a1,bob
	rin	d0,jam

	add.l	(fred)+,jam	; don't even bother trying to make sense of this code
	move.l	jam,banana	; jam is d0 here for sure, because add.l has a dest with an input
	move.l	jam,orange
	lsl.l	#2,orange
	move.l	(fred)+,jam	; jam might not be d0 here!
	or.l	jam,banana
	add.l	orange,banana
	move.l	(fred)+,jam	; jam's life gets reset again by a move op (a dest supporting no inputs) - gets a chance to become d0 again
	rout	jam,d0		; note: only d0 is mapped both in and out
	rout	banana,d7


- actual syntax isn't that important for the most part, so long as its robust
- register 'types' are implied here, but may be better to specify via some prefix - user vs design hassle trade!
- each opcode needs some internal info to say whether the operands are inputs or outputs or both, to analyse token lifespans
- assigning to a token as output-only means 'internal rename opportunity' - can be given a new register immediately. 
- any dest operand which doubles as an input (add, or, and, bset ...etc) is not a rename opportunity.
- i usually do this by following outputs backwards through the program and making a little graph.
- err. that's all.

GCC inline assembly nearly does this. it could have done this. they had everything they needed...
..but those beards prefer awesome levels of self-induced pain to common sense. what they did is an abomination.

FYI, 6888fu uses a simplified version of this scheme for constraining and allocating, 
but doesn't allow arbitrary tokens for regs - just fp0-fp7.
internally it will rename them in a much larger range of digits (each new assignment increments 
the 'name counter') until it optimizes the lifespans back down to fp0-7 in the final pass. its
also at this point where it will whine if the program needs more registers than can possibly be handed out
given the inout constraints.

what is it useful for? writing, modifying, optimizing, refactoring big asm programs without burning 90% of your effort
worrying about which registers just got trashed or might become free after the change. 

one last bonus is that it may accept normal register names d0-7/a0-7 and leave it up to the user whether they want
zero, partial or full reallocation from those original names - and with or without feedback in each scenario. 
all very handy for R&D!
Comment 1 LinkoVitch 2018-08-22 10:41:21 CDT
Necrotic 2P

Hope you don't mind another thought in this?

Sounds like a cool idea, and would probably be really handy for the RISC side of things too. 

What I think may also be useful/required is the ability to specify registers that cannot be used for this reallocation.  

My thoughts:

You have a function like the one specified in the example, but the calling code makes use of d2.  On the line:

move.l (fred)+,jam

If I am understanding you correctly at this point jam might be allocated to a different register? 

If that is correct then would need to protect other registers outside of their nominated block.  Or possibly indicate registers that are free for dynamic usage between the rin and rout.

Hope that makes sense (and I understand what you are saying too :) )