[Firm] Queries about writing a backend

Matthias Braun matze at braunis.de
Fri Jul 10 18:34:58 CEST 2015


Hi,

> On Jul 9, 2015, at 1:38 PM, David Given <dg at cowlark.com> wrote:
> 
> Hello,
> 
> I'm interested in the possibility of using libfirm as a compiler for a
> CPU architecture I'm working with. I have a few questions.
> 
> Firstly, though, playing with the latest code from git, I see that
> TEMPLATE is broken:
> 
> $ cat test.c
> int add(int a, int b, int c) { return a+b+c; }
> 
> $ build/debug/cparser -S test.c -bisa=TEMPLATE
> Segmentation fault
> 
> (Would I be better off working against 1.21? If so, where do I get it?
> The download link just points at the git repository.)
You should definitely work against the git version, 1.21 is quiet old by now. Unfortunately the TEMPLATE backend is not a tested by our buildbots at http://buildbot.info.uni-karlsruhe.de <http://buildbot.info.uni-karlsruhe.de/> so it breaks from time to time. Anyway I have fixed it enough to work with your example again. In general I’d recommend looking at the sparc and ia32 backends which are both fully functional.

> 
> Anyway, my questions:
> 
> a) How well does the code generator handle situations where there are
> multiple ways to lower trees of nodes into instructions? For example, my
> CPU architecture has both 2op and 3op forms of some intructions; 2op
> forms are encoded as 16-bit instructions, the 3op forms as 32-bit.
> However, 2op instructions can only use a limited set of registers. 3op
> instructions can use all registers. So, deciding whether to pick a 2op
> or a 3op instruction is non-trivial, as it can have a major effect on
> the other instructions in the block.
Our backends usually follow this pattern:
1. Select target specific nodes
2. Schedule the nodes
3. Allocate registers
4. Peephole Optimizations
5. Emit assembly

The first step produces nodes with register requirements on each input/output but can’t know the final registers yet so you cannot select between 2- and 3-address variants yet. What I would recommend here is using 3 address operations and setting a should_be_same register requirement, that way the allocator tries to assign the same register to respective inputs/outputs where possible. In step 4 you can then change the 3op forms to 2op form in the cases where the register allocator succeeded in fulfilling the constraint.

> 
> b) Can I have overlapping register classes? (My registers have three
> different orthogonal properties which I might want to select for.)
There is no support for aliasing registers, you can limit node inputs/outputs to a subset of a register class. You have to be able to freely copy between any register in a class however. I’m not completely sure I understand your requirements, so not sure whether you can model this in libfirm.

> 
> c) Instructions with side effects? e.g. post or pre increment. Is this
> just a matter of writing brute force code in *_transform.c to see if I
> have the appropriate graph? I notice that the existing backends don't
> appear to generate these instructions. (My most complicated instruction
> is a
> add-constant-to-register-then-compare-with-another-constant-and-compare-and-branch,
> all in a single 32-bit instruction. It would be awesome to be able to
> support this, but as the possible branch displacement is very small it's
> probably hard. I assume that Firm doesn't track instruction positions.)
Yes this a matter of writing rules in *_transform.c, things usually get a bit tricky when your pattern have multiple roots but there are certainly some more complicated rules already like folding a load,add,store sequence to a single add with load-modify-store addressing mode on ia32.

Greetings
	Matthias


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ira.uni-karlsruhe.de/pipermail/firm/attachments/20150710/7fa86921/attachment.html>


More information about the Firm mailing list