Discussion:
Segmentation fault when compiling GCC with new RTL pass
Tomasz Jankowski
2012-10-02 20:17:42 UTC
Permalink
Hello,

I'm implementing new RTL pass in GCC. I attached current C source with
my RTL pass. I have to use GCC v4.5.1 port for OpenRISC project.

Basically I want to discover all "SET" insns which moves constant
immediate to register. Then I want to insert additional instruction
call right after this move instruction (for now I just want to insert
a copy of found "SET" insn). When I compile this pass with commented
"add_insn_after(...)" (line 70 in attachment) GCC compiles fine and
after installation it discovers SET insn properly. When I uncomment
this "add_insn_after(...)" compilation fails with message:

(...)
../../gcc-4.5.1/gcc/crtstuff.c: In function ‘__do_global_dtors_aux’:
../../gcc-4.5.1/gcc/crtstuff.c:332:1: internal compiler error:
Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
(...)

I run my pass just after "expand" pass. This is first time I'm trying
to modify GCC. What am I doing wrong?
Ian Lance Taylor
2012-10-03 04:21:46 UTC
Permalink
Post by Tomasz Jankowski
Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
(...)
I run my pass just after "expand" pass. This is first time I'm trying
to modify GCC. What am I doing wrong?
I don't know what you are doing wrong, but:

http://gcc.gnu.org/wiki/DebuggingGCC

Ian
Georg-Johann Lay
2012-10-03 13:29:07 UTC
Permalink
Post by Tomasz Jankowski
Hello,
I'm implementing new RTL pass in GCC. I attached current C source with
my RTL pass. I have to use GCC v4.5.1 port for OpenRISC project.
Basically I want to discover all "SET" insns which moves constant
immediate to register. Then I want to insert additional instruction
call right after this move instruction (for now I just want to insert
a copy of found "SET" insn). When I compile this pass with commented
"add_insn_after(...)" (line 70 in attachment) GCC compiles fine and
after installation it discovers SET insn properly. When I uncomment
(...)
I run my pass just after "expand" pass. This is first time I'm trying
to modify GCC. What am I doing wrong?
add_insn_after (copy_rtx (set), set, block);
Are you adding a pattern/singe_set to the insn stream?
You need an insn.
Tomasz Jankowski
2012-10-04 20:00:00 UTC
Permalink
Hello,
I don't know what rto:SI means and I don't know what you are trying to
do. If I were trying to insert an insn at a particular point I would
not define a new RTL code, I would use UNSPEC_VOLATILE.
Ok, now I see it was my fault and I was emitting new "rto" instruction
in wrong place.

I have last feature to implement in machine description and RTL pass -
SIMD instruction. As I see implementing SIMDs in GCC is a bit odd and
there's no example. Anyway, I have to implement add instruction called
"radd". As I know SIMD instructions usually operates on operands
packed in registers (like on x86, where we have 128 bit registers for
MMX/SSE). "radd" instructions operates of operands stored in two sets
of registers, were I we have one operand per registers. For me it's
completely new approach and I don't know how to deal with it... What's
more we specify only first set of registers in instruction call,
second registers set is based on first on. Example, when we write:

radd rD1, rA1, rB1

will result in performing:

rD1 = rA1 + rB1
rD2 = rA2 + rB2

Processor implicitly knows where to look for second set of registers
(rD2, rA2, rB2), because there is strong relation between rD1 and rD2:
rD2 is exactly after rD1 (the same apply to [rA1,rA2] and [rB1,rB2]).
Example pseudo asm code showing how it we should use this instruction:

mov 10, r5
mov 10, r6
mov 2, r10
mov 3, r11
radd r0, r5, r10

Code above will perform such calculation:

r0 = r5 + r10
r1 = r6 + r11

Now I really stuck, I don't know how to deal with vectorization and
how to handle register allocation for this "radd" (if I have to do
that....).
Tomasz Jankowski
2012-10-03 19:00:40 UTC
Permalink
Hello again,
Post by Georg-Johann Lay
Are you adding a pattern/singe_set to the insn stream?
You need an insn.
Yes, this was the reason, I was using rtx with patten instead of valid
insn. After reading more source code I found, that I have to use
make_insn_raw() to create insn from patter. This problem is solved,
however I face new issues:

*** 1. ***
When reading source code of RTL passes I saw two ways of browsing
insn. In one way basic blocks are used, in the way we have something
like:

FOR_EACH_BB(bb)
{
FOR_BB_INSNS(bb, insn)
{
// do something with insn
}
}

and in the second way we access insns using "get_insns()" function
from rtl.h and just handle it in regular "for" loop. What's the
difference between these two solutions? When using basic blocks we
browse source code as function by function. But when we use
"get_insns()" we simple go trough all insns in current compilation
unit, right?

*** 2. ***
What's the difference between "emit_insn_...()" and "add_insn_...()"
functions? From RTL pass point of view, they seem to work in the same
way.

*** 3. ***
In OpenRISC assigning 32 bit constant to register is handled by
"define_expand". What I want to do is to call my instruction after
constant is copied to register. For such assignment in C:

int AAAA = 12345678;

I get such dump after RTL expand:

(insn 5 4 6 3 simple_test.c:3 (set (reg:SI 43)
(const_int 12320768 [0xbc0000])) -1 (nil))

Then my new pass is executed and I get ("rto" is my custom instruction
and it take single register):

(insn 5 4 19 3 simple_test.c:3 (set (reg:SI 43)
(const_int 12320768 [0xbc0000])) -1 (nil))
(insn 19 5 6 3 (rto:SI (reg:SI 43)) -1 (nil))

At this point everything is ok, but in final assembler output, here
this assignment is expanded with "define_expand" I get:

l.movhi r3,hi(12320768) # move immediate M
l.rto r3
l.ori r3,r3,24910

instead of:

l.movhi r3,hi(12320768) # move immediate M
l.ori r3,r3,24910
l.rto r3

I don't know why mu instruction call gets "injected" in the previous
define_expand output.



I also want to mention that I'm extending GCC for my BSc of Computer
Science thesis. All your answers will not get lost in this mailing
list, because I'm going to write some sort of tutorial of extending
GCC with new RTL and GIMPLE passes.

Last thing - should I send my questions on gcc-help or other mailing list?
Ian Lance Taylor
2012-10-03 20:28:49 UTC
Permalink
Post by Tomasz Jankowski
Yes, this was the reason, I was using rtx with patten instead of valid
insn. After reading more source code I found, that I have to use
make_insn_raw() to create insn from patter.
Note that most callers use emit_insn and friends, not make_insn_raw.
Post by Tomasz Jankowski
When reading source code of RTL passes I saw two ways of browsing
insn. In one way basic blocks are used, in the way we have something
FOR_EACH_BB(bb)
{
FOR_BB_INSNS(bb, insn)
{
// do something with insn
}
}
and in the second way we access insns using "get_insns()" function
from rtl.h and just handle it in regular "for" loop. What's the
difference between these two solutions? When using basic blocks we
browse source code as function by function. But when we use
"get_insns()" we simple go trough all insns in current compilation
unit, right?
get_insns() returns all the insns in the current function or in the
current insn sequence (see push_to_sequence). In new code if you want
to look at all the insns in the current function you should always use
the first way--loop over the basic blocks and loop over the insns in
the block.
Post by Tomasz Jankowski
What's the difference between "emit_insn_...()" and "add_insn_...()"
functions? From RTL pass point of view, they seem to work in the same
way.
emit_insn takes an general rtx and emits it as an insn. add_insn only
takes an insn. In particular, emit_insn calls add_insn.
Post by Tomasz Jankowski
In OpenRISC assigning 32 bit constant to register is handled by
"define_expand". What I want to do is to call my instruction after
int AAAA = 12345678;
(insn 5 4 6 3 simple_test.c:3 (set (reg:SI 43)
(const_int 12320768 [0xbc0000])) -1 (nil))
Then my new pass is executed and I get ("rto" is my custom instruction
(insn 5 4 19 3 simple_test.c:3 (set (reg:SI 43)
(const_int 12320768 [0xbc0000])) -1 (nil))
(insn 19 5 6 3 (rto:SI (reg:SI 43)) -1 (nil))
At this point everything is ok, but in final assembler output, here
l.movhi r3,hi(12320768) # move immediate M
l.rto r3
l.ori r3,r3,24910
l.movhi r3,hi(12320768) # move immediate M
l.ori r3,r3,24910
l.rto r3
I don't know why mu instruction call gets "injected" in the previous
define_expand output.
I think you are misunderstanding something. define_expand is called
when GIMPLE is converted to RTL. It is also called during reload, and
at other times when general instructions are generated. In
particular, define_expand is not used to convert one insn to another
(define_split does that) and define_expand is not used when generating
assembler code.

I don't know what rto:SI means and I don't know what you are trying to
do. If I were trying to insert an insn at a particular point I would
not define a new RTL code, I would use UNSPEC_VOLATILE.
Post by Tomasz Jankowski
Last thing - should I send my questions on gcc-help or other mailing list?
For these kinds of questions, gcc-help is good.

Ian

Loading...