Is the GCC optimazer too smart?
Hi All, I just joined the list and I'm not a compiler guru, so I'd like "the list" opinion on a behavior I notice today. Not sure it is really a bug, so do not want to directly open a bug in the bugzilla repository. Consider the below sample code: #include int main(int argc, char** argv) { const int i = 0; printf("i: %d\n", i); foo(&i); printf("i: %d\n", i); return 0; } I compiled the above code without any optimization flag, and with the -O3 flag. [bash] sborg...@ree> gcc gcc_const_optimazer_bug.c -o gcc_const_optimazer_bug gcc_const_optimazer_bug.c: In function `main': gcc_const_optimazer_bug.c:18: warning: passing arg 1 of `foo' discards qualifiers from pointer target type [bash] sborg...@ree> ./gcc_const_optimazer_bug i: 0 i: 42 [bash] sborg...@ree> gcc -O3 gcc_const_optimazer_bug.c -o gcc_const_optimazer_bug gcc_const_optimazer_bug.c: In function `main': gcc_const_optimazer_bug.c:18: warning: passing arg 1 of `foo' discards qualifiers from pointer target type [bash] sborg...@ree> ./gcc_const_optimazer_bug i: 0 i: 0 Now my question is: is it correct that the compiler enforces the constantness of the variable, even tought it states in the warning that the const qualifier has been discarded? Best Regards Sergio -- preferisco ammazzare il tempo, preferisco sparare cazzate, preferisco fare esplodere una moda, preferisco morire d'amore. (Caparezza)
Re: Is the GCC optimizer too smart?
On 12/10/2009 01:03 PM, sergio borghese wrote: > Now my question is: is it correct that the compiler enforces the > constantness of the variable, even tought it states in the warning > that the const qualifier has been discarded? > I think you are missing that the compiler is not "enforcing" anything, just doing what it likes best depending on the circumstances, since you are triggering an undefined behavior and anything can happen, in principle. By the way, this kind of question is more suited for gcc-help. Paolo.
Re: Is the GCC optimazer too smart?
2009/12/10 sergio borghese: > > Now my question is: is it correct that the compiler enforces the > constantness of the variable, even tought it states in the warning > that the const qualifier has been discarded? the calls to printf can be optimised to printf("i: %dn", 0) so it doesn't use the value of i, because the compiler knows that the value of i cannot be changed by a valid program. You didn't show what foo does, but if you change the value of a const variable the program's behaviour is undefined, so you can't rely on any particular behaviour.
gcc-4.5-20091210 is now available
Snapshot gcc-4.5-20091210 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.5-20091210/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.5 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/trunk revision 155144 You'll find: gcc-4.5-20091210.tar.bz2 Complete GCC (includes all of below) gcc-core-4.5-20091210.tar.bz2 C front end and core compiler gcc-ada-4.5-20091210.tar.bz2 Ada front end and runtime gcc-fortran-4.5-20091210.tar.bz2 Fortran front end and runtime gcc-g++-4.5-20091210.tar.bz2 C++ front end and runtime gcc-java-4.5-20091210.tar.bz2 Java front end and runtime gcc-objc-4.5-20091210.tar.bz2 Objective-C front end and runtime gcc-testsuite-4.5-20091210.tar.bz2The GCC testsuite Diffs from 4.5-20091203 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.5 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.
generate RTL sequence
Hi, I have a problem about RTL sequence. If I wanna generate the RTL in sequence, and don't let gcc to schedule them. Like the following(all the variable is rtx): emit_insn(reg0, operands[0]); emit_insn(reg1, reg0); emit_insn(operands[0], reg1); But gcc will will reorder the three rtl in optimization. I just wanna the those rtl in one block as a unit, don't let the gcc disrupt the sequence. How can I do it? By the way, what do the function start_sequence and end_sequence do. I type to call those functions in my prologue and epilogue in my porting back end. but cc1 will crash. I need to bind some kind of rtl, and make them stay the sequence as generated. Thanks for your guys. daniel.tian
Re: generate RTL sequence
daniel tian writes: > I have a problem about RTL sequence. > If I wanna generate the RTL in sequence, and don't let gcc to schedule > them. > Like the following(all the variable is rtx): > > emit_insn(reg0, operands[0]); > emit_insn(reg1, reg0); > emit_insn(operands[0], reg1); > > But gcc will will reorder the three rtl in optimization. > I just wanna the those rtl in one block as a unit, don't let the > gcc disrupt the sequence. > How can I do it? Write a single define_insn which emits the instructions you want to treat as a unit. Ian
Re: generate RTL sequence
2009/12/11 Ian Lance Taylor : > daniel tian writes: > >> I have a problem about RTL sequence. >> If I wanna generate the RTL in sequence, and don't let gcc to schedule >> them. >> Like the following(all the variable is rtx): >> >> emit_insn(reg0, operands[0]); >> emit_insn(reg1, reg0); >> emit_insn(operands[0], reg1); >> >> But gcc will will reorder the three rtl in optimization. >> I just wanna the those rtl in one block as a unit, don't let the >> gcc disrupt the sequence. >> How can I do it? > > Write a single define_insn which emits the instructions you want to > treat as a unit. > Does there any solution in RTL level? Because I already solve the problem in ASM output level, exactly the same solution as you suggest in this email. I may need do some optimization later. So RTL level will be great! Thanks for your advice. Best Regards. daniel.tian
Re: generate RTL sequence
I'm tring this function, but it have some problems. It seems not link the new insn in the double-list. void merge(rtx insn1,rtx insn2) { rtx par, pre,sur, insn; par = gen_rtx_PARALLEL (SFmode, rtvec_alloc (2)); XVECEXP (par, 0, 0) = PATTERN(insn1); XVECEXP (par, 0, 1) = PATTERN(insn2); insn = make_insn_raw (par); sur = NEXT_INSN(insn1); PREV_INSN(insn) = insn1; NEXT_INSN(insn) = sur; delete_insn(insn1); delete_insn(insn2); } 2009/12/11 daniel tian : > 2009/12/11 Ian Lance Taylor : >> daniel tian writes: >> >>> I have a problem about RTL sequence. >>> If I wanna generate the RTL in sequence, and don't let gcc to schedule >>> them. >>> Like the following(all the variable is rtx): >>> >>> emit_insn(reg0, operands[0]); >>> emit_insn(reg1, reg0); >>> emit_insn(operands[0], reg1); >>> >>> But gcc will will reorder the three rtl in optimization. >>> I just wanna the those rtl in one block as a unit, don't let the >>> gcc disrupt the sequence. >>> How can I do it? >> >> Write a single define_insn which emits the instructions you want to >> treat as a unit. >> > > Does there any solution in RTL level? > Because I already solve the problem in ASM output level, exactly the > same solution as you suggest in this email. > I may need do some optimization later. So RTL level will be great! > > Thanks for your advice. > Best Regards. > > daniel.tian > -- Jianzhang Peng
Re: generate RTL sequence
daniel tian writes: > 2009/12/11 Ian Lance Taylor : >> daniel tian writes: >> >>> I have a problem about RTL sequence. >>> If I wanna generate the RTL in sequence, and don't let gcc to schedule >>> them. >>> Like the following(all the variable is rtx): >>> >>> emit_insn(reg0, operands[0]); >>> emit_insn(reg1, reg0); >>> emit_insn(operands[0], reg1); >>> >>> But gcc will will reorder the three rtl in optimization. >>> I just wanna the those rtl in one block as a unit, don't let the >>> gcc disrupt the sequence. >>> How can I do it? >> >> Write a single define_insn which emits the instructions you want to >> treat as a unit. >> > > Does there any solution in RTL level? > Because I already solve the problem in ASM output level, exactly the > same solution as you suggest in this email. > I may need do some optimization later. So RTL level will be great! As far as I know there is no way to do this at the RTL level. I don't know why there would be a way, as it does not strike me as a useful feature to have. If the instructions must stay together at the assembly level, use a single define_insn. If you use multiple define_insns, then it's OK for the compiler to move them around. Ian
Re: generate RTL sequence
I think you should do the operation with the functions in emit-rtl.c. Like the functions:add_insn_after, add_insn_before, df_insn_delete. You could try those things. 2009/12/11 Jianzhang Peng : > I'm tring this function, but it have some problems. It seems not link > the new insn in the double-list. > > void merge(rtx insn1,rtx insn2) > { > rtx par, pre,sur, insn; > > par = gen_rtx_PARALLEL (SFmode, rtvec_alloc (2)); > > XVECEXP (par, 0, 0) = PATTERN(insn1); > XVECEXP (par, 0, 1) = PATTERN(insn2); > > insn = make_insn_raw (par); > > sur = NEXT_INSN(insn1); > > PREV_INSN(insn) = insn1; > NEXT_INSN(insn) = sur; > delete_insn(insn1); > > delete_insn(insn2); > } > > > 2009/12/11 daniel tian : >> 2009/12/11 Ian Lance Taylor : >>> daniel tian writes: >>> I have a problem about RTL sequence. If I wanna generate the RTL in sequence, and don't let gcc to schedule them. Like the following(all the variable is rtx): emit_insn(reg0, operands[0]); emit_insn(reg1, reg0); emit_insn(operands[0], reg1); But gcc will will reorder the three rtl in optimization. I just wanna the those rtl in one block as a unit, don't let the gcc disrupt the sequence. How can I do it? >>> >>> Write a single define_insn which emits the instructions you want to >>> treat as a unit. >>> >> >> Does there any solution in RTL level? >> Because I already solve the problem in ASM output level, exactly the >> same solution as you suggest in this email. >> I may need do some optimization later. So RTL level will be great! >> >> Thanks for your advice. >> Best Regards. >> >> daniel.tian >> > > > > -- > Jianzhang Peng >
Re: generate RTL sequence
>> Does there any solution in RTL level? >> Because I already solve the problem in ASM output level, exactly the >> same solution as you suggest in this email. >> I may need do some optimization later. So RTL level will be great! > > As far as I know there is no way to do this at the RTL level. I don't > know why there would be a way, as it does not strike me as a useful > feature to have. If the instructions must stay together at the > assembly level, use a single define_insn. If you use multiple > define_insns, then it's OK for the compiler to move them around. > > Ian > Ok. Thanks.
Re: generate RTL sequence
Ian: By the way, I don't underand the start_sequence and end_sequence. What does those function mean. I checked the source code in emit-rtl.c. I still can't figure out what they do. There is a structure sequence_stack, I don't what it does. Thanks.
identifying indirect references in a loop
Hi, Im trying to identify all indirect references in a loop so that, after this analysis, I have a list of tree_nodes of pointer_type that are dereferenced in a loop along with their step size, if any. E.g. while(i++ < n) { *(p+i); } I want to get the pointer_type_node for 'p' and identify the step size as '1', since 'i' has a step size of 1. I am able to identify 'INDIRECT_REF' nodes in the loop. But since these are generally the expression_temporaries, I will not get the tree_node for 'p'. But I believe INDIRECT_REF is an expression who's arg0 is an SSA_NAME node from which I will be able to use the SSA_NAME_DEF_STMT to ultimately reach the tree_node for 'p'. But I dont know how to get the SSA_NAME node from the given INDIRECT_REF. Could someone please point out how to do this. Also, I find it very difficult to know how the tree_nodes and types are contained one within the other. Is there a general technique by which I can know when a tree node will be nested within another and how to retrieve them ? Thanks, Aravinda
Re: generate RTL sequence
daniel tian writes: > By the way, I don't underand the start_sequence and end_sequence. > What does those function mean. > I checked the source code in emit-rtl.c. > I still can't figure out what they do. > There is a structure sequence_stack, I don't what it does. start_sequence and end_sequence are used to group insns into a specific location when you are generating insns. I quote the comment in emit-rtl.c: For example, consider the instruction named SPOT and the fact that we would like to emit some instructions before SPOT. We might do it like this: start_sequence (); ... emit the new instructions ... insns_head = get_insns (); end_sequence (); emit_insn_before (insns_head, SPOT); Ian
Re: generate RTL sequence
> > There is a structure sequence_stack, I don't what it does. > > start_sequence and end_sequence are used to group insns into a > specific location when you are generating insns. I quote the comment > in emit-rtl.c: And sequence_stack exists so you can arbitrarily nest insn sequences.
Re: generate RTL sequence
Quoting daniel tian : Hi, I have a problem about RTL sequence. If I wanna generate the RTL in sequence, and don't let gcc to schedule them. Like the following(all the variable is rtx): emit_insn(reg0, operands[0]); emit_insn(reg1, reg0); emit_insn(operands[0], reg1); But gcc will will reorder the three rtl in optimization. I just wanna the those rtl in one block as a unit, don't let the gcc disrupt the sequence. How can I do it? If you want to merely fix the order of the instructions relative to each other, you can do this by adding an explicit dependency in the rtl. I.e. you can invent some hard register (or model an actual one if there is one that is the reason for your ordering requirements), set it in the first instruction, use and set it in the second insn, and use it in the third insn. You can use UNSPEC and dependencies on other inputs to avoid some undesired compiler transformation like from combine. If you need more rigid scheduling, you can use CC0.