[Firm] Queries about writing a backend

Matthias Braun matze at braunis.de
Fri Jul 10 18:38:01 CEST 2015

Some notes on debugging the crash below:

> 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.)
> 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.
> b) Can I have overlapping register classes? (My registers have three
> different orthogonal properties which I might want to select for.)
> 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.)
> Here's my stack trace, produced by valgrind:
> ==15285== Command: build/debug/cparser -S test.c -bisa=TEMPLATE
> ==15285==
> ==15285== Source and destination overlap in strcpy(0x9f1b00, 0x9f1b00)
> ==15285==    at 0x4C2C326: strcpy (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==15285==    by 0x41E6E5: setup_isa (target.c:214)
> ==15285==    by 0x41E7C7: setup_firm_isa (target.c:250)
> ==15285==    by 0x41EB62: target_setup (target.c:336)
> ==15285==    by 0x402D53: main (main.c:330)
> ==15285==
> ==15285== Invalid read of size 1
> ==15285==    at 0x4896CE: arch_irn_is_ignore (bearch.h:300)
> ==15285==    by 0x489BBF: normal_tree_cost (beschednormal.c:116)
> ==15285==    by 0x489EBE: normal_cost_walker (beschednormal.c:166)
> ==15285==    by 0x4C9686: irg_walk_2_pre (irgwalk.c:39)
> ==15285==    by 0x4C972F: irg_walk_2_pre (irgwalk.c:48)
> ==15285==    by 0x4C96CB: irg_walk_2_pre (irgwalk.c:44)
> ==15285==    by 0x4C9A43: irg_walk_2 (irgwalk.c:107)
> ==15285==    by 0x4C9AB2: irg_walk_core (irgwalk.c:115)
> ==15285==    by 0x4C9B11: irg_walk (irgwalk.c:125)
> ==15285==    by 0x4C9BA5: irg_walk_graph (irgwalk.c:133)
> ==15285==    by 0x48A855: sched_normal (beschednormal.c:317)
> ==15285==    by 0x488F23: be_schedule_graph (besched.c:160)
> ==15285==  Address 0x19 is not stack'd, malloc'd or (recently) free'd
> gdb says that arch_get_irn_register_req() is returning NULL on this node
> (unfortunately I can't call dump_ir_block_graph() on it because of an
> invalid string):

Usually this works. In this particular case I just used the -bdump=all commandline which dumps a graph after each backend pass. In this particular case viewing the graph after code selection showed that the Start node didn’t have proper register requirements assigned to the outputs (you can view them by inspecting the attributes of the node in ycomp).

- Matthias

More information about the Firm mailing list