Re: What does zero-length array mean at file scope?
Hello! I found something rather odd in testcase gcc.c-torture/execute/20030811-1.c: > /* Origin: PR target/11535 from H. J. Lu */ > > void vararg (int i, ...) > { > (void) i; > } > > int i0[0], i1; Huh? > void test1 (void) > { > int a = (int) (long long) __builtin_return_address (0); > vararg (0, a); > } > > void test2 (void) > { > i0[0] = (int) (long long) __builtin_return_address (0); > } Nasal demons? > void test3 (void) > { > i1 = (int) (long long) __builtin_return_address (0); > } > > void test4 (void) > { > volatile long long a = (long long) __builtin_return_address (0); > i0[0] = (int) a; > } And testing it on Linux, I see that the linker goes ahead and assigns zero bytes of the common area to i0, then assigns four bytes of common space to i1 at the same address, so writing to i0[0] aliases and alters i1. That certainly sounds like undefined behaviour to me! It looks like a typo in the testcase to me, but let's add some CCs to be sure. Uros.
a strange make error
I' m trying to make some changes to GCC4.2. I want to obtain some information about callee so i add one statment to function: rtx expand_call (tree exp, rtx target, int ignore) as follows: 2702 /* Generate the actual call instruction. */ 2703 emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size, 2704 adjusted_args_size.constant, struct_value_size, 2705 next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, 2706 flags, & args_so_far); 2707 tree callee = DECL_SAVED_TREE(fndecl); /* added stamtment by myself */ Then, i get following strange make error message: make[2]: *** [crtend.o] Error 1 ../.././gcc/crtstuff.c: In function ‘__do_global_ctors_aux’: ../.././gcc/crtstuff.c:521: internal compiler error: Segmentation ../.././gcc/crtstuff.c: In function ‘__do_global_dtors_aux’: ../.././gcc/crtstuff.c:287: internal compiler error: Segmentation fault make[2]: *** [crtbegin.o] Error 1 make[2]: Leaving directory `/wxiao3/src/gcc-4.2.0/host-i686-pc-linux-gnu/gcc' make[1]: *** [install-gcc] Error 2 make[1]: Leaving directory `/wxiao3/src/gcc-4.2.0' make: *** [install] Error 2 What's the cause of these errors? I have never touch the files such as crtend.c and crtstuff.c. I only add one statement to calls.c.
Re: Seeking suggestion
Jamie Prescott schrieb: Is there a reason why something like this would not work? (define_insn "addsi3_nc" [(set (match_operand:SI 0 "fullreg_operand" "=r") (plus:SI (match_operand:SI 1 "fullreg_operand" "r") (match_operand:SI 2 "fullreg_or_imm_operand" "rn")))] "" "..." ) (define_expand "addsi3" [(set (match_operand:SI 0 "fullreg_operand" "=r") (plus:SI (match_operand:SI 1 "fullreg_operand" "r") (match_operand:SI 2 "fullreg_or_imm_operand" "rn")))] "" { if (!TARGET_XXX2) emit_clobber(gen_rtx_REG(CCmode, CC_REGNUM)); emit_insn(gen_addsi3_nc(operands[0], operands[1], operands[2])); DONE; } ) That would limit to two instructions per basic insns, instead of the current three. Thanks, - Jamie Maybe that works. But I would not include such stuff in one of my machine descriptions because addsi3_nc lies: Its effect on the machine differ from what it states algebraically in RTL. Therefore, you may get trouble in corner cases or when instructions are reordered/scheduled/combined/... Georg-Johann
Re: What does zero-length array mean at file scope?
Dave Korn wrote: > Dave Korn wrote: >> Dave Korn wrote: >> >>> ELF GAS/LD seem happy enough when presented with a ".comm foo,0" >>> directive, >>> but PE does rather literally what you asked, and gives you no data object, >>> leading to i0 in the above being an undefined reference at link time. >> After a bit further digging, it turns out that this is because PE uses the >> same representation for an external symbol as would represent a common of >> size >> 0, so if you define such a common, it magically becomes an undefined external >> symbol instead! I don't see what the big deal is here: just allocate one byte to a statically- allocated zero-length array. > And testing it on Linux, I see that the linker goes ahead and assigns zero > bytes of the common area to i0, then assigns four bytes of common space to i1 > at the same address, so writing to i0[0] aliases and alters i1. That > certainly sounds like undefined behaviour to me! Sure, but in that case it's clearly the user's fault: they're writing beyond the bounds of an array. Andrew.
Re: What does zero-length array mean at file scope?
Andrew Haley wrote: > Dave Korn wrote: >> Dave Korn wrote: >>> Dave Korn wrote: >>> ELF GAS/LD seem happy enough when presented with a ".comm foo,0" directive, but PE does rather literally what you asked, and gives you no data object, leading to i0 in the above being an undefined reference at link time. >>> After a bit further digging, it turns out that this is because PE uses >>> the same representation for an external symbol as would represent a >>> common of size 0, so if you define such a common, it magically becomes >>> an undefined external symbol instead! > > I don't see what the big deal is here: just allocate one byte to a > statically- allocated zero-length array. The "big deal" is that this is blatantly and trivially invalid code, and we silently accept it and generate nonsensical assembler output without the least hint of any kind of a diagnostic. " 6.7.5.2 Array declarators Constraints 1 In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. " > Sure, but in that case it's clearly the user's fault: they're writing > beyond the bounds of an array. But how, as a user, would you attempt to write /within/ the bounds of such an array? Exactly. So why should we let the user create this meaningless construct in the first place? cheers, DaveK
Re: a strange make error
william xiao wrote: > I' m trying to make some changes to GCC4.2. I want to obtain some > information about callee so i add one statment to function: rtx > expand_call (tree exp, rtx target, int ignore) as follows: > > 2702 /* Generate the actual call instruction. */ > 2703 emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size, > 2704 adjusted_args_size.constant, struct_value_size, > 2705 next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, > 2706 flags, & args_so_far); > 2707 tree callee = DECL_SAVED_TREE(fndecl); /* added stamtment by myself > */ > > Then, i get following strange make error message: > > > make[2]: *** [crtend.o] Error 1 > ../.././gcc/crtstuff.c: In function ‘__do_global_ctors_aux’: > ../.././gcc/crtstuff.c:521: internal compiler error: Segmentation > ../.././gcc/crtstuff.c: In function ‘__do_global_dtors_aux’: > ../.././gcc/crtstuff.c:287: internal compiler error: Segmentation fault > make[2]: *** [crtbegin.o] Error 1 > make[2]: Leaving directory `/wxiao3/src/gcc-4.2.0/host-i686-pc-linux-gnu/gcc' > make[1]: *** [install-gcc] Error 2 > make[1]: Leaving directory `/wxiao3/src/gcc-4.2.0' > make: *** [install] Error 2 > > What's the cause of these errors? I have never touch the files such > as crtend.c and crtstuff.c. I only add one statement to calls.c. The files crtend.c and crtstuff.c are being compiled by the newly-built compiler, as the form part of the libgcc for the target, and it is your newly-built compiler that is crashing, owing to a bug in the change you made to calls.c. It's really hard to see what could be wrong with adding a call to DECL_SAVED_TREE if fndecl isn't NULL, but from the look of some of the code just a few lines earlier in the function: /* If register arguments require space on the stack and stack space was not preallocated, allocate stack space here for arguments passed in registers. */ if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) ... it seems to me that that is at least a possibility that you have to deal with. cheers, DaveK
Limiting the use of pointer registers
Hi there. I'm working on a port to an architecture where the pointer registers X and Y are directly backed by small 128 byte caches. Changing one of these registers to a different memory row causes a cache load cycle, so using them for memory access is fine but using them as general purpose registers is expensive. How can I prevent the register allocator from using these for anything but memory access? I have a register class called ADDR_REGS that contains just X and Y and one called DATA_REGS which contains the general registers R10 to R1E. GENERAL_REGS is the same as DATA_REGS. The order they appear in in reg_class is DATA_REGS, GENERAL_REGS, then ADDR_REGS. I've defined the constrains for most of the patterns to only take 'r' which prevents X or Y being used as operands for those patterns. I have to allow X and Y to be used in movsi and addsi3 to allow indirect memory addresses to be calculated. Unfortunately Pmode is SImode so I can't tell the difference between pointer and normal values in PREFERRED_RELOAD_CLASS, LIMIT_RELOAD_CLASS, or TARGET_SECONDARY_RELOAD. I tried setting REGISTER_MOVE_COST and MEMORY_MOVE_COST to 100 when the source or destination is ADDR_REGS but this didn't affect the output. I suspect that I'll have to do the same as the accumulator and hide X and Y from the register allocator. Pretend that any general register can access memory and then use post reload split to turn the patterns into X based patterns for the later phases to tidy up. One more question. The backing caches aren't coherent so X and Y can't read and write to the same 128 bytes of memory at the same time. Does GCC have any other information about the location of a pointer that I could use? Something like: * Pointer is to text memory or read only data, so it is safe to read from * Pointer 1 is in the stack and pointer 2 is in BSS, so they are definitely far apart * Pointer 1 is to to one on stack item and pointer 2 is to a stack item at least 128 bytes apart * The call stack is known and pointer 1 and pointer 2 point to different rows My fallback plan is to add a variable attribute so the programmer can mark the pointer as non overlapping and push the problem onto them. Something clever would be nice though :) Sorry for all the questions - this is quite a difficult architecture. I hope to collect all the answers and do a write up for others to use when I'm done. -- Michael
Re: What does zero-length array mean at file scope?
Dave Korn wrote: > Andrew Haley wrote: >> Dave Korn wrote: >>> Dave Korn wrote: Dave Korn wrote: > ELF GAS/LD seem happy enough when presented with a ".comm foo,0" > directive, but PE does rather literally what you asked, and gives you > no data object, leading to i0 in the above being an undefined > reference at link time. After a bit further digging, it turns out that this is because PE uses the same representation for an external symbol as would represent a common of size 0, so if you define such a common, it magically becomes an undefined external symbol instead! >> I don't see what the big deal is here: just allocate one byte to a >> statically- allocated zero-length array. > > The "big deal" is that this is blatantly and trivially invalid code, and we > silently accept it and generate nonsensical assembler output without the least > hint of any kind of a diagnostic. Of course we have to fix the assembler output. For ant two declarations a and b, &a != &b, even when a is a zero-length array. So, you have to allocate at least one byte. > " 6.7.5.2 Array declarators > Constraints > 1 In addition to optional type qualifiers and the keyword static, the [ and > ] may delimit an expression or *. If they delimit an expression (which > specifies the size of an array), the expression shall have an integer type. If > the expression is a constant expression, it shall have a value greater than > zero. " But zero-length arrays are a gcc extension. There's nothing that limits them to the last member of a struct. zero-length arrays must be rejected with -pedantic, but not otherwise. >> Sure, but in that case it's clearly the user's fault: they're writing >> beyond the bounds of an array. > > But how, as a user, would you attempt to write /within/ the bounds of such > an array? You can't. > Exactly. So why should we let the user create this meaningless > construct in the first place? Because it's a documented gcc extension. Andrew.
Re: What does zero-length array mean at file scope?
Dave Korn wrote: > I've read http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html about six > times and can't see anywhere it even hints that you can use this syntax > anywhere except as the trailing member of a struct. Andrew Haley wrote: > But zero-length arrays are a gcc extension. There's nothing that limits > them to the last member of a struct. zero-length arrays must be rejected > with -pedantic, but not otherwise. > Because it's a documented gcc extension. Obviously I can't see for looking; can you please point me to the precise chapter/page/paragraph/line that I should have found earlier? cheers, DaveK
Re: What does zero-length array mean at file scope?
Dave Korn wrote: > Dave Korn wrote: >> I've read http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html about six >> times and can't see anywhere it even hints that you can use this syntax >> anywhere except as the trailing member of a struct. > > Andrew Haley wrote: >> But zero-length arrays are a gcc extension. There's nothing that limits >> them to the last member of a struct. zero-length arrays must be rejected >> with -pedantic, but not otherwise. > >> Because it's a documented gcc extension. > > Obviously I can't see for looking; can you please point me to the precise > chapter/page/paragraph/line that I should have found earlier? (I honestly mean that, no sarcasm intended; it was late at night and I was tired, I could easily have misread or overlooked something.) I did find this comment in varasm.c:assemble_noswitch_variable() that says we need to handle this case: /* Don't allocate zero bytes of common, since that means "undefined external" in the linker. */ if (size == 0) rounded = 1; ... so I guess it counts as a backend bug if the backend still emits a zero in the .comm directive, and that the documentation of ASM_OUTPUT.*COMMON should probably be improved to warn of the danger that size may be zero. cheers, DaveK
problem with getting statements (DECL_SAVED_TREE?)
Hi, I'm trying to help with the porting of dehydra / treehydra to gcc 4.5. There are some tests that are failing, and in working through them, I'm finding some issues that might be differences between 4.3 and 4.5. One problem is about walking the instructions associated with a function. The treehydra code is a bit convoluted, so I've converted it into a testsuite case. See attached. Essentially, the problem appears to be that DECL_SAVED_TREE() returns null. If I understand the treehydra code, that used to provide a list of GENERIC instructions. Is there a way to get that in 4.5? Brad Index: testsuite/g++.dg/plugin/exec_plugin.c === --- testsuite/g++.dg/plugin/exec_plugin.c (revision 0) +++ testsuite/g++.dg/plugin/exec_plugin.c (revision 0) @@ -0,0 +1,94 @@ +/* test case for DECL_SAVED_TREE */ + +#include +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "gcc-plugin.h" + + +static unsigned int +execute_exec_plugin_example (void) +{ + warning (0, "%p", DECL_SAVED_TREE (current_function_decl)); + return 0; +} + +static struct gimple_opt_pass pass_exec_plugin_example = +{ + { +GIMPLE_PASS, +"exec_plugin",/* name */ +NULL, /* gate */ +execute_exec_plugin_example, /* execute */ +NULL, /* sub */ +NULL, /* next */ +0,/* static_pass_number */ +0,/* tv_id */ +PROP_cfg, /* properties_required */ +0,/* properties_provided */ +0,/* properties_destroyed */ +0,/* todo_flags_start */ +TODO_dump_func/* todo_flags_finish */ + } +}; + +/* Initialization function that GCC calls. This plugin takes an argument + that specifies the name of the reference pass and an instance number, + both of which determine where the plugin pass should be inserted. */ + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + struct plugin_pass pass_info; + const char *plugin_name = plugin_info->base_name; + int argc = plugin_info->argc; + struct plugin_argument *argv = plugin_info->argv; + char *ref_pass_name = NULL; + int ref_instance_number = 0; + int i; + + /* Process the plugin arguments. This plugin takes the following arguments: + ref-pass-name= and ref-pass-instance-num=. */ + for (i = 0; i < argc; ++i) +{ + if (!strcmp (argv[i].key, "ref-pass-name")) +{ + if (argv[i].value) +ref_pass_name = argv[i].value; + else +warning (0, G_("option '-fplugin-arg-%s-ref-pass-name'" + " requires a pass name"), plugin_name); +} + else if (!strcmp (argv[i].key, "ref-pass-instance-num")) +{ + if (argv[i].value) +ref_instance_number = strtol (argv[i].value, NULL, 0); + else +warning (0, G_("option '-fplugin-arg-%s-ref-pass-instance-num'" + " requires an integer value"), plugin_name); +} + else +warning (0, G_("plugin %qs: unrecognized argument %qs ignored"), + plugin_name, argv[i].key); +} + + if (!ref_pass_name) +{ + error (G_("plugin %qs requires a reference pass name"), plugin_name); + return 1; +} + + pass_info.pass = &pass_exec_plugin_example.pass; + pass_info.reference_pass_name = ref_pass_name; + pass_info.ref_pass_instance_number = ref_instance_number; + pass_info.pos_op = PASS_POS_INSERT_AFTER; + + register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); + + return 0; +} Index: testsuite/g++.dg/plugin/plugin.exp === --- testsuite/g++.dg/plugin/plugin.exp (revision 147827) +++ testsuite/g++.dg/plugin/plugin.exp (working copy) @@ -48,6 +48,7 @@ # plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... } set plugin_test_list [list \ { attribute_plugin.c attribute_plugin-test-1.C } \ +{ exec_plugin.c exec_plugin-test-1.C } \ { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \ { dumb_plugin.c dumb-plugin-test-1.C } ] Index: testsuite/g++.dg/plugin/exec_plugin-test-1.C === --- testsuite/g++.dg/plugin/exec_plugin-test-1.C (revision 0) +++ testsuite/g++.dg/plugin/exec_plugin-test-1.C (revision 0) @@ -0,0 +1,16 @@ +// Test case for the exec plugin. +// { dg-do compile } +// { dg-options "-O -fplugin-arg-exec_plugin-ref-pass-name=cfg -fplugin-arg-exec_plugin-ref-pass
Re: problem with getting statements (DECL_SAVED_TREE?)
On Sun, May 24, 2009 at 1:38 PM, Brad Hards wrote: > Hi, > > I'm trying to help with the porting of dehydra / treehydra to gcc 4.5. > > There are some tests that are failing, and in working through them, I'm > finding some issues that might be differences between 4.3 and 4.5. > > One problem is about walking the instructions associated with a function. The > treehydra code is a bit convoluted, so I've converted it into a testsuite > case. See attached. > > Essentially, the problem appears to be that DECL_SAVED_TREE() returns null. If > I understand the treehydra code, that used to provide a list of GENERIC > instructions. Is there a way to get that in 4.5? It depends on when you hook into the gcc pipeline. DECL_SAVED_TREE will only be available before gimplification (gimplification doesn't run as part of a pass, it is currently invoked by the frontends). Richard. > Brad > >
Re: problem with getting statements (DECL_SAVED_TREE?)
On Sunday 24 May 2009 10:03:36 pm Richard Guenther wrote: > On Sun, May 24, 2009 at 1:38 PM, Brad Hards wrote: > > Essentially, the problem appears to be that DECL_SAVED_TREE() returns > > null. If I understand the treehydra code, that used to provide a list of > > GENERIC instructions. Is there a way to get that in 4.5? > > It depends on when you hook into the gcc pipeline. DECL_SAVED_TREE will > only be available before gimplification (gimplification doesn't run as part > of a pass, it is currently invoked by the frontends). I'm pretty flexible about where we hook in - the current default is after "useless". If the output of the front ends is GIMPLE, then I guess I need to work in terms of GIMPLE statements? Brad
Re: problem with getting statements (DECL_SAVED_TREE?)
On Sun, May 24, 2009 at 2:29 PM, Brad Hards wrote: > On Sunday 24 May 2009 10:03:36 pm Richard Guenther wrote: >> On Sun, May 24, 2009 at 1:38 PM, Brad Hards wrote: >> > Essentially, the problem appears to be that DECL_SAVED_TREE() returns >> > null. If I understand the treehydra code, that used to provide a list of >> > GENERIC instructions. Is there a way to get that in 4.5? >> >> It depends on when you hook into the gcc pipeline. DECL_SAVED_TREE will >> only be available before gimplification (gimplification doesn't run as part >> of a pass, it is currently invoked by the frontends). > I'm pretty flexible about where we hook in - the current default is > after "useless". > > If the output of the front ends is GIMPLE, then I guess I need to work in > terms of GIMPLE statements? The frontend still outputs GENERIC, but at useless you have unlowered gimple already (also known as 'tuples' these days). This was true before, just that gimple was a subset of GENERIC, even from a data-structure point of view. The GIMPLE of today is accessible via gimple_body (). Richard. > Brad > > >
Re: What does zero-length array mean at file scope?
Dave Korn wrote: > Dave Korn wrote: >> Dave Korn wrote: >>> I've read http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html about six >>> times and can't see anywhere it even hints that you can use this syntax >>> anywhere except as the trailing member of a struct. >> Andrew Haley wrote: >>> But zero-length arrays are a gcc extension. There's nothing that limits >>> them to the last member of a struct. zero-length arrays must be rejected >>> with -pedantic, but not otherwise. >>> Because it's a documented gcc extension. >> Obviously I can't see for looking; can you please point me to the precise >> chapter/page/paragraph/line that I should have found earlier? "Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure ..." That doesn't in any way imply that the last element of a struct is the only circumstance in which you may use a zero-length array. > (I honestly mean that, no sarcasm intended; it was late at night and I was > tired, I could easily have misread or overlooked something.) I did find this > comment in varasm.c:assemble_noswitch_variable() that says we need to handle > this case: > > /* Don't allocate zero bytes of common, > since that means "undefined external" in the linker. */ > if (size == 0) > rounded = 1; > > ... so I guess it counts as a backend bug if the backend still emits a zero in > the .comm directive, and that the documentation of ASM_OUTPUT.*COMMON should > probably be improved to warn of the danger that size may be zero. Yes. That's what is usually done: all you have to do is fix the back end. Andrew.
Re: What does zero-length array mean at file scope?
Andrew Haley wrote: >>> Obviously I can't see for looking; can you please point me to the precise >>> chapter/page/paragraph/line that I should have found earlier? > > "Zero-length arrays are allowed in GNU C. They are very useful as the > last element of a structure ..." > > That doesn't in any way imply that the last element of a struct is the only > circumstance in which you may use a zero-length array. *boggle* Yes, I must have been tired! I repeatedly scanned that as "Zero-length arrays are allowed in GNU C [ ... eyes or perhaps brain go blurry about here ... ] as the last element of a structure which is really a header for a variable-length object" > Yes. That's what is usually done: all you have to do is fix the back end. :) Just to be helpful, I added a few extra words to the documentation for ASM_OUTPUT_COMMON in my revised patch. http://gcc.gnu.org/ml/gcc-patches/2009-05/msg01545.html cheers, DaveK
[RFC] removing statement walking from domwalk.c?
Hi all, for my next patch to fwprop for PR33928, I need a dominator walk and I would have liked to use domwalk.c; however it is only for trees at the moment, while I need it on RTL. I was thinking therefore of removing the following fields from the dominator walk callbacks: BOOL_BITFIELD walk_stmts_backward : 1; void (*before_dom_children_walk_stmts) (struct dom_walk_data *, basic_block, gimple_stmt_iterator); void (*after_dom_children_walk_stmts) (struct dom_walk_data *, basic_block, gimple_stmt_iterator); (the last is unused anyway). After merging the before_stmts/after_stmts callbacks into one, the callbacks would be initialize_block_local_data, before_dom_children and after_dom_children. I would of course take care of adapting the current uses, which would be quite mechanical (and anyway there are just half a dozen). Any objections? I don't know exactly when I'll get to it, but I hope by the end of June. Paolo
Re: [RFC] removing statement walking from domwalk.c?
On Sun, May 24, 2009 at 7:09 PM, Paolo Bonzini wrote: > Hi all, > > for my next patch to fwprop for PR33928, I need a dominator walk and I > would have liked to use domwalk.c; however it is only for trees at the > moment, while I need it on RTL. > > I was thinking therefore of removing the following fields from the > dominator walk callbacks: > > BOOL_BITFIELD walk_stmts_backward : 1; > > void (*before_dom_children_walk_stmts) (struct dom_walk_data *, > basic_block, > gimple_stmt_iterator); > > void (*after_dom_children_walk_stmts) (struct dom_walk_data *, > basic_block, > gimple_stmt_iterator); > > (the last is unused anyway). After merging the before_stmts/after_stmts > callbacks into one, the callbacks would be initialize_block_local_data, > before_dom_children and after_dom_children. I would of course take care > of adapting the current uses, which would be quite mechanical (and > anyway there are just half a dozen). > > Any objections? I don't know exactly when I'll get to it, but I hope by > the end of June. Works for me. Richard.
Re: Seeking suggestion
On Fri, May 22, 2009 at 05:04:22PM -0700, Jamie Prescott wrote: > > > From: Jamie Prescott > > To: gcc@gcc.gnu.org > > Sent: Friday, May 22, 2009 10:36:47 AM > > Subject: Seeking suggestion > > > > > > Suppose you're writing the backend for a VM supporting two architectures, > > in > > which > > one of them clobbers the CC registers for certain instructions, while the > > other > > does not. > > The instructions themselves are exactly the same. > > What is the best/shortest/more-elegant way to write this, possibly w/out > > duplicating the > > instructions? > > I know I can write a define_expand and redirect, based on the TARGET, to > > two > > different > > instructions (one with "clobber", the other w/out), but that's basically > > three > > declarations > > for each insns. Is there a shorter way? > > I ended up doing something like this (long way, but the only one I know of). > Example, for addsi3: > > (define_insn "addsi3_xxx2" > [(set (match_operand:SI 0 "fullreg_operand" "=r,r") > (plus:SI (match_operand:SI 1 "fullreg_operand" "0,r") > (match_operand:SI 2 "fullreg_or_imm_operand" "rn,rn")))] > "" > "@ >add\t%0,%2,%0 >add\t%1,%2,%0" > ) > > (define_insn "addsi3_xxx" > [(set (match_operand:SI 0 "fullreg_operand" "=r,r") > (plus:SI (match_operand:SI 1 "fullreg_operand" "0,r") > (match_operand:SI 2 "fullreg_or_imm_operand" "rn,rn"))) >(clobber (reg:CC CC_REG))] > "" > "@ >add\t%0,%2,%0 >add\t%1,%2,%0" > ) > > (define_expand "addsi3" > [(set (match_operand:SI 0 "fullreg_operand" "=r,r") > (plus:SI (match_operand:SI 1 "fullreg_operand" "0,r") > (match_operand:SI 2 "fullreg_or_imm_operand" "rn,rn")))] > "" > { > if (!TARGET_XXX2) > emit_insn(gen_addsi3_xxx(operands[0], operands[1], operands[2])); > else > emit_insn(gen_addsi3_xxx2(operands[0], operands[1], operands[2])); > DONE; > } > ) One way is to use match_scratch, and different register classes for the two cases. (define_insn "add3" [(set (match_operand:SI 0 "register_operand" "=x,y") (plus:SI (match_operand:SI 1 "register_operand" "%x,y") (match_operand:SI 2 "register_operand" "x,y"))) (clobber (match_scratch:CC 3 "=X,z"))] "" "add %0,%1,%2") (define_register_constraint "x" "TARGET_MACHINE ? GENERAL_REGS : NO_REGS" "@internal") (define_register_constraint "y" "!TARGET_MACHINE ? GENERAL_REGS : NO_REGS" "@internal") (define_register_constraint "z" CR_REGS "@interal") This assumes you have a register class for the condition code register. Most machines however, use the normal define_expand with two different insns. In theory, you could define a second condition code register that doesn't actually exist in the machine, and change the clobber from the main CC to the fake one. > But now I get and invalid rtx sharing from the push/pop parallels: > > > .c: In function 'test_dashr': > .c:32: error: invalid rtl sharing found in the insn > (insn 26 3 28 2 .c:26 (parallel [ > (insn/f 25 0 0 (set (reg/f:SI 51 SP) > (minus:SI (reg/f:SI 51 SP) > (const_int 4 [0x4]))) -1 (nil)) > (set/f (mem:SI (reg/f:SI 51 SP) [0 S4 A8]) > (reg:SI 8 r8)) > ]) -1 (nil)) > .c:32: error: shared rtx > (insn/f 25 0 0 (set (reg/f:SI 51 SP) > (minus:SI (reg/f:SI 51 SP) > (const_int 4 [0x4]))) -1 (nil)) > .c:32: internal compiler error: internal consistency failure I suspect you don't have the proper guards on the push/pop insns, and the combiner is eliminating the clobber. You probably need to have parallel insns for the push and pop. -- Michael Meissner, IBM 4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA meiss...@linux.vnet.ibm.com
gcc-4.3-20090524 is now available
Snapshot gcc-4.3-20090524 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.3-20090524/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.3 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_3-branch revision 147837 You'll find: gcc-4.3-20090524.tar.bz2 Complete GCC (includes all of below) gcc-core-4.3-20090524.tar.bz2 C front end and core compiler gcc-ada-4.3-20090524.tar.bz2 Ada front end and runtime gcc-fortran-4.3-20090524.tar.bz2 Fortran front end and runtime gcc-g++-4.3-20090524.tar.bz2 C++ front end and runtime gcc-java-4.3-20090524.tar.bz2 Java front end and runtime gcc-objc-4.3-20090524.tar.bz2 Objective-C front end and runtime gcc-testsuite-4.3-20090524.tar.bz2The GCC testsuite Diffs from 4.3-20090517 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.3 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
Re: Limiting the use of pointer registers
Michael Hope writes: > How can I prevent the register allocator from using these for anything > but memory access? Unfortunately, you can't. You can make them the last registers the allocator will use, but if you say that they can hold Pmode values then the register allocator will use them. > I suspect that I'll have to do the same as the accumulator and hide X > and Y from the register allocator. Pretend that any general register > can access memory and then use post reload split to turn the patterns > into X based patterns for the later phases to tidy up. I agree. > > One more question. The backing caches aren't coherent so X and Y > can't read and write to the same 128 bytes of memory at the same time. > Does GCC have any other information about the location of a pointer > that I could use? Something like: > * Pointer is to text memory or read only data, so it is safe to read from > * Pointer 1 is in the stack and pointer 2 is in BSS, so they are > definitely far apart > * Pointer 1 is to to one on stack item and pointer 2 is to a stack > item at least 128 bytes apart > * The call stack is known and pointer 1 and pointer 2 point to different rows Ouch. You can get alias set information but I don't think it will help. In some cases you can look in REG_ATTRS to at least get the original decl that the register is associated with. This information is not always there, and it won't always be useful, but it may at least let you distinguish between a function pointer and a data pointer. After reload, you need to look at ORIGINAL_REGNO to get the original register number (if any) and look at regno_reg_rtx[orig_regno]. Ian
Re: Limiting the use of pointer registers
On Sun, May 24, 2009 at 10:23:05PM +1200, Michael Hope wrote: > Hi there. I'm working on a port to an architecture where the pointer > registers X and Y are directly backed by small 128 byte caches. > Changing one of these registers to a different memory row causes a > cache load cycle, so using them for memory access is fine but using > them as general purpose registers is expensive. > > How can I prevent the register allocator from using these for anything > but memory access? I have a register class called ADDR_REGS that > contains just X and Y and one called DATA_REGS which contains the > general registers R10 to R1E. GENERAL_REGS is the same as DATA_REGS. > The order they appear in in reg_class is DATA_REGS, GENERAL_REGS, then > ADDR_REGS. I've defined the constrains for most of the patterns to > only take 'r' which prevents X or Y being used as operands for those > patterns. I have to allow X and Y to be used in movsi and addsi3 to > allow indirect memory addresses to be calculated. > > Unfortunately Pmode is SImode so I can't tell the difference between > pointer and normal values in PREFERRED_RELOAD_CLASS, > LIMIT_RELOAD_CLASS, or TARGET_SECONDARY_RELOAD. I tried setting > REGISTER_MOVE_COST and MEMORY_MOVE_COST to 100 when the source or > destination is ADDR_REGS but this didn't affect the output. > > I suspect that I'll have to do the same as the accumulator and hide X > and Y from the register allocator. Pretend that any general register > can access memory and then use post reload split to turn the patterns > into X based patterns for the later phases to tidy up. One thought is to make Pmode PSImode instead of SImode. You may have to define a bunch of duplicate insns that do arithmetic on PSImode values instead of SImode values, and you may run into some problems about PSImode because it isn't widely used. I am in the middle of writing a paper right now, where I mention that one of the things I've felt was wrong since I've been hacking GCC is that the RTL backend assumes pointers are just integers. > One more question. The backing caches aren't coherent so X and Y > can't read and write to the same 128 bytes of memory at the same time. > Does GCC have any other information about the location of a pointer > that I could use? Something like: > * Pointer is to text memory or read only data, so it is safe to read from > * Pointer 1 is in the stack and pointer 2 is in BSS, so they are > definitely far apart > * Pointer 1 is to to one on stack item and pointer 2 is to a stack > item at least 128 bytes apart > * The call stack is known and pointer 1 and pointer 2 point to different rows Look at the mem_attrs structure in rtl.h. However, it looks like you have a very challenging machine on your hands. > My fallback plan is to add a variable attribute so the programmer can > mark the pointer as non overlapping and push the problem onto them. > Something clever would be nice though :) Another place where the named address spaces stuff I worked on last year might be useful. > Sorry for all the questions - this is quite a difficult architecture. > I hope to collect all the answers and do a write up for others to use > when I'm done. > > -- Michael -- Michael Meissner, IBM 4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA meiss...@linux.vnet.ibm.com
extern const (Was: Re: [gcc-in-cxx]: patches from multi-target-4_4-branch)
Quoting Ian Lance Taylor : Joern Rennecke writes: * config/sh/sh.c (sh_attribute_table): Use extern in forward declaration. Common issue with declaring/defining const variables in C++. I've been doing this as #ifdef __cplusplus extern #endif These #ifdefs sprinkled over the code are awkward. Could we use a #define for this? E.g. put in system.h #ifdef __cplusplus #define CONST_VAR_DECL extern const #else #define CONST_VAR_DECL const #endif
Re: extern const (Was: Re: [gcc-in-cxx]: patches from multi-target-4_4-branch)
Joern Rennecke writes: > Quoting Ian Lance Taylor : >> Joern Rennecke writes: >>> * config/sh/sh.c (sh_attribute_table): Use extern in forward >>> declaration. >>> Common issue with declaring/defining const variables in C++. >> >> I've been doing this as >> >> #ifdef __cplusplus >> extern >> #endif > > These #ifdefs sprinkled over the code are awkward. Could we use a #define > for this? E.g. put in system.h > #ifdef __cplusplus > #define CONST_VAR_DECL extern const > #else > #define CONST_VAR_DECL const > #endif Yes, that is certainly the way to go if it is in fact not safe to use "extern const int i = 1;" for all C compilers. I hadn't planned to deal with this issue yet, but since you bring it up, we should decide whether that construct is safe, or whether we need the macro. Ian
Re: extern const (Was: Re: [gcc-in-cxx]: patches from multi-target-4_4-branch)
Quoting Ian Lance Taylor : Joern Rennecke writes: ... Could we use a #define for this? E.g. put in system.h #ifdef __cplusplus #define CONST_VAR_DECL extern const #else #define CONST_VAR_DECL const #endif Yes, that is certainly the way to go if it is in fact not safe to use "extern const int i = 1;" for all C compilers. I hadn't planned to deal with this issue yet, but since you bring it up, we should decide whether that construct is safe, or whether we need the macro. I think it would also be a better interim solution, since it is easier to code, easier to switch experimentally, and easier to globally replace with extern const if we decide that that is safe for all the C bootstrap compilers we care about.
Re: extern const (Was: Re: [gcc-in-cxx]: patches from multi-target-4_4-branch)
Joern Rennecke writes: > Quoting Ian Lance Taylor : > >> Joern Rennecke writes: >>> ... Could we use a #define >>> for this? E.g. put in system.h >>> #ifdef __cplusplus >>> #define CONST_VAR_DECL extern const >>> #else >>> #define CONST_VAR_DECL const >>> #endif >> >> Yes, that is certainly the way to go if it is in fact not safe to use >> "extern const int i = 1;" for all C compilers. I hadn't planned to deal >> with this issue yet, but since you bring it up, we should decide whether >> that construct is safe, or whether we need the macro. > > I think it would also be a better interim solution, since it is easier to > code, easier to switch experimentally, and easier to globally replace with > extern const if we decide that that is safe for all the C bootstrap compilers > we care about. Seems reasonable, though I'd like to wait at least a couple of days to see if anybody else has a comment. I think the macro name should simply be EXTERN_CONST. Ian