Re: [Patch,AVR]: Better log output with -mdeb
2011/9/28 Georg-Johann Lay : > Georg-Johann Lay schrieb: >> This is a tentative patch for better support of logging information for avr >> BE >> developers. >> >> [...] >> >> * config/avr/avr-protos.h (avr_edump, avr_fdump): New macros. >> (avr__set_caller_e, avr__set_caller_f): New prototypes. >> * config/avr/avr.c: Include tree-pass.h. >> (avr__caller, avr__stream): New static variables. >> (avr__fdump_e, avr__fdump_f, avr__vadump): New static functions. >> (avr__set_caller_e, avr__set_caller_f): New functions. > > Sorry, picked the wrong ML. > I have no objections against the patch. May be better to put it in separate file. (avr-debug.c or avr-log.c) Denis.
-fdebug-types-section unidentifiable anonymous struct (PR debug/49750)
Hi all and Cary, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49750 It is a part of former Bug (FIXED): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510 currently -fdebug-types-section regresses GDB testsuite for: FAIL: gdb.cp/anon-struct.exp: print type of X::t2::t2 FAIL: gdb.cp/member-ptr.exp: * Describing `gdb.cp/anon-struct.exp' which is addressed also by Tom Tromey's Bug above. Unaware if it fixes also gdb.cp/member-ptr.exp, I hope so. There is no way to find out where the "t2" method (constructor) belongs from DIE <77> (it belongs to "X::t2", making the constructor name "X::t2::t2()"). With posted FSF GDB HEAD fix (fixing another unrelated issue): [patch] Fix printed anonymous struct name http://sourceware.org/ml/gdb-patches/2011-09/msg00483.html I think it would be enough to just put proper declarations around the "t2" method DIE, at least it works for me with the GDB patch above. But maybe a better DWARF solution exists. Thanks, Jan Attaching "anonstruct4b.s" patched by hand as the diff below suggests: echo 'int main(){}'|g++ -g -c -o anonstructmain4.o -Wall -x c++ -;g++ -o anonstruct4b anonstructmain4.o anonstruct4b.s -Wall ./gdb -q -nx -ex 'set language c++' -ex "ptype X::t2::t2" -ex q ~/t/anonstruct4b -There is no field named t2 -> +type = void (X::t2 * const) <1><>: Abbrev Number: 18 (DW_TAG_namespace) <> DW_AT_name: X <2><>: Abbrev Number: 19 (DW_TAG_typedef) <> DW_AT_name: t2 <> DW_AT_type: signature: 9d52f6834a49e845 <2><>: Abbrev Number: 20 (DW_TAG_variable) <> DW_AT_name: v <> DW_AT_linkage_name: (indirect string, offset: ): _ZN1X1vE <> DW_AT_type: <> <> DW_AT_external: 1 <> DW_AT_declaration : 1 - <1><>: Abbrev Number: 21 (DW_TAG_structure_type) -<> DW_AT_declaration : 1 + <2><>: Abbrev Number: 21 (DW_TAG_structure_type) +<> DW_AT_declaration : 1 +<> DW_AT_MIPS_linkage_name: (indirect string, offset: ): N1X2t2E - <2><>: Abbrev Number: 22 (DW_TAG_subprogram) + <3><>: Abbrev Number: 22 (DW_TAG_subprogram) <> DW_AT_name: t2 <> DW_AT_artificial : 1 <> DW_AT_declaration : 1 <> DW_AT_object_pointer: <> .file "anonstruct.C" .text .Ltext0: .weak _ZN1CC1Ev .set_ZN1CC1Ev,_ZN1CC2Ev .section.text._ZN1CC2Ev,"axG",@progbits,_ZN1CC5Ev,comdat .align 2 .weak _ZN1CC2Ev .type _ZN1CC2Ev, @function _ZN1CC2Ev: .LFB1: .file 1 "anonstruct.C" # anonstruct.C:1 .loc 1 1 0 .cfi_startproc # BLOCK 2 seq:0 # PRED: ENTRY (fallthru) pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq%rsp, %rbp .cfi_def_cfa_register 6 movq%rdi, -8(%rbp) # anonstruct.C:1 .loc 1 1 0 popq%rbp .cfi_def_cfa 7, 8 # SUCC: EXIT [100.0%] ret .cfi_endproc .LFE1: .size _ZN1CC2Ev, .-_ZN1CC2Ev .set_ZN1X2t2C1Ev,_ZN1X2t2C2Ev .text .align 2 .type _ZN1X2t2C2Ev, @function _ZN1X2t2C2Ev: .LFB4: # anonstruct.C:6 .loc 1 6 0 .cfi_startproc # BLOCK 2 seq:0 # PRED: ENTRY (fallthru) pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq%rsp, %rbp .cfi_def_cfa_register 6 subq$16, %rsp movq%rdi, -8(%rbp) .LBB2: # anonstruct.C:6 .loc 1 6 0 movq-8(%rbp), %rax movq%rax, %rdi call_ZN1CC1Ev .LBE2: leave .cfi_def_cfa 7, 8 # SUCC: EXIT [100.0%] ret .cfi_endproc .LFE4: .size _ZN1X2t2C2Ev, .-_ZN1X2t2C2Ev .globl _ZN1X1vE .bss .type _ZN1X1vE, @object .size _ZN1X1vE, 1 _ZN1X1vE: .zero 1 .text .type _Z41__static_initialization_and_destruction_0ii, @function _Z41__static_initialization_and_destruction_0ii: .LFB6: # anonstruct.C:9 .loc 1 9 0 .cfi_startproc # BLOCK 2 seq:0 # PRED: ENTRY (fallthru) pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq%rsp, %rbp .cfi_def_cfa_register 6 subq$16, %rsp movl%edi, -4(%rbp) movl%esi, -8(%rbp) # anonstruct.C:9 .loc 1 9 0 cmpl$1, -4(%rbp) # SUCC: 3 (fallthru) 5 jne .L3 # BLOCK 3 seq:1 # PRED: 2 (fallthru) # anonstruct.C:9 .loc 1 9 0 is_stmt 0 discriminator 1 cmpl$65535, -8(%rbp) # SUCC: 4 (fallthru) 5 jne .L3 # BLOCK 4 seq:2 # PRED: 3 (fallthru) # anonstruct.C:8 .loc 1 8 0 is_stmt 1 movl$_ZN1X1vE, %edi # SUCC: 5 (fallthru) call_ZN1X2t2C1Ev # BLOCK 5 seq:3 # PRED: 4 (fallthru) 2 3 .L3: # anonstruct.C:9 .loc 1 9 0 leave .cfi_def_cfa 7, 8 # SUCC: EXIT [10
Re: [Patch,AVR]: Better log output with -mdeb
Georg-Johann Lay schrieb: > This is a tentative patch for better support of logging information for avr BE > developers. > > [...] > > * config/avr/avr-protos.h (avr_edump, avr_fdump): New macros. > (avr__set_caller_e, avr__set_caller_f): New prototypes. > * config/avr/avr.c: Include tree-pass.h. > (avr__caller, avr__stream): New static variables. > (avr__fdump_e, avr__fdump_f, avr__vadump): New static functions. > (avr__set_caller_e, avr__set_caller_f): New functions. Sorry, picked the wrong ML.
[Patch,AVR]: Better log output with -mdeb
This is a tentative patch for better support of logging information for avr BE developers. There are situations where it is more convenient to let the compiler produce information than to debug into the compiler. One example are -da dumps. This patch proposes a better support to print information by means of a printf-like function via %-codes. The current debug output with avr-gcc's option -mdeb produces bulk of information that is very hard to read because - there is much output - there is no information on current_function_decl - there is no information on current pass name/number - there is no print-like function so the trees, rtxes so that it is tedious to get formatted output. For example, the following call to avr_edump static int avr_OS_main_function_p (tree func) { avr_edump ("%?: %t\n", func); return avr_lookup_function_attribute1 (func, "OS_main"); } prints additional information in a convenient way (foo is function to be compiled): avr_OS_main_function_p[foo:pro_and_epilogue(202)]: Index: config/avr/avr-protos.h === --- config/avr/avr-protos.h (revision 179257) +++ config/avr/avr-protos.h (working copy) @@ -111,3 +111,9 @@ extern rtx avr_incoming_return_addr_rtx #ifdef REAL_VALUE_TYPE extern void asm_output_float (FILE *file, REAL_VALUE_TYPE n); #endif + +#define avr_edump (avr__set_caller_e (__FUNCTION__)) +#define avr_fdump (avr__set_caller_f (__FUNCTION__)) + +extern int (*avr__set_caller_e (const char*))(const char*, ...); +extern int (*avr__set_caller_f (const char*))(FILE*, const char*, ...); Index: config/avr/avr.c === --- config/avr/avr.c (revision 179257) +++ config/avr/avr.c (working copy) @@ -7810,5 +7810,233 @@ avr_expand_builtin (tree exp, rtx target gcc_unreachable (); } + +/*** + ** Logging, for BE developers only + ***/ + +#include "tree-pass.h" + +static const char* avr__caller = "?"; +static FILE* avr__stream; + +static void avr__vadump (FILE*, const char*, va_list); + +static int +avr__fdump_f (FILE *stream, const char* fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + if (stream) +avr__vadump (stream, fmt, ap); + va_end (ap); + + return 1; +} + +int (* +avr__set_caller_f (const char* caller) + )(FILE*, const char*, ...) +{ + avr__caller = caller; + + return avr__fdump_f; +} + +static int +avr__fdump_e (const char* fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + avr__vadump (stderr, fmt, ap); + va_end (ap); + + return 1; +} + +int (* +avr__set_caller_e (const char* caller) + )(const char*, ...) +{ + avr__caller = caller; + avr__stream = stderr; + + return avr__fdump_e; +} + +/* + -- known %-codes -- + + r: rtx + t: tree + T: tree (brief) + C: enum rtx_code + m: enum machine_mode + R: enum reg_class + L: insn list + H: location_t + + -- no args -- + A: call abort() + f: current_function_name() + F: caller (via __FUNCTION__) + P: Pass name and number + ?: Print caller, current function and pass info + + -- same as printf -- + %: % + c: char + s: string + d: int (decimal) + x: int (hex) +*/ + +static void +avr__vadump (FILE *file, const char *fmt, va_list ap) +{ + char bs[3] = {'\\', '?', '\0'}; + + while (*fmt) +{ + switch (*fmt++) +{ +default: + fputc (*(fmt-1), file); + break; + +case '\\': + bs[1] = *fmt++; + fputs (bs, file); + break; + +case '%': + switch (*fmt++) +{ +case '%': + fputc ('%', file); + break; + +case 't': + { +tree t = va_arg (ap, tree); +if (NULL_TREE == t) + fprintf (file, ""); +else + { +if (stderr == file) + debug_tree (t); + } +break; + } + +case 'T': + print_node_brief (file, "", va_arg (ap, tree), 3); + break; + +case 'd': + fprintf (file, "%d", va_arg (ap, int)); + break; + +case 'x': + fprintf (file, "%x", va_arg (ap, int)); + break; + +case 'c': + fputc (va_arg (ap, int), file); + break; + +case 'r': + print_inline_rtx (file, va_arg (ap, rtx), 0); + break; + +case 'L': + { +rtx insn = va_arg (ap, rtx); + +while (insn) + { +print_inline_rtx (file, insn, 0); +
Question on cse_not_expected in explow.c:memory_address_addr_space()
Hi, looking into PR50448 there is the following C code: typedef struct { unsigned char a,b,c,d; } SPI_t; #define SPIE (*(SPI_t volatile*) 0x0AC0) void foo (void) { SPIE.d = 0xAA; while (!(SPIE.c & 0x80)); SPIE.d = 0xBB; while (!(SPIE.c & 0x80)); } At .optimized, the .c and .d struct accesses are direct: ... D.1985_3 ={v} MEM[(volatile struct SPI_t *)2752B].c; D.1986_4 = (signed char) D.1985_3; ... MEM[(volatile struct SPI_t *)2752B].d ={v} 187; ... Then in explow.c:memory_address_addr_space() there is: /* By passing constant addresses through registers we get a chance to cse them. */ if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)) x = force_reg (address_mode, x); So that in .expand the code is ... (insn 5 4 6 3 (set (reg/f:HI 46) (const_int 2752 [0xac0])) pr50448.c:10 -1 (nil)) (insn 6 5 7 3 (set (reg:QI 47) (const_int -86 [0xffaa])) pr50448.c:10 -1 (nil)) (insn 7 6 11 3 (set (mem/s/v:QI (plus:HI (reg/f:HI 46) (const_int 3 [0x3])) [0 MEM[(volatile struct SPI_t *)2752B].d+0 S1 A8]) (reg:QI 47)) pr50448.c:10 -1 (nil)) ... This leads to unpleasant code. The machine can access all RAM locations by direct addressing. However, the resulting code is: foo: ldi r24,lo8(-86) ; 6 *movqi/2[length = 1] ldi r30,lo8(-64) ; 34 *movhi/5[length = 2] ldi r31,lo8(10) std Z+3,r24 ; 7 *movqi/3[length = 1] .L2: lds r24,2754 ; 10 *movqi/4[length = 2] sbrs r24,7 ; 43 *sbrx_branchhi [length = 2] rjmp .L2 ldi r24,lo8(-69) ; 16 *movqi/2[length = 1] ldi r30,lo8(-64) ; 33 *movhi/5[length = 2] ldi r31,lo8(10) std Z+3,r24 ; 17 *movqi/3[length = 1] .L3: lds r24,2754 ; 20 *movqi/4[length = 2] sbrs r24,7 ; 42 *sbrx_branchhi [length = 2] rjmp .L3 ret ; 39 return [length = 1] Insn 34 loads 2752 (0xAC0) to r30/r31 (Z) and does an indirect access (*(Z+3), i.e. *2755) in insn 7. The same happens in insn 33 (load 2752) and access (insn 17). Is there a way to avoid this? I tried -f[no-]rerun-cse-after-loop but without effect, same for -Os/-O2 and trying to patch rtx_costs. cse_not_expected is overridden in some places in the middle-end. What's the preferred way to avoid such "optimization" in the back-end? At least for CONST_INT addresses? AVR has just 2 pointer registers that can do such an access (and only one besides the frame pointer), so it's not very likely that a register is free and CSEing too much might lead to spills or data living in the frame causing bulky load/store from/to stack. Direct access is faster than loading the constant+indirect access (3 times slower). And iff not all of the base address 0xAC0 = 2752 gets factored out to Z+2 resp. Z+3 accesses, the code is bulkier, too. Johann
Re: GCC testting infrastructure issue
Thanks a lot. That is exactly what I was looking for! K On Wed, Sep 28, 2011 at 2:49 PM, Richard Guenther wrote: > On Wed, Sep 28, 2011 at 12:18 PM, Kirill Yukhin > wrote: >> Hi folks, >> I have a question. For DejaGNU we have only one option for each test. >> >> It may be e.g. either "dg-do" compile or "dg-do run". This is really >> not as suitable >> >> For instance, we cheking some new instructio autogeneration. We have >> to do 2 tests: >> 1. We have to write some routine which will contain a pattern which >> will be generated as desired instruction. And check at runtime if that >> was done correctly, comparing to some expected result. We use "dg-do >> run here" >> 2. Next we have to check that instruction really is auto generated, >> so we use "scan-assembler" for that source. >> >> May question is: am I missed something? Is there an opportunity to >> store to tests into single file? If no, why we do not have one? > > Add -save-temps via dg-options, then you can use dg-scan-assembler. > >> Here is reduced example (from gcc.target/i386): >> 1. >> /* run.c */ >> /* { dg-do run } */ >> >> int >> auto_gen_insn(args...) >> { >> /* Code to auto-gen instruction. */ >> return result; >> } >> >> int >> check_semantic(args...) >> { >> /* Code to do the same, but without desired insn. */ >> return result >> } >> >> int >> main () >> { >> if( auto_gen_insn(args...) != check_semantic(args...) ) >> abort (); >> } >> >> 2. >> /* check_gen.c */ >> /* { dg-do compile } */ >> #include "run.c" >> /* { dg-final { scan-assembler-times "insn" 1 } } */ >> >> -- >> Thanks, k >> >
Re: GCC testting infrastructure issue
On Wed, Sep 28, 2011 at 12:18 PM, Kirill Yukhin wrote: > Hi folks, > I have a question. For DejaGNU we have only one option for each test. > > It may be e.g. either "dg-do" compile or "dg-do run". This is really > not as suitable > > For instance, we cheking some new instructio autogeneration. We have > to do 2 tests: > 1. We have to write some routine which will contain a pattern which > will be generated as desired instruction. And check at runtime if that > was done correctly, comparing to some expected result. We use "dg-do > run here" > 2. Next we have to check that instruction really is auto generated, > so we use "scan-assembler" for that source. > > May question is: am I missed something? Is there an opportunity to > store to tests into single file? If no, why we do not have one? Add -save-temps via dg-options, then you can use dg-scan-assembler. > Here is reduced example (from gcc.target/i386): > 1. > /* run.c */ > /* { dg-do run } */ > > int > auto_gen_insn(args...) > { > /* Code to auto-gen instruction. */ > return result; > } > > int > check_semantic(args...) > { > /* Code to do the same, but without desired insn. */ > return result > } > > int > main () > { > if( auto_gen_insn(args...) != check_semantic(args...) ) > abort (); > } > > 2. > /* check_gen.c */ > /* { dg-do compile } */ > #include "run.c" > /* { dg-final { scan-assembler-times "insn" 1 } } */ > > -- > Thanks, k >
Re: A question about detecting array bounds for case Warray-bounds-3.c
On Monday 26 September 2011, Matthew Gretton-Dann wrote: > As far as I understand it -Warray-bounds should be emitting a warning > for this case, but PR31227 seemed to be about removing these warnings. > > The PR comments do not explain why the array accesses are valid and I'm > hoping someone can shed some light on the situation - what are we missing? The fix for PR was when the address of an element beyond the array is taken, but not actually dereferenced (used). For cases where the element is dereferenced it should warn IMHO. Note however that in this case it accesses an adjacent array of the same type in memory, and it is arguable if it should give a warning there or not. I have no strong opinion about this (I suspect that choosing for one variant gives false positives, and the other false negatives). It seems fortify_source has a similar problem, which is why they have added an option for it (1/2): http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html I guess we need the same approach here. Thanks, Dirk
GCC testting infrastructure issue
Hi folks, I have a question. For DejaGNU we have only one option for each test. It may be e.g. either "dg-do" compile or "dg-do run". This is really not as suitable For instance, we cheking some new instructio autogeneration. We have to do 2 tests: 1. We have to write some routine which will contain a pattern which will be generated as desired instruction. And check at runtime if that was done correctly, comparing to some expected result. We use "dg-do run here" 2. Next we have to check that instruction really is auto generated, so we use "scan-assembler" for that source. May question is: am I missed something? Is there an opportunity to store to tests into single file? If no, why we do not have one? Here is reduced example (from gcc.target/i386): 1. /* run.c */ /* { dg-do run } */ int auto_gen_insn(args...) { /* Code to auto-gen instruction. */ return result; } int check_semantic(args...) { /* Code to do the same, but without desired insn. */ return result } int main () { if( auto_gen_insn(args...) != check_semantic(args...) ) abort (); } 2. /* check_gen.c */ /* { dg-do compile } */ #include "run.c" /* { dg-final { scan-assembler-times "insn" 1 } } */ -- Thanks, k