Re: C6X port 4/11: Backtracking scheduler
Bernd Schmidt ber...@codesourcery.com writes: Because of this problem, I've chosen a different model for this patch. Before calling the final sched_ebb pass, the port must split jump insns (or anything that should have delay slots) into two separate insns, a real insn and a shadow. As an example, (jump_insn (set (pc) (label_ref 24))) becomes (insn (unspec [(label_ref 24)] UNSPEC_REAL_JUMP) (jump_insn (set (pc) (unspec [(pc)] UNSPEC_JUMP_SHADOW) where the first insn emits the branch into the assembly file, while the second one produces no output (or, in the case of C6X, a helpful comment that documents that the side effect takes place). Neat! It'll be interesting to see how easy it would be to convert recog and in-tree delayed-branch targets to use this form instead of SEQUENCEs. It'd certainly be a big step towards keeping the CFG around during and after md-reorg. I might look at that (getting rid of SEQUENCEs in the insn stream) if I have time. But... ...your message and examples all seem to emphasis unconditional jumps. How good a job does the scheduler do for conditional jumps? E.g. do we steal from the branch target in cases where that's useful? Or, more generally, do you think we're at the stage where all targets could move away from reorg.c to this approach, or do you think more work is needed on the scheduler first? I realise the scheduler won't need to do everything that reorg.c does. Running reorg.c on already-scheduled code (and without pipeline information, and without a proper CFG or DF tracking) has so many oft-discussed downsides that a properly integrated approach could easily be better without copying all the tricks that reorg.c can do. I was just wondering where you think the boundary is. Richard
Re: [PATCH] Fix tree parts of PR18041
On Tue, 10 May 2011, Steven Bosscher wrote: On Tue, May 10, 2011 at 1:25 PM, Richard Guenther rguent...@suse.de wrote: The generated code is the same though, and still contains too many masking operations. The lowering you're planning -- does that mean lowering all bitfield ops for all targets? You've noticed expand makes some very conservative assumptions (has to, without context), perhaps after lowering your next project should be rewriting the bit-ops expanders ;-) That was the original idea - though I guess for now I will leave the possibility to have some of the unlowered. After all, such radical changes always prove difficult ;) Especially as I want to avoid code generation regressions and don't feel like replicating what expand does 1:1 on the tree level (though maybe I should do exactly that ... hmm). And yes, one idea was to get rid of the complication of doing this during RTL expansion (including handling unaligned loads/stores on strict align targets). Richard.
Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
On Tue, May 10, 2011 at 9:01 PM, Diego Novillo dnovi...@google.com wrote: On Fri, Mar 11, 2011 at 10:19, Richard Guenther richard.guent...@gmail.com wrote: On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd froy...@codesourcery.com wrote: Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR. Nothing to see here. I wonder if there isn't a better way to do this ... like always requiring operand 2 of SWITCH_EXPRs. Could be, but I think it makes sense to do it in incremental steps. This change seems like a step forward in its own sense. I'm fine with it. Yeah, ok. Richard. Diego.
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote: 2011/5/10 Kai Tietz ktiet...@googlemail.com: 2011/5/10 Richard Guenther richard.guent...@gmail.com: On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote: On 05/10/2011 05:23 PM, Richard Guenther wrote: I suppose you have testcases for all the cases you looked at, please add some that cover these corner cases. Also, there is quite some tree-vrp.c dead code with these changes. Removing the TRUTH_*_CODE handling in VRP will help finding more places where the middle-end is building boolean operations. There should be testcases covering these parts of VRP. Btw, you can split the patch into two pieces - first, make TRUTH_* expressions correctly typed (take boolean typed operands and procude a boolean typed result) and verify that in verify_gimple_assign_binary. A second patch than can do the s/TRUTH_/BIT_/ substitution during gimplification. That way the first (and more difficult) part doesn't get too big with unrelated changes. Richard. Paolo Well, I think I found one big issue here about booified expression of condition. The gimple_boolify needs to handle COND_EXPR in more detail. As if a conditional expression has to be boolified, it means its condition and its other operands need to be boolified, too. And this is for sure one cause, why I see for ANDIF/ORIF and the truth AND|OR|XOR none boolean types. I will continue on that. To split this seems to make sense, as I have to touch much more areas for the TRUTH to BIT conversion. Regards, Kai So I use this thread for first part of the series of patches. This one improves boolean type-logic during gimplification. To gimple_boolify the handling for COND_EXPR are added, and in general it is tried to do boolean operation just on boolean type. As sadly fold-const (and here in special fold_truth_not_expr (), which doesn't provide by default boolean type and uses instead operand-type, which is IMHO a major flaw here. But well, there are some comments indicating that this behavior is required due some other quirks. But this is for sure something to be cleaned up) produces truth operations with wrong type, which are in calculations not necessarily identifyable as truth ops anymore, this patch makes sure that for truth AND|OR|XOR original type remains. 2011-05-10 Kai Tietz * gimplify.c (gimple_boolify): Handle COND_EXPR and make sure that even if type is BOOLEAN for TRUTH-opcodes the operands getting boolified. (gimplify_expr): Boolify operand condition for COND_EXPR. Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. Ok for apply? Posting patches inline makes it easier to put in review comments, so please consider doing that. Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200 +++ gcc/gcc/gimplify.c 2011-05-10 21:14:49.106340400 +0200 @@ -2824,11 +2824,20 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) -return expr; - switch (TREE_CODE (expr)) { +case COND_EXPR: + /* If we have a conditional expression, which shall be + boolean, take care we boolify also their left and right arm. */ + if (TREE_OPERAND (expr, 2) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2 +TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2)); + if (TREE_OPERAND (expr, 1) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1 +TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); + TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; + return fold_convert_loc (loc, boolean_type_node, expr); + That looks like premature optimization. Why isn't it enough to fold-convert the COND_EXPR itself? Thus, I don't see why the existing gimple_boolify isn't enough. case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: @@ -2851,6 +2860,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, gimple_seq break; case COND_EXPR: + TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0)); ret = gimplify_cond_expr (expr_p, pre_p, fallback); This boolification should be done by gimplify_cond_expr as I said in the previous review. It does already handle this perfectly fine. /* C99 code may assign to an array in a
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
Hi, By investigating the conditional expression handling I found some causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are appearing withing conditional folding during gimplification. The reason for this can be that the truth expression is simply used as result of an assignment or return statement, which then leads to the issue that expression has lhs type. By this reason it is still necessary to have in TRUTH operations type-cast after boolifying it for later operation, if type isn't of kind boolean. Therefore it is necessary for conditional to check if their arms might be TRUTH results and therefore doing boolification of the arms, too. 2011-05-11 Kai Tietz * gimplify.c (gimple_boolify): Handle COND_EXPR and make sure that even if type is BOOLEAN for TRUTH-opcodes the operands getting boolified. (gimple_has_cond_boolean_arms): Helper function to detect if condition is a TRUTH operation in arms. (gimple_is_truth_op): Checks if operand is of BOOLEAN kind. (gimplify_expr): Boolify operand condition for COND_EXPR and try to see if condition might be an TRUTH operation. Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. Tested on x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply? Regards, Kai Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200 +++ gcc/gcc/gimplify.c 2011-05-11 10:20:30.413964700 +0200 @@ -102,6 +102,7 @@ typedef struct gimple_temp_hash_elt /* Forward declaration. */ static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool); +static bool gimple_has_cond_boolean_arms (tree); /* Mark X addressable. Unlike the langhook we expect X to be in gimple form and we don't do any syntax checking. */ @@ -2824,11 +2825,26 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) -return expr; - switch (TREE_CODE (expr)) { +case COND_EXPR: + /* If we have a conditional expression, which shall be + boolean, take care we boolify also their left and right arm. */ + if (TREE_OPERAND (expr, 2) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2 +TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2)); + if (TREE_OPERAND (expr, 1) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1 +TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); + TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; + if (!VOID_TYPE_P (TREE_TYPE (expr))) +{ + /* These expressions always produce boolean results. */ + TREE_TYPE (expr) = boolean_type_node; + } + else +return fold_convert_loc (loc, boolean_type_node, expr); + case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: @@ -2851,6 +2867,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -2909,6 +2927,66 @@ generic_expr_could_trap_p (tree expr) return false; } +/* This function checks if OP is of TRUTH kind expression. It special-case + COND_EXPR, as here we need to look on results, too. See function + gimple_has_cond_boolean_arms () for more details. + If OP is of possible kind TRUTH expression, TRUE is returned, + otherwise FALSE is returned. + This functions assumes that all TRUTH operations, COND_EXPR with + boolean arms, INTEGER_CST with value of one or zero, and any + comparision has boolean result. */ + +static bool +gimple_is_truth_op (tree op) +{ + if (VOID_TYPE_P (TREE_TYPE (op))) +return false; + if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE) +return true; + switch (TREE_CODE (op)) +{ +case TRUTH_AND_EXPR: +case TRUTH_OR_EXPR: +case TRUTH_XOR_EXPR: +case TRUTH_ANDIF_EXPR: +case TRUTH_ORIF_EXPR: +case TRUTH_NOT_EXPR: + return true; +case COND_EXPR: + return gimple_has_cond_boolean_arms (op); +case INTEGER_CST: + if (integer_zerop (op) || integer_onep (op)) + return true; + return false; +default: + if (TREE_CODE_CLASS (TREE_CODE (op)) == tcc_comparison) + return true; + break; +} + return false; +} + +/* This function checks if all arms of the condition expression EXPR + are of kind TRUTH. If so, it returns TRUE, otherwise FALSE. */ + +static bool +gimple_has_cond_boolean_arms (tree expr) +{ + tree type = TREE_TYPE (expr); + tree arm1 = TREE_OPERAND (expr, 0); + tree arm2 =
Re: [PATCH] split tree_type, a.k.a. tuplifying types
On Tue, May 10, 2011 at 7:50 PM, Nathan Froyd froy...@codesourcery.com wrote: On Tue, May 10, 2011 at 02:28:06PM -0300, Diego Novillo wrote: On Tue, May 10, 2011 at 13:15, Nathan Froyd froy...@codesourcery.com wrote: Other types can of course be shrunk, but the memory savings from doing so will be negligible Have you done any measurements on the potential savings? Only back-of-the-envelope. I will try to get some numbers after we start saving memory. :) +static void +lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib, + struct data_in *data_in, tree expr) +{ + TYPE_SIZE (expr) = lto_input_tree (ib, data_in); + TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in); + TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in); + TYPE_NAME (expr) = lto_input_tree (ib, data_in); + /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO. */ Add some wording as to why not? This was copied from existing comments, but I do not remember why we were doing this. Not too critical, anyway. I'm not entirely sure; I'm not intimately familiar with how LTO streaming works. lto.c's lto_ft_type and lto_ft_common purport to recreate TYPE_{POINTER,REFERENCE}_TO, but I don't immediately see how that's supposed to work. I can imagine that we ought to be able to recreate those fields after reading everything in, and that's why don't stream them; I just don't know where that's done. Yes, we're re-creating them to avoid streaming all pointer types that might be unused before streaming. One nit: +struct GTY(()) tree_type_non_common { + struct tree_type_with_lang_specific common; shouldn't that field be named w_lang_specific or something like that, instead of re-using common? Richard. -Nathan
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
On Wed, May 11, 2011 at 11:00 AM, Kai Tietz ktiet...@googlemail.com wrote: Hi, By investigating the conditional expression handling I found some causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are appearing withing conditional folding during gimplification. The reason for this can be that the truth expression is simply used as result of an assignment or return statement, which then leads to the issue that expression has lhs type. By this reason it is still necessary to have in TRUTH operations type-cast after boolifying it for later operation, if type isn't of kind boolean. Therefore it is necessary for conditional to check if their arms might be TRUTH results and therefore doing boolification of the arms, too. You are not making much sense - gimple_boolify already boolifies both arms. It assumes that if the expr is bool already the arms are as well - I'm not sure that always holds, so defering that check as your patch did probably makes sense. Richard. 2011-05-11 Kai Tietz * gimplify.c (gimple_boolify): Handle COND_EXPR and make sure that even if type is BOOLEAN for TRUTH-opcodes the operands getting boolified. (gimple_has_cond_boolean_arms): Helper function to detect if condition is a TRUTH operation in arms. (gimple_is_truth_op): Checks if operand is of BOOLEAN kind. (gimplify_expr): Boolify operand condition for COND_EXPR and try to see if condition might be an TRUTH operation. Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. Tested on x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply? Regards, Kai
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
2011/5/11 Richard Guenther richard.guent...@gmail.com: On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote: 2011/5/10 Kai Tietz ktiet...@googlemail.com: 2011/5/10 Richard Guenther richard.guent...@gmail.com: On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote: On 05/10/2011 05:23 PM, Richard Guenther wrote: I suppose you have testcases for all the cases you looked at, please add some that cover these corner cases. Also, there is quite some tree-vrp.c dead code with these changes. Removing the TRUTH_*_CODE handling in VRP will help finding more places where the middle-end is building boolean operations. There should be testcases covering these parts of VRP. Btw, you can split the patch into two pieces - first, make TRUTH_* expressions correctly typed (take boolean typed operands and procude a boolean typed result) and verify that in verify_gimple_assign_binary. A second patch than can do the s/TRUTH_/BIT_/ substitution during gimplification. That way the first (and more difficult) part doesn't get too big with unrelated changes. Richard. Paolo Well, I think I found one big issue here about booified expression of condition. The gimple_boolify needs to handle COND_EXPR in more detail. As if a conditional expression has to be boolified, it means its condition and its other operands need to be boolified, too. And this is for sure one cause, why I see for ANDIF/ORIF and the truth AND|OR|XOR none boolean types. I will continue on that. To split this seems to make sense, as I have to touch much more areas for the TRUTH to BIT conversion. Regards, Kai So I use this thread for first part of the series of patches. This one improves boolean type-logic during gimplification. To gimple_boolify the handling for COND_EXPR are added, and in general it is tried to do boolean operation just on boolean type. As sadly fold-const (and here in special fold_truth_not_expr (), which doesn't provide by default boolean type and uses instead operand-type, which is IMHO a major flaw here. But well, there are some comments indicating that this behavior is required due some other quirks. But this is for sure something to be cleaned up) produces truth operations with wrong type, which are in calculations not necessarily identifyable as truth ops anymore, this patch makes sure that for truth AND|OR|XOR original type remains. 2011-05-10 Kai Tietz * gimplify.c (gimple_boolify): Handle COND_EXPR and make sure that even if type is BOOLEAN for TRUTH-opcodes the operands getting boolified. (gimplify_expr): Boolify operand condition for COND_EXPR. Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. Ok for apply? Posting patches inline makes it easier to put in review comments, so please consider doing that. Ok, I think about this. Not sure how well, google-mail handles this. I'll try next time. Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200 +++ gcc/gcc/gimplify.c 2011-05-10 21:14:49.106340400 +0200 @@ -2824,11 +2824,20 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) - return expr; - switch (TREE_CODE (expr)) { + case COND_EXPR: + /* If we have a conditional expression, which shall be + boolean, take care we boolify also their left and right arm. */ + if (TREE_OPERAND (expr, 2) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2 + TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2)); + if (TREE_OPERAND (expr, 1) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1 + TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); + TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; + return fold_convert_loc (loc, boolean_type_node, expr); + That looks like premature optimization. Why isn't it enough to fold-convert the COND_EXPR itself? Thus, I don't see why the existing gimple_boolify isn't enough. See description of recent update patch. It isn't enough. case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: @@ -2851,6 +2860,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p, gimple_seq break; case COND_EXPR: + TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0)); ret
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
2011/5/11 Richard Guenther richard.guent...@gmail.com: On Wed, May 11, 2011 at 11:00 AM, Kai Tietz ktiet...@googlemail.com wrote: Hi, By investigating the conditional expression handling I found some causes, why TRUTH operations AND, ANDIF, OR, XOR, and ORIF are appearing withing conditional folding during gimplification. The reason for this can be that the truth expression is simply used as result of an assignment or return statement, which then leads to the issue that expression has lhs type. By this reason it is still necessary to have in TRUTH operations type-cast after boolifying it for later operation, if type isn't of kind boolean. Therefore it is necessary for conditional to check if their arms might be TRUTH results and therefore doing boolification of the arms, too. You are not making much sense - gimple_boolify already boolifies both arms. It assumes that if the expr is bool already the arms are as well - I'm not sure that always holds, so defering that check as your patch did probably makes sense. It makes absolutely sense. Simply try the following example: int foo (int a, int b, int c) { int e = (a b); return e ? (c !a) : (c a b); } You will see that by this you have TRUTH AND operations with none boolean type, due the fact that for a conditional only the cond part was converted. This patch checks that inner arms getting boolified, if result of condition on both arms is a TRUTH result. Regards, Kai
Re: [PATCH, SMS 1/3] Support closing_branch_deps (second try)
Hello, please clarify that, e.g., instruction scheduled on cycle AMOUNT will move to cycle zero. OK, done. shouldn't normalized_time be used here instead of SCHED_TIME (u)? SCHED_TIME (u) is been set to normalized_time just before using it. Thanks, Revital
Re: [PATCH, SMS 1/3] Support closing_branch_deps (second try)
Hello, please clarify that, e.g., instruction scheduled on cycle AMOUNT will move to cycle zero. OK, done. shouldn't normalized_time be used here instead of SCHED_TIME (u)? SCHED_TIME (u) is been set to normalized_time just before using it. Thanks, Revital
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
For more detail what happens and why this conditional handling is necessary: The sample code is: int foo (int a, int b) { return (a ? b != 3 : 0); } leads for variant without condition boolifying of arms to: ;; Function foo (foo) foo (int a, int b) { int D.1991; int D.1990; int D.1989; bb 2: D.1990_2 = a_1(D) != 0; D.1991_4 = b_3(D) != 3; D.1989_5 = D.1991_4 D.1990_2; return D.1989_5; } with this code we see ;; Function foo (foo) foo (int a, int b) { _Bool D.1992; _Bool D.1991; _Bool D.1990; int D.1989; bb 2: D.1990_2 = a_1(D) != 0; D.1991_4 = b_3(D) != 3; D.1992_5 = D.1991_4 D.1990_2; D.1989_6 = (int) D.1992_5; return D.1989_6; } So you see that by this, the SSA variable having _Bool type, as to be wished, and not being handled as int. Regards, Kai
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR expressions on gimplification to their binary form. What is it for? This will redirect the compilation stream from proven paths to others so there must be a good reason to do it. What's the effect on the code? -- Eric Botcazou
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
2011/5/11 Richard Guenther richard.guent...@gmail.com: On Tue, May 10, 2011 at 9:26 PM, Kai Tietz ktiet...@googlemail.com wrote: 2011/5/10 Kai Tietz ktiet...@googlemail.com: 2011/5/10 Richard Guenther richard.guent...@gmail.com: On Tue, May 10, 2011 at 5:30 PM, Paolo Bonzini bonz...@gnu.org wrote: On 05/10/2011 05:23 PM, Richard Guenther wrote: I suppose you have testcases for all the cases you looked at, please add some that cover these corner cases. Also, there is quite some tree-vrp.c dead code with these changes. Removing the TRUTH_*_CODE handling in VRP will help finding more places where the middle-end is building boolean operations. There should be testcases covering these parts of VRP. Btw, you can split the patch into two pieces - first, make TRUTH_* expressions correctly typed (take boolean typed operands and procude a boolean typed result) and verify that in verify_gimple_assign_binary. A second patch than can do the s/TRUTH_/BIT_/ substitution during gimplification. That way the first (and more difficult) part doesn't get too big with unrelated changes. Richard. Paolo Well, I think I found one big issue here about booified expression of condition. The gimple_boolify needs to handle COND_EXPR in more detail. As if a conditional expression has to be boolified, it means its condition and its other operands need to be boolified, too. And this is for sure one cause, why I see for ANDIF/ORIF and the truth AND|OR|XOR none boolean types. I will continue on that. To split this seems to make sense, as I have to touch much more areas for the TRUTH to BIT conversion. Regards, Kai So I use this thread for first part of the series of patches. This one improves boolean type-logic during gimplification. To gimple_boolify the handling for COND_EXPR are added, and in general it is tried to do boolean operation just on boolean type. As sadly fold-const (and here in special fold_truth_not_expr (), which doesn't provide by default boolean type and uses instead operand-type, which is IMHO a major flaw here. But well, there are some comments indicating that this behavior is required due some other quirks. But this is for sure something to be cleaned up) produces truth operations with wrong type, which are in calculations not necessarily identifyable as truth ops anymore, this patch makes sure that for truth AND|OR|XOR original type remains. 2011-05-10 Kai Tietz * gimplify.c (gimple_boolify): Handle COND_EXPR and make sure that even if type is BOOLEAN for TRUTH-opcodes the operands getting boolified. (gimplify_expr): Boolify operand condition for COND_EXPR. Boolify truth opcodes AND, ANDIF, OR, ORIF, and XOR. Additional take care that we keep expression's type. Ok for apply? Posting patches inline makes it easier to put in review comments, so please consider doing that. Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-10 18:31:40.0 +0200 +++ gcc/gcc/gimplify.c 2011-05-10 21:14:49.106340400 +0200 @@ -2824,11 +2824,20 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) - return expr; - switch (TREE_CODE (expr)) { + case COND_EXPR: + /* If we have a conditional expression, which shall be + boolean, take care we boolify also their left and right arm. */ + if (TREE_OPERAND (expr, 2) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2 + TREE_OPERAND (expr, 2) = gimple_boolify (TREE_OPERAND (expr, 2)); + if (TREE_OPERAND (expr, 1) != NULL_TREE !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1 + TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); + TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; + return fold_convert_loc (loc, boolean_type_node, expr); + That looks like premature optimization. Why isn't it enough to fold-convert the COND_EXPR itself? Thus, I don't see why the existing gimple_boolify isn't enough. Old code simple casted condition expression to boolean type, but didn't converted inner arms. By this the arms are remaining by their old type, which later then gets converted. This is for a condition of kind COND_EXPR pretty bad, as exactly this leads us to useless type conversion in inner arms. case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: @@ -2851,6 +2860,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -6714,6 +6725,7 @@ gimplify_expr (tree *expr_p,
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
2011/5/11 Eric Botcazou ebotca...@adacore.com: this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR expressions on gimplification to their binary form. What is it for? This will redirect the compilation stream from proven paths to others so there must be a good reason to do it. What's the effect on the code? -- Eric Botcazou Well, it would have some effects. First we don't need to handle TRUTH and BINARY variants of AND, OR, XOR any longer special. Second cause is that on BINARY trees the reassociation pass can operate, which leads to better optimized boolean logic. Regards, Kai
Re: C6X port 4/11: Backtracking scheduler
On 05/11/2011 10:04 AM, Richard Sandiford wrote: Neat! It'll be interesting to see how easy it would be to convert recog and in-tree delayed-branch targets to use this form instead of SEQUENCEs. It'd certainly be a big step towards keeping the CFG around during and after md-reorg. I might look at that (getting rid of SEQUENCEs in the insn stream) if I have time. But... ...your message and examples all seem to emphasis unconditional jumps. How good a job does the scheduler do for conditional jumps? E.g. do we steal from the branch target in cases where that's useful? It uses sched-ebb, which means it sort of does a reasonable job, but it's weaker than reorg.c in some respects. I'd like to turn sched-ebb into sched-dag and add better support for predicating insns when moving them across a branch (there's some code for it in c6x.c), but that'll need more work. Bernd
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
On Wed, May 11, 2011 at 11:35 AM, Kai Tietz ktiet...@googlemail.com wrote: For more detail what happens and why this conditional handling is necessary: The sample code is: int foo (int a, int b) { return (a ? b != 3 : 0); } leads for variant without condition boolifying of arms to: ;; Function foo (foo) foo (int a, int b) { int D.1991; int D.1990; int D.1989; bb 2: D.1990_2 = a_1(D) != 0; D.1991_4 = b_3(D) != 3; D.1989_5 = D.1991_4 D.1990_2; return D.1989_5; } There is no TRUTH_* expr. The patch should fix TRUTH_* expr types, not everything else (I know tcc_comparison exprs have the same issue). If you want to fix tcc_comparison results as well do so in gimplify_expr (and adjust the type verifier similar to the TRUTH_ case). Richard.
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
On Wed, May 11, 2011 at 12:03 PM, Kai Tietz ktiet...@googlemail.com wrote: 2011/5/11 Eric Botcazou ebotca...@adacore.com: this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR expressions on gimplification to their binary form. What is it for? This will redirect the compilation stream from proven paths to others so there must be a good reason to do it. What's the effect on the code? -- Eric Botcazou Well, it would have some effects. First we don't need to handle TRUTH and BINARY variants of AND, OR, XOR any longer special. Second cause is that on BINARY trees the reassociation pass can operate, which leads to better optimized boolean logic. The most important thing is to get predicate types sane - that affects tcc_comparison codes and the TRUTH_* codes. After that, the TRUTH_* codes are redundant with the BIT_* ones which already are always validly typed. As fold already converts some TRUTH_* to BIT_* variants we usually have a mix of both which is not handled very well by tree optimizers. Richard. Regards, Kai
Re: The TI C6X port
On 05/10/2011 06:51 PM, Joseph S. Myers wrote: On Tue, 10 May 2011, Bernd Schmidt wrote: Binutils and uClibc already contain C6X patches; unfortunately there isn't an open-source sim. The newlib support is also upstream. I've also run c6x tests, which look fairly clean on the whole. Does this testing cover all six architecture variants (c62x, c64x, c64x+, c67x, c67x+, c674x), for both big and little endian? No, not recently. In general, most effort is on c64x+ and c674x - as shown by the multilib selection and by the --with-arch selection as you noticed. Linux certainly won't run on anything else, although I suppose I could give c6x-elf another try. Bernd
Re: The TI C6X port
On Wed, 11 May 2011, Bernd Schmidt wrote: On 05/10/2011 06:51 PM, Joseph S. Myers wrote: On Tue, 10 May 2011, Bernd Schmidt wrote: Binutils and uClibc already contain C6X patches; unfortunately there isn't an open-source sim. The newlib support is also upstream. I've also run c6x tests, which look fairly clean on the whole. Does this testing cover all six architecture variants (c62x, c64x, c64x+, c67x, c67x+, c674x), for both big and little endian? No, not recently. In general, most effort is on c64x+ and c674x - as shown by the multilib selection and by the --with-arch selection as you noticed. Linux certainly won't run on anything else, although I suppose I could give c6x-elf another try. I'd say that since the port has options for the older variants, it should at least be tested that they appear to work at the point the port goes in (will build libgcc / pass the testsuite for c6x-elf without ICEs or wrong code being generated) - though it will of course be for anyone in the community who wishes to use it on those variants to do any performance tuning for them, or add any missing features for the older variants, and it would be reasonable to call sorry () in any cases where an option, language feature etc. isn't currently supported for them. -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] Fix tree parts of PR18041
On Tue, 10 May 2011, Richard Guenther wrote: And I now get FAIL: gcc.target/i386/pr45903.c scan-assembler-not shr[qdl] because the optimization Jakub put in place relies on operations carried out in smaller modes. That's of course a conflict of interest. I'm going to sit on this patch for a little longer. The following seems to work for all cases I am interested in. It avoids undoing narrowing optimizations if they were not to bitfield types. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-11 Richard Guenther rguent...@suse.de PR tree-optimization/18041 * tree-ssa-forwprop.c (simplify_bitwise_and): Rename to ... (simplify_bitwise_binary): ... this. Handle operand conversions by applying them to the result instead. (tree_ssa_forward_propagate_single_use_vars): Adjust. CSE tree code. * gcc.dg/tree-ssa/forwprop-13.c: New testcase. Index: gcc/tree-ssa-forwprop.c === *** gcc/tree-ssa-forwprop.c.orig2011-05-10 16:18:16.0 +0200 --- gcc/tree-ssa-forwprop.c 2011-05-10 17:50:43.0 +0200 *** simplify_builtin_call (gimple_stmt_itera *** 1612,1655 return false; } ! /* Run bitwise and assignments throug the folder. If the first argument is an !ssa name that is itself a result of a typecast of an ADDR_EXPR to an !integer, feed the ADDR_EXPR to the folder rather than the ssa name. ! */ ! static void ! simplify_bitwise_and (gimple_stmt_iterator *gsi, gimple stmt) { ! tree res; tree arg1 = gimple_assign_rhs1 (stmt); tree arg2 = gimple_assign_rhs2 (stmt); ! if (TREE_CODE (arg2) != INTEGER_CST) ! return; ! ! if (TREE_CODE (arg1) == SSA_NAME !SSA_NAME_IS_DEFAULT_DEF (arg1)) { gimple def = SSA_NAME_DEF_STMT (arg1); ! if (gimple_assign_cast_p (def) ! INTEGRAL_TYPE_P (gimple_expr_type (def))) ! { ! tree op = gimple_assign_rhs1 (def); ! if (TREE_CODE (op) == ADDR_EXPR) ! arg1 = op; } } ! res = fold_binary_loc (gimple_location (stmt), !BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)), !arg1, arg2); ! if (res is_gimple_min_invariant (res)) { ! gimple_assign_set_rhs_from_tree (gsi, res); ! update_stmt (stmt); } ! return; } --- 1612,1701 return false; } ! /* Simplify bitwise binary operations. !Return true if a transformation applied, otherwise return false. */ ! static bool ! simplify_bitwise_binary (gimple_stmt_iterator *gsi) { ! gimple stmt = gsi_stmt (*gsi); tree arg1 = gimple_assign_rhs1 (stmt); tree arg2 = gimple_assign_rhs2 (stmt); + enum tree_code code = gimple_assign_rhs_code (stmt); + tree res; ! /* If the first argument is an SSA name that is itself a result of a ! typecast of an ADDR_EXPR to an integer, feed the ADDR_EXPR to the ! folder rather than the ssa name. */ ! if (code == BIT_AND_EXPR !TREE_CODE (arg2) == INTEGER_CST !TREE_CODE (arg1) == SSA_NAME) { gimple def = SSA_NAME_DEF_STMT (arg1); + tree op = arg1; ! /* ??? This looks bogus - the conversion could be truncating. */ ! if (is_gimple_assign (def) ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)) ! INTEGRAL_TYPE_P (TREE_TYPE (arg1))) ! { ! tree opp = gimple_assign_rhs1 (def); ! if (TREE_CODE (opp) == ADDR_EXPR) ! op = opp; ! } ! res = fold_binary_loc (gimple_location (stmt), !BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)), !op, arg2); ! if (res is_gimple_min_invariant (res)) ! { ! gimple_assign_set_rhs_from_tree (gsi, res); ! update_stmt (stmt); ! return true; } } ! /* For bitwise binary operations apply operand conversions to the ! binary operation result instead of to the operands. This allows ! to combine successive conversions and bitwise binary operations. */ ! if (TREE_CODE (arg1) == SSA_NAME !TREE_CODE (arg2) == SSA_NAME) { ! gimple def_stmt1 = SSA_NAME_DEF_STMT (arg1); ! gimple def_stmt2 = SSA_NAME_DEF_STMT (arg2); ! if (is_gimple_assign (def_stmt1) ! is_gimple_assign (def_stmt2) ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt1)) ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))) ! { ! tree darg1 = gimple_assign_rhs1 (def_stmt1); ! tree darg2 = gimple_assign_rhs1 (def_stmt2); ! /* Make sure that the conversion widens the operands or that it !changes the operation to a bitfield precision. */ ! if (types_compatible_p (TREE_TYPE (darg1), TREE_TYPE (darg2)) ! ((TYPE_PRECISION (TREE_TYPE (darg1))
Move some option settings to finish_options
This patch moves some option settings from process_options to finish_options, making them avoid global state in the process, in preparation for moving parts of the target option override hook to be called from finish_options as well. (The idea is to minimize the amount of code in process_options above the call to targetm.target_option.override. Reordering code in the course of splitting the struct-based code from the global-state code is unavoidable, but moving this code now reduces the amount of reordering involved. I've checked the lang_hooks.post_options implementations and believe moving the target code past them should be safe.) Bootstrapped with no regressions on x86_64-unknown-linux-gnu. Applied to mainline. 2011-05-11 Joseph Myers jos...@codesourcery.com * opts.c (finish_options): Move warning settings from process_options. * toplev.c (process_options): Move warning settings to finish_options. Index: gcc/toplev.c === --- gcc/toplev.c(revision 173620) +++ gcc/toplev.c(working copy) @@ -1253,29 +1253,6 @@ process_options (void) maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT; - /* This replaces set_Wunused. */ - if (warn_unused_function == -1) -warn_unused_function = warn_unused; - if (warn_unused_label == -1) -warn_unused_label = warn_unused; - /* Wunused-parameter is enabled if both -Wunused -Wextra are enabled. */ - if (warn_unused_parameter == -1) -warn_unused_parameter = (warn_unused extra_warnings); - if (warn_unused_variable == -1) -warn_unused_variable = warn_unused; - /* Wunused-but-set-parameter is enabled if both -Wunused -Wextra are - enabled. */ - if (warn_unused_but_set_parameter == -1) -warn_unused_but_set_parameter = (warn_unused extra_warnings); - if (warn_unused_but_set_variable == -1) -warn_unused_but_set_variable = warn_unused; - if (warn_unused_value == -1) -warn_unused_value = warn_unused; - - /* This replaces set_Wextra. */ - if (warn_uninitialized == -1) -warn_uninitialized = extra_warnings; - /* Allow the front end to perform consistency checks and do further initialization based on the command line options. This hook also sets the original filename if appropriate (e.g. foo.i - foo.c) Index: gcc/opts.c === --- gcc/opts.c (revision 173620) +++ gcc/opts.c (working copy) @@ -807,6 +807,31 @@ finish_options (struct gcc_options *opts if (!opts-x_flag_tree_vectorize || !opts-x_flag_tree_loop_if_convert) maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0, opts-x_param_values, opts_set-x_param_values); + + /* This replaces set_Wunused. */ + if (opts-x_warn_unused_function == -1) +opts-x_warn_unused_function = opts-x_warn_unused; + if (opts-x_warn_unused_label == -1) +opts-x_warn_unused_label = opts-x_warn_unused; + /* Wunused-parameter is enabled if both -Wunused -Wextra are enabled. */ + if (opts-x_warn_unused_parameter == -1) +opts-x_warn_unused_parameter = (opts-x_warn_unused + opts-x_extra_warnings); + if (opts-x_warn_unused_variable == -1) +opts-x_warn_unused_variable = opts-x_warn_unused; + /* Wunused-but-set-parameter is enabled if both -Wunused -Wextra are + enabled. */ + if (opts-x_warn_unused_but_set_parameter == -1) +opts-x_warn_unused_but_set_parameter = (opts-x_warn_unused + opts-x_extra_warnings); + if (opts-x_warn_unused_but_set_variable == -1) +opts-x_warn_unused_but_set_variable = opts-x_warn_unused; + if (opts-x_warn_unused_value == -1) +opts-x_warn_unused_value = opts-x_warn_unused; + + /* This replaces set_Wextra. */ + if (opts-x_warn_uninitialized == -1) +opts-x_warn_uninitialized = opts-x_extra_warnings; } #define LEFT_COLUMN27 -- Joseph S. Myers jos...@codesourcery.com
[MELT] merged trunk into MELT branch.
Hello All, I just merged the trunk rev 173647 into MELT branch 173652: 2011-05-11 Basile Starynkevitch bas...@starynkevitch.net MELT branch merged with trunk rev 173647 using svnmerge That was quite a massive merge. The previous time trunk was merged into MELT branch was 2011-03-14 Basile Starynkevitch bas...@starynkevitch.net MELT branch merged with trunk rev 170941 From a coding point of view, today's merge was quite easy (I only had to add one line into gengtype.c). However, it seems that svn commit (aftere the merge) failed twice to work (wih a message similar to db/melt-branch/ out of date; I forgot the details). And svnmerge (I am using the svnmerge python scripts) took each time more than two hours (real time). Do you have any hints to avoid svn failure when merging (more precisely when commiting the massive changes)? Regards. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basileatstarynkevitchdotnet mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} ***
Re: Cgraph thunk reorg
Honza, This patch seems to have introduced approximately 150 new G++ testsuite failures on AIX. The errors all are verify_cgraph_node ICEs related to thunks. The all have a similar pattern: Hmm, thanks. It seems that visibility needs even more tweaking. I am currently on a trip till Saturday but I will try to look into it ASAP. Honza
[PATCH] Fix debug stmt handling in -ftree-loop-distribution (PR debug/48159)
Hi! The first testcase below ICEs, because generate_loops_for_partition removes phis and stmts in the get_loop_body_in_dom_order order of bbs and within within the bbs starting with phi nodes and then from beginning to end of the bb. While looking at it, I've noticed that stmts_from_loop and all the analysis happily considers debug stmts as any other stmts, so I fear it is problematic for -fcompare-debug, furthermore debug stmts should be just always kept and only reset when needed. The following patch implements that, debug stmts are ignored by the analysis, kept around unless the whole loop is transformed into memset and reset if they are using SSA_NAMES defined in the loop that are going to be removed (well, moved to another loop or done using memset). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6? 2011-05-11 Jakub Jelinek ja...@redhat.com PR debug/48159 * tree-data-ref.c (stmts_from_loop): Ignore debug stmts. * tree-loop-distribution.c (reset_debug_uses): New function. (generate_loops_for_partition): Call reset_debug_uses on the stmts that will be removed. Keep around all debug stmts, don't count them as bits in partition bitmap. (generate_builtin): Don't count debug stmts or labels as bits in partition bitmap. * gcc.dg/pr48159-1.c: New test. * gcc.dg/pr48159-2.c: New test. --- gcc/tree-data-ref.c.jj 2011-05-02 18:39:28.0 +0200 +++ gcc/tree-data-ref.c 2011-05-11 10:08:15.0 +0200 @@ -5017,7 +5017,7 @@ stmts_from_loop (struct loop *loop, VEC for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (bsi)) { stmt = gsi_stmt (bsi); - if (gimple_code (stmt) != GIMPLE_LABEL) + if (gimple_code (stmt) != GIMPLE_LABEL !is_gimple_debug (stmt)) VEC_safe_push (gimple, heap, *stmts, stmt); } } --- gcc/tree-loop-distribution.c.jj 2011-01-03 09:54:28.0 +0100 +++ gcc/tree-loop-distribution.c2011-05-11 10:36:27.0 +0200 @@ -152,6 +152,34 @@ create_bb_after_loop (struct loop *loop) split_edge (exit); } +/* Reset all debug stmts that use SSA_NAME(s) defined in STMT. */ + +static void +reset_debug_uses (gimple stmt) +{ + ssa_op_iter op_iter; + def_operand_p def_p; + imm_use_iterator imm_iter; + gimple use_stmt; + + FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF) +{ + tree var = DEF_FROM_PTR (def_p); + + if (TREE_CODE (var) != SSA_NAME) + continue; + + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, var) + { + if (!gimple_debug_bind_p (use_stmt)) + continue; + + gimple_debug_bind_reset_value (use_stmt); + update_stmt (use_stmt); + } +} +} + /* Generate code for PARTITION from the code in LOOP. The loop is copied when COPY_P is true. All the statements not flagged in the PARTITION bitmap are removed from the loop or from its copy. The @@ -181,6 +209,25 @@ generate_loops_for_partition (struct loo stmts_from_loop. */ bbs = get_loop_body_in_dom_order (loop); + if (MAY_HAVE_DEBUG_STMTS) +for (x = 0, i = 0; i loop-num_nodes; i++) + { + basic_block bb = bbs[i]; + + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (bsi)) + if (!bitmap_bit_p (partition, x++)) + reset_debug_uses (gsi_stmt (bsi)); + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (bsi)) + { + gimple stmt = gsi_stmt (bsi); + if (gimple_code (stmt) != GIMPLE_LABEL +!is_gimple_debug (stmt) +!bitmap_bit_p (partition, x++)) + reset_debug_uses (stmt); + } + } + for (x = 0, i = 0; i loop-num_nodes; i++) { basic_block bb = bbs[i]; @@ -199,7 +246,8 @@ generate_loops_for_partition (struct loo for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);) { gimple stmt = gsi_stmt (bsi); - if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL + if (gimple_code (stmt) != GIMPLE_LABEL + !is_gimple_debug (stmt) !bitmap_bit_p (partition, x++)) { unlink_stmt_vdef (stmt); @@ -312,7 +360,9 @@ generate_builtin (struct loop *loop, bit { gimple stmt = gsi_stmt (bsi); - if (bitmap_bit_p (partition, x++) + if (gimple_code (stmt) != GIMPLE_LABEL + !is_gimple_debug (stmt) + bitmap_bit_p (partition, x++) is_gimple_assign (stmt) !is_gimple_reg (gimple_assign_lhs (stmt))) { --- gcc/testsuite/gcc.dg/pr48159-1.c.jj 2011-05-11 10:38:03.0 +0200 +++ gcc/testsuite/gcc.dg/pr48159-1.c2011-05-11 10:37:34.0 +0200 @@ -0,0 +1,10 @@ +/* PR debug/48159 */ +/* { dg-do compile } */ +/* { dg-options -O3 -fcompare-debug } */ + +void +foo (double x, int y, double *__restrict z, double *__restrict w) +{ +
Re: [PATCH] Fix debug stmt handling in -ftree-loop-distribution (PR debug/48159)
On Wed, May 11, 2011 at 2:15 PM, Jakub Jelinek ja...@redhat.com wrote: Hi! The first testcase below ICEs, because generate_loops_for_partition removes phis and stmts in the get_loop_body_in_dom_order order of bbs and within within the bbs starting with phi nodes and then from beginning to end of the bb. While looking at it, I've noticed that stmts_from_loop and all the analysis happily considers debug stmts as any other stmts, so I fear it is problematic for -fcompare-debug, furthermore debug stmts should be just always kept and only reset when needed. The following patch implements that, debug stmts are ignored by the analysis, kept around unless the whole loop is transformed into memset and reset if they are using SSA_NAMES defined in the loop that are going to be removed (well, moved to another loop or done using memset). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6? Ok if you move reset_debug_uses to ... hmmm, say, tree-ssa.c near the other debug related fns. Thanks, Richard. 2011-05-11 Jakub Jelinek ja...@redhat.com PR debug/48159 * tree-data-ref.c (stmts_from_loop): Ignore debug stmts. * tree-loop-distribution.c (reset_debug_uses): New function. (generate_loops_for_partition): Call reset_debug_uses on the stmts that will be removed. Keep around all debug stmts, don't count them as bits in partition bitmap. (generate_builtin): Don't count debug stmts or labels as bits in partition bitmap. * gcc.dg/pr48159-1.c: New test. * gcc.dg/pr48159-2.c: New test. --- gcc/tree-data-ref.c.jj 2011-05-02 18:39:28.0 +0200 +++ gcc/tree-data-ref.c 2011-05-11 10:08:15.0 +0200 @@ -5017,7 +5017,7 @@ stmts_from_loop (struct loop *loop, VEC for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (bsi)) { stmt = gsi_stmt (bsi); - if (gimple_code (stmt) != GIMPLE_LABEL) + if (gimple_code (stmt) != GIMPLE_LABEL !is_gimple_debug (stmt)) VEC_safe_push (gimple, heap, *stmts, stmt); } } --- gcc/tree-loop-distribution.c.jj 2011-01-03 09:54:28.0 +0100 +++ gcc/tree-loop-distribution.c 2011-05-11 10:36:27.0 +0200 @@ -152,6 +152,34 @@ create_bb_after_loop (struct loop *loop) split_edge (exit); } +/* Reset all debug stmts that use SSA_NAME(s) defined in STMT. */ + +static void +reset_debug_uses (gimple stmt) +{ + ssa_op_iter op_iter; + def_operand_p def_p; + imm_use_iterator imm_iter; + gimple use_stmt; + + FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF) + { + tree var = DEF_FROM_PTR (def_p); + + if (TREE_CODE (var) != SSA_NAME) + continue; + + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, var) + { + if (!gimple_debug_bind_p (use_stmt)) + continue; + + gimple_debug_bind_reset_value (use_stmt); + update_stmt (use_stmt); + } + } +} + /* Generate code for PARTITION from the code in LOOP. The loop is copied when COPY_P is true. All the statements not flagged in the PARTITION bitmap are removed from the loop or from its copy. The @@ -181,6 +209,25 @@ generate_loops_for_partition (struct loo stmts_from_loop. */ bbs = get_loop_body_in_dom_order (loop); + if (MAY_HAVE_DEBUG_STMTS) + for (x = 0, i = 0; i loop-num_nodes; i++) + { + basic_block bb = bbs[i]; + + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (bsi)) + if (!bitmap_bit_p (partition, x++)) + reset_debug_uses (gsi_stmt (bsi)); + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (bsi)) + { + gimple stmt = gsi_stmt (bsi); + if (gimple_code (stmt) != GIMPLE_LABEL + !is_gimple_debug (stmt) + !bitmap_bit_p (partition, x++)) + reset_debug_uses (stmt); + } + } + for (x = 0, i = 0; i loop-num_nodes; i++) { basic_block bb = bbs[i]; @@ -199,7 +246,8 @@ generate_loops_for_partition (struct loo for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);) { gimple stmt = gsi_stmt (bsi); - if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL + if (gimple_code (stmt) != GIMPLE_LABEL + !is_gimple_debug (stmt) !bitmap_bit_p (partition, x++)) { unlink_stmt_vdef (stmt); @@ -312,7 +360,9 @@ generate_builtin (struct loop *loop, bit { gimple stmt = gsi_stmt (bsi); - if (bitmap_bit_p (partition, x++) + if (gimple_code (stmt) != GIMPLE_LABEL + !is_gimple_debug (stmt) + bitmap_bit_p (partition, x++) is_gimple_assign (stmt) !is_gimple_reg (gimple_assign_lhs (stmt))) { --- gcc/testsuite/gcc.dg/pr48159-1.c.jj 2011-05-11 10:38:03.0 +0200
[PATCH] Fix PR48953
This fixes the tree inliner which fails to remap the type of MEM_REFs. That downstream causes issues when LTO re-computes TYPE_CANONICAL and fails during stmt verification. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. I'm considering this also for 4.6 as it is latent there. Richard. 2011-05-11 Richard Guenther rguent...@suse.de PR middle-end/48953 * tree-inline.c (remap_gimple_op_r): Also remap types of MEM_REFs. * gcc.dg/torture/pr48953.c: New testcase. Index: gcc/tree-inline.c === *** gcc/tree-inline.c (revision 173649) --- gcc/tree-inline.c (working copy) *** remap_gimple_op_r (tree *tp, int *walk_s *** 811,819 --- 811,825 { /* Otherwise, just copy the node. Note that copy_tree_r already knows not to copy VAR_DECLs, etc., so this is safe. */ + + /* We should never have TREE_BLOCK set on non-statements. */ + if (EXPR_P (*tp)) + gcc_assert (!TREE_BLOCK (*tp)); + if (TREE_CODE (*tp) == MEM_REF) { tree ptr = TREE_OPERAND (*tp, 0); + tree type = remap_type (TREE_TYPE (*tp), id); tree old = *tp; tree tem; *** remap_gimple_op_r (tree *tp, int *walk_s *** 824,830 if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp), ptr, TREE_OPERAND (*tp, 1), !TREE_TYPE (*tp))) TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old)) { tree *tem_basep = tem; --- 830,836 if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp), ptr, TREE_OPERAND (*tp, 1), !type)) TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old)) { tree *tem_basep = tem; *** remap_gimple_op_r (tree *tp, int *walk_s *** 846,852 } else { ! *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp), ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); --- 852,858 } else { ! *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); *** remap_gimple_op_r (tree *tp, int *walk_s *** 860,865 --- 866,874 tweak some special cases. */ copy_tree_r (tp, walk_subtrees, NULL); + if (TREE_CODE (*tp) != OMP_CLAUSE) + TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id); + /* Global variables we haven't seen yet need to go into referenced vars. If not referenced from types only. */ if (gimple_in_ssa_p (cfun) *** remap_gimple_op_r (tree *tp, int *walk_s *** 868,880 !processing_debug_stmt) add_referenced_var (*tp); - /* We should never have TREE_BLOCK set on non-statements. */ - if (EXPR_P (*tp)) - gcc_assert (!TREE_BLOCK (*tp)); - - if (TREE_CODE (*tp) != OMP_CLAUSE) - TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id); - if (TREE_CODE (*tp) == TARGET_EXPR TREE_OPERAND (*tp, 3)) { /* The copied TARGET_EXPR has never been expanded, even if the --- 877,882 Index: gcc/testsuite/gcc.dg/torture/pr48953.c === *** gcc/testsuite/gcc.dg/torture/pr48953.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr48953.c (revision 0) *** *** 0 --- 1,17 + /* { dg-do run } */ + /* { dg-options -fno-tree-dce } */ + + static inline int foo (int n, int k) + { + struct S + { + int i[n]; + int value; + } s[2]; + return s[k].value = 0; + } + + int main () + { + return foo (2, 0); + }
[C++ PATCH] Attempt to find implicitly determined firstprivate class type vars during genericization (PR c++/48869)
Hi! Richard's changes to gimplify C++ unit at a time apparently broke OpenMP 3.0 support in C++, if a variable is implicitly firstprivate in some task region and needs copy ctor or dtor instantiated, the copy ctor or dtor might not be instantiated. In 4.4 when the gimplifier noticed an implicitly firstprivate variable, it told the FE to finalize the clause and it was instantiated later on, but now the gimplification happens after instantiation of pending templates. This patch duplicates parts of the gimplifier's work during genericization, just to determine if a class typed var referenced in some task region might be firstprivate or not. If it finds such vars, it just calls get_dtor and get_copy_ctor on its type to make sure they will be instantiated. I've added to those two functions a COMPLAIN argument, so that this is done quietly in case the genericization code wasn't 100% right, the ultimate code is still in the gimplifier, which has to do such a job anyway e.g. to prevent DECL_VALUE_EXPR vars from expansion in OpenMP regions when needed, and also so that it is done for all 3 FEs instead of each FE rolling its own. Bootstrapped/regtested on x86_64-linux and i686-linux. Jason, are you ok with it? 2011-05-11 Jakub Jelinek ja...@redhat.com PR c++/48869 * method.c (get_dtor, get_copy_ctor): Add COMPLAIN argument, pass it down to locate_fn_flags. * cp-tree.h (get_dtor, get_copy_ctor): Adjust prototypes. * semantics.c (cxx_omp_create_clause_info): Adjust callers. * cp-gimplify.c: Include splay-tree.h. (splay_tree_compare_decl_uid, omp_var_to_track, omp_cxx_notice_variable): New functions. (struct cp_genericize_omp_taskreg): New type. (struct cp_genericize_data): Add omp_ctx field. (cp_genericize_r): Attempt to determine implicitly determined firstprivate class type variables. (cp_genericize): Clear omp_ctx. * Make-lang.in (cp/cp-gimplify.o): Depend on $(SPLAY_TREE_H). * testsuite/libgomp.c++/pr48869.C: New test. --- gcc/cp/method.c.jj 2011-05-04 10:13:56.0 +0200 +++ gcc/cp/method.c 2011-05-10 18:47:31.0 +0200 @@ -843,10 +843,10 @@ locate_fn_flags (tree type, tree name, t /* Locate the dtor of TYPE. */ tree -get_dtor (tree type) +get_dtor (tree type, tsubst_flags_t complain) { tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE, -LOOKUP_NORMAL, tf_warning_or_error); +LOOKUP_NORMAL, complain); if (fn == error_mark_node) return NULL_TREE; return fn; @@ -883,13 +883,13 @@ get_default_ctor (tree type) /* Locate the copy ctor of TYPE. */ tree -get_copy_ctor (tree type) +get_copy_ctor (tree type, tsubst_flags_t complain) { int quals = (TYPE_HAS_CONST_COPY_CTOR (type) ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); tree argtype = build_stub_type (type, quals, false); tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype, -LOOKUP_NORMAL, tf_warning_or_error); +LOOKUP_NORMAL, complain); if (fn == error_mark_node) return NULL_TREE; return fn; --- gcc/cp/cp-tree.h.jj 2011-05-04 10:13:56.0 +0200 +++ gcc/cp/cp-tree.h2011-05-10 18:47:31.0 +0200 @@ -5020,10 +5020,10 @@ extern tree lazily_declare_fn (special extern tree skip_artificial_parms_for (const_tree, tree); extern int num_artificial_parms_for(const_tree); extern tree make_alias_for (tree, tree); -extern tree get_copy_ctor (tree); +extern tree get_copy_ctor (tree, tsubst_flags_t); extern tree get_copy_assign(tree); extern tree get_default_ctor (tree); -extern tree get_dtor (tree); +extern tree get_dtor (tree, tsubst_flags_t); extern tree locate_ctor(tree); /* In optimize.c */ --- gcc/cp/semantics.c.jj 2011-05-02 18:39:12.0 +0200 +++ gcc/cp/semantics.c 2011-05-10 18:47:31.0 +0200 @@ -3757,7 +3757,7 @@ cxx_omp_create_clause_info (tree c, tree if (need_default_ctor) t = get_default_ctor (type); else - t = get_copy_ctor (type); + t = get_copy_ctor (type, tf_warning_or_error); if (t !trivial_fn_p (t)) TREE_VEC_ELT (info, 0) = t; @@ -3765,7 +3765,7 @@ cxx_omp_create_clause_info (tree c, tree if ((need_default_ctor || need_copy_ctor) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) -TREE_VEC_ELT (info, 1) = get_dtor (type); +TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error); if (need_copy_assignment) { --- gcc/cp/cp-gimplify.c.jj 2011-05-04 10:13:56.0 +0200 +++ gcc/cp/cp-gimplify.c2011-05-11 09:40:21.0 +0200 @@ -32,6 +32,7 @@ along with GCC; see the
[PATCH][4/n] Cleanup LTO type merging
This removes the mode param from the generic type merging machinery and simplifies code accordingly. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-11 Richard Guenther rguent...@suse.de * gimple.c (gimple_type_hash_1): Merge with ... (gimple_type_hash): ... this. (gtc_visit): Remove mode parameter and simplify accordingly. (gimple_types_compatible_p_1): Likewise. (gimple_types_compatible_p): Likewise. (iterative_hash_gimple_type): Likewise. (visit): Likewise. (gimple_type_eq): Adjust. Index: gcc/gimple.c === --- gcc/gimple.c(revision 173649) +++ gcc/gimple.c(working copy) @@ -3210,7 +3210,7 @@ gimple_call_copy_skip_args (gimple stmt, enum gtc_mode { GTC_MERGE = 0, GTC_DIAG = 1 }; -static hashval_t gimple_type_hash_1 (const void *, enum gtc_mode); +static hashval_t gimple_type_hash (const void *); /* Structure used to maintain a cache of some type pairs compared by gimple_types_compatible_p when comparing aggregate types. There are @@ -3459,7 +3459,7 @@ gimple_compatible_complete_and_incomplet } static bool -gimple_types_compatible_p_1 (tree, tree, enum gtc_mode, type_pair_t, +gimple_types_compatible_p_1 (tree, tree, type_pair_t, VEC(type_pair_t, heap) **, struct pointer_map_t *, struct obstack *); @@ -3470,7 +3470,7 @@ gimple_types_compatible_p_1 (tree, tree, SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */ static bool -gtc_visit (tree t1, tree t2, enum gtc_mode mode, +gtc_visit (tree t1, tree t2, struct sccs *state, VEC(type_pair_t, heap) **sccstack, struct pointer_map_t *sccstate, @@ -3479,6 +3479,7 @@ gtc_visit (tree t1, tree t2, enum gtc_mo struct sccs *cstate = NULL; type_pair_t p; void **slot; + tree leader1, leader2; /* Check first for the obvious case of pointer identity. */ if (t1 == t2) @@ -3490,21 +3491,12 @@ gtc_visit (tree t1, tree t2, enum gtc_mo /* If the types have been previously registered and found equal they still are. */ - if (mode == GTC_MERGE) -{ - tree leader1 = gimple_lookup_type_leader (t1); - tree leader2 = gimple_lookup_type_leader (t2); - if (leader1 == t2 - || t1 == leader2 - || (leader1 leader1 == leader2)) - return true; -} - else if (mode == GTC_DIAG) -{ - if (TYPE_CANONICAL (t1) - TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)) - return true; -} + leader1 = gimple_lookup_type_leader (t1); + leader2 = gimple_lookup_type_leader (t2); + if (leader1 == t2 + || t1 == leader2 + || (leader1 leader1 == leader2)) +return true; /* Can't be the same type if the types don't have the same code. */ if (TREE_CODE (t1) != TREE_CODE (t2)) @@ -3558,16 +3550,16 @@ gtc_visit (tree t1, tree t2, enum gtc_mo /* If the hash values of t1 and t2 are different the types can't possibly be the same. This helps keeping the type-pair hashtable small, only tracking comparisons for hash collisions. */ - if (gimple_type_hash_1 (t1, mode) != gimple_type_hash_1 (t2, mode)) + if (gimple_type_hash (t1) != gimple_type_hash (t2)) return false; /* Allocate a new cache entry for this comparison. */ p = lookup_type_pair (t1, t2, gtc_visited, gtc_ob); - if (p-same_p[mode] == 0 || p-same_p[mode] == 1) + if (p-same_p[GTC_MERGE] == 0 || p-same_p[GTC_MERGE] == 1) { /* We have already decided whether T1 and T2 are the same, return the cached result. */ - return p-same_p[mode] == 1; + return p-same_p[GTC_MERGE] == 1; } if ((slot = pointer_map_contains (sccstate, p)) != NULL) @@ -3575,7 +3567,7 @@ gtc_visit (tree t1, tree t2, enum gtc_mo /* Not yet visited. DFS recurse. */ if (!cstate) { - gimple_types_compatible_p_1 (t1, t2, mode, p, + gimple_types_compatible_p_1 (t1, t2, p, sccstack, sccstate, sccstate_obstack); cstate = (struct sccs *)* pointer_map_contains (sccstate, p); state-low = MIN (state-low, cstate-low); @@ -3595,15 +3587,14 @@ gtc_visit (tree t1, tree t2, enum gtc_mo SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */ static bool -gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode, -type_pair_t p, +gimple_types_compatible_p_1 (tree t1, tree t2, type_pair_t p, VEC(type_pair_t, heap) **sccstack, struct pointer_map_t *sccstate, struct obstack *sccstate_obstack) { struct sccs *state; - gcc_assert (p-same_p[mode] == -2); + gcc_assert (p-same_p[GTC_MERGE] == -2); state = XOBNEW (sccstate_obstack, struct sccs); *pointer_map_insert
[Patch, IRA] Fix a function accessing beyond end-of-array
Hello, I discussed this problem with Vlad in http://gcc.gnu.org/ml/gcc/2011-05/msg00131.html. I propose the following patch to fix it. Okay to commit? Thanks Hari ChangeLog: * ira.c (clarify_prohibited_class_mode_regs): It was running beyond the end of REGNO_REG_CLASS array. Fixed. Patch: Index: gcc/ira.c === --- gcc/ira.c (revision 173654) +++ gcc/ira.c (working copy) @@ -1422,6 +1422,12 @@ if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) continue; nregs = hard_regno_nregs[hard_regno][j]; + if (hard_regno + nregs = FIRST_PSEUDO_REGISTER) +{ + SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], +hard_regno); + continue; +} pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; for (nregs-- ;nregs = 0; nregs--) if (((enum reg_class) pclass
[Patch, Fortran] PR 48889 - fix 4.6/4.7 regression: ICE in generics' resolution
As the PR shows, in the function the gfc_expr can be such that expr-value.function.esym points to the correct specific function but the generic expr-symtree-n.sym does not exist (expr-symtree == NULL). However, also the opposite can happen that only expr-symtree is set and neither esym nor isym is (yet) set. Build and regtested on x86-64-linux. OK for the trunk and 4.6? * * * Regression status: - PR 48955 [4.6/4.7] Serious missing temporary regression, which Paul wants to fix - PR 45586 [4.6/4.7] Restricted vs. not-restricted assignment-tree check ICE - PR 48786 [4.6/4.7] Probably no regression and just two OOP-related bugs - PR 42954 [4.5/4.6/4.7]: Target CPP regression ... Tobias 2011-05-11 Tobias Burnus bur...@net-b.de PR fortran/48889 * expr.c (gfc_is_constant_expr): Use e-value.function.esym instead of e-symtree-n.sym, if available. 2011-05-11 Tobias Burnus bur...@net-b.de PR fortran/48889 * gfortran.dg/generic_24.f90: New. diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 3d519db..f881bb1 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -893,6 +893,9 @@ gfc_is_constant_expr (gfc_expr *e) case EXPR_FUNCTION: case EXPR_PPC: case EXPR_COMPCALL: + gcc_assert (e-symtree || e-value.function.esym + || e-value.function.isym); + /* Call to intrinsic with at least one argument. */ if (e-value.function.isym e-value.function.actual) { @@ -901,13 +904,14 @@ gfc_is_constant_expr (gfc_expr *e) return 0; } - /* Make sure we have a symbol. */ - gcc_assert (e-symtree); - - sym = e-symtree-n.sym; - /* Specification functions are constant. */ /* F95, 7.1.6.2; F2003, 7.1.7 */ + sym = NULL; + if (e-symtree) + sym = e-symtree-n.sym; + if (e-value.function.esym) + sym = e-value.function.esym; + if (sym sym-attr.function sym-attr.pure --- /dev/null 2011-05-11 08:03:10.239890179 +0200 +++ gcc/gcc/testsuite/gfortran.dg/generic_24.f90 2011-05-11 14:28:53.0 +0200 @@ -0,0 +1,100 @@ +! { dg-do compile } +! +! PR fortran/48889 +! +! Thanks for +! reporting to Lawrence Mitchell +! for the test case to David Ham +! +module sparse_tools + implicit none + private + + type csr_foo + integer, dimension(:), pointer :: colm=null() + end type csr_foo + + type block_csr_matrix + type(csr_foo) :: sparsity + end type block_csr_matrix + + interface attach_block + module procedure block_csr_attach_block + end interface + + interface size + module procedure sparsity_size + end interface + + public :: size, attach_block +contains + subroutine block_csr_attach_block(matrix, val) +type(block_csr_matrix), intent(inout) :: matrix +real, dimension(size(matrix%sparsity%colm)), intent(in), target :: val + end subroutine block_csr_attach_block + + pure function sparsity_size(sparsity, dim) +integer :: sparsity_size +type(csr_foo), intent(in) :: sparsity +integer, optional, intent(in) :: dim + end function sparsity_size +end module sparse_tools + +module global_numbering + use sparse_tools + implicit none + + type ele_numbering_type + integer :: boundaries + end type ele_numbering_type + + type element_type + integer :: loc + type(ele_numbering_type), pointer :: numbering=null() + end type element_type + + type csr_sparsity + end type csr_sparsity + + interface size + module procedure sparsity_size + end interface size +contains + pure function sparsity_size(sparsity, dim) +integer :: sparsity_size +type(csr_sparsity), intent(in) :: sparsity +integer, optional, intent(in) :: dim + end function sparsity_size + + subroutine make_boundary_numbering(EEList, xndglno, ele_n) +type(csr_sparsity), intent(in) :: EEList +type(element_type), intent(in) :: ele_n +integer, dimension(size(EEList,1)*ele_n%loc), intent(in), target :: + xndglno +integer, dimension(ele_n%numbering%boundaries) :: neigh +integer :: j +j=size(neigh) + end subroutine make_boundary_numbering +end module global_numbering + +module sparse_matrices_fields + use sparse_tools +implicit none + type scalar_field + real, dimension(:), pointer :: val + end type scalar_field +contains + subroutine csr_mult_T_scalar(x) +type(scalar_field), intent(inout) :: x +real, dimension(:), allocatable :: tmp +integer :: i +i=size(x%val) + end subroutine csr_mult_T_scalar +end module sparse_matrices_fields + +program test + use sparse_matrices_fields + use global_numbering +end program test + +! { dg-final { cleanup-tree-dump sparse_tools sparse_matrices_fields global_numbering } }
[PATCH][6/n] LTO type merging cleanup
This streamlines the now separate hashing and comparing functions for canonical and regular type matching. It should significantly shrink the canonical tables (doing more merging) and reduce the number of hash collisions in the regular tables. Boostrap regtest pending on x86_64-unknown-linux-gnu. Richard. 2011-05-11 Richard Guenther rguent...@suse.de * gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. Defer type-leader lookup until after simple checks. (gimple_types_compatible_p): Likewise. (iterative_hash_gimple_type): Always hash pointer targets and function return and argument types. (iterative_hash_canonical_type): Do not hash TYPE_QUALS, hash TYPE_ALIGN. Do not hash TYPE_MIN/MAX_VALUE. (gimple_canonical_types_compatible_p): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. Handle non-aggregates completely in the simple compare section. Index: gcc/gimple.c === *** gcc/gimple.c(revision 173655) --- gcc/gimple.c(working copy) *** gtc_visit (tree t1, tree t2, *** 3489,3503 if (t1 == NULL_TREE || t2 == NULL_TREE) return false; - /* If the types have been previously registered and found equal - they still are. */ - leader1 = gimple_lookup_type_leader (t1); - leader2 = gimple_lookup_type_leader (t2); - if (leader1 == t2 - || t1 == leader2 - || (leader1 leader1 == leader2)) - return true; - /* Can't be the same type if the types don't have the same code. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return false; --- 3489,3494 *** gtc_visit (tree t1, tree t2, *** 3506,3528 if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return false; ! /* Void types are always the same. */ ! if (TREE_CODE (t1) == VOID_TYPE) return true; /* Do some simple checks before doing three hashtable queries. */ if (INTEGRAL_TYPE_P (t1) || SCALAR_FLOAT_TYPE_P (t1) || FIXED_POINT_TYPE_P (t1) || TREE_CODE (t1) == VECTOR_TYPE || TREE_CODE (t1) == COMPLEX_TYPE ! || TREE_CODE (t1) == OFFSET_TYPE) { ! /* Can't be the same type if they have different alignment, !sign, precision or mode. */ ! if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) ! || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) ! || TYPE_MODE (t1) != TYPE_MODE (t2) || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) return false; --- 3497,3526 if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return false; ! if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2)) ! return false; ! ! /* Void types and nullptr types are always the same. */ ! if (TREE_CODE (t1) == VOID_TYPE ! || TREE_CODE (t1) == NULLPTR_TYPE) return true; + /* Can't be the same type if they have different alignment or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2)) + return false; + /* Do some simple checks before doing three hashtable queries. */ if (INTEGRAL_TYPE_P (t1) || SCALAR_FLOAT_TYPE_P (t1) || FIXED_POINT_TYPE_P (t1) || TREE_CODE (t1) == VECTOR_TYPE || TREE_CODE (t1) == COMPLEX_TYPE ! || TREE_CODE (t1) == OFFSET_TYPE ! || POINTER_TYPE_P (t1)) { ! /* Can't be the same type if they have different sign or precision. */ ! if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2) || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) return false; *** gtc_visit (tree t1, tree t2, *** 3536,3551 || FIXED_POINT_TYPE_P (t1)) return true; ! /* For integral types fall thru to more complex checks. */ } ! else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1)) ! { ! /* Can't be the same type if they have different alignment or mode. */ ! if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) ! || TYPE_MODE (t1) != TYPE_MODE (t2)) ! return false; ! } /* If the hash values of t1 and t2 are different the types can't possibly be the same. This helps keeping the type-pair hashtable --- 3534,3550 || FIXED_POINT_TYPE_P (t1)) return true; ! /* For other types fall thru to more complex checks. */ } ! /* If the types have been previously registered and found equal ! they still are. */ ! leader1 = gimple_lookup_type_leader (t1); ! leader2 = gimple_lookup_type_leader (t2); ! if (leader1 == t2 ! || t1 == leader2 ! || (leader1 leader1 == leader2)) ! return true; /* If the hash values of t1 and t2 are different the types can't possibly be the same. This helps keeping the type-pair hashtable *** gimple_types_compatible_p_1 (tree t1, tr *** 3739,3748
Re: [Patch, IRA] Fix a function accessing beyond end-of-array
* ira.c (clarify_prohibited_class_mode_regs): It was running beyond the end of REGNO_REG_CLASS array. Fixed. This isn't a valid ChangeLog entry. It must not state the why (it was running beyond the end of REGNO_REG_CLASS array), only the what. So you need to describe how you're fixing the problem, e.g. Do not access the array if ... or Stop the loop if See the numerous examples in ChangeLog. -- Eric Botcazou
Re: [PATCH][3/n] LTO type merging cleanup
On Tue, May 10, 2011 at 8:41 AM, Richard Guenther rguent...@suse.de wrote: This is the second half of splitting TYPE_CANONICAL handling away from the rest of the machinery. The following patch introduces a simplified, non-SCC based hashing for TYPE_CANONICAL - it still hashes things it shouldn't, but the patch is supposed to be functional equivalent apart from the pointer-following case. Bootstrapped on x86_64-unknown-linux-gnu, testing and SPEC2k6 LTO building in progress. I plan to commit both pieces together tomorrow, if the testing succeeded. A followup will then remove dead codepaths from the other half of the machinery, followed by a patch to simplify both hashing and comparing TYPE_CANONICALs a tad bid. Richard. 2011-05-10 Richard Guenther rguent...@suse.de * gimple.c (iterative_hash_canonical_type): Split out from iterative_hash_gimple_type and friends. Do not recurse to pointed-to types. (gimple_canonical_type_hash): Use it, allocate the hash here. This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48964 -- H.J.
Re: [PATCH][1/n] LTO type merging cleanup
On Mon, May 9, 2011 at 8:15 AM, Richard Guenther rguent...@suse.de wrote: This makes gimple_types_compatible_p private to gimple.c again, removing the need to call it from lto-symtab.c as we now merge types early (and thus we can resort to the middle-end types_compatible_p function). Bootstrapped on x86_64-unknown-linux-gnu, testing and SPEC2k6 build in progress. Given that one of LTO type merging cleanup patches breaks LTO bootstrap, I think we should pause and fix LTO bootstrap before applying more patches. Thanks. -- H.J.
[Patch, IRA] Fix a function accessing beyond end-of-array
Hello, I discussed this problem with Vlad in http://gcc.gnu.org/ml/gcc/2011-05/msg00131.html. I propose the following patch to fix it. Okay to commit? Revised the ChangeLog. Thanks Hari ChangeLog: * ira.c (clarify_prohibited_class_mode_regs): Prevent the function from accessing beyond the end of REGNO_REG_CLASS array by stopping the loop early. Patch: Index: gcc/ira.c === --- gcc/ira.c (revision 173654) +++ gcc/ira.c (working copy) @@ -1422,6 +1422,12 @@ if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) continue; nregs = hard_regno_nregs[hard_regno][j]; + if (hard_regno + nregs = FIRST_PSEUDO_REGISTER) +{ + SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], +hard_regno); + continue; +} pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; for (nregs-- ;nregs = 0; nregs--) if (((enum reg_class) pclass
[PATCH] Fix parts of PR15256
This fixes parts of PR15256 - optimization of manual bitfield manipulation on the tree level. The patch extends the previous forwprop patch for this and adds two additional patterns we can easily match. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-11 Richard Guenther rguent...@suse.de PR tree-optimization/15256 * tree-ssa-forwprop.c (simplify_bitwise_binary): Canonicalize (A B) | C, combine (A op CST1) op CST2. (tree_ssa_forward_propagate_single_use_vars): Only bother to visit assigns that have uses. * gcc.dg/tree-ssa/forwprop-14.c: New testcase. Index: gcc/tree-ssa-forwprop.c === *** gcc/tree-ssa-forwprop.c (revision 173650) --- gcc/tree-ssa-forwprop.c (working copy) *** simplify_bitwise_binary (gimple_stmt_ite *** 1623,1628 --- 1623,1631 tree arg2 = gimple_assign_rhs2 (stmt); enum tree_code code = gimple_assign_rhs_code (stmt); tree res; + gimple def1 = NULL, def2 = NULL; + tree def1_arg1, def2_arg1; + enum tree_code def1_code, def2_code; /* If the first argument is an SSA name that is itself a result of a typecast of an ADDR_EXPR to an integer, feed the ADDR_EXPR to the *** simplify_bitwise_binary (gimple_stmt_ite *** 1655,1698 } } /* For bitwise binary operations apply operand conversions to the binary operation result instead of to the operands. This allows to combine successive conversions and bitwise binary operations. */ ! if (TREE_CODE (arg1) == SSA_NAME !TREE_CODE (arg2) == SSA_NAME) { ! gimple def_stmt1 = SSA_NAME_DEF_STMT (arg1); ! gimple def_stmt2 = SSA_NAME_DEF_STMT (arg2); ! if (is_gimple_assign (def_stmt1) ! is_gimple_assign (def_stmt2) ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt1)) ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))) ! { ! tree darg1 = gimple_assign_rhs1 (def_stmt1); ! tree darg2 = gimple_assign_rhs1 (def_stmt2); ! /* Make sure that the conversion widens the operands or that it !changes the operation to a bitfield precision. */ ! if (types_compatible_p (TREE_TYPE (darg1), TREE_TYPE (darg2)) ! ((TYPE_PRECISION (TREE_TYPE (darg1)) ! TYPE_PRECISION (TREE_TYPE (arg1))) ! || (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (arg1))) ! != MODE_INT) ! || (TYPE_PRECISION (TREE_TYPE (arg1)) ! != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg1)) ! { ! gimple newop; ! tree tem = create_tmp_reg (TREE_TYPE (darg1), !NULL); ! newop = gimple_build_assign_with_ops (code, tem, darg1, darg2); ! tem = make_ssa_name (tem, newop); ! gimple_assign_set_lhs (newop, tem); ! gsi_insert_before (gsi, newop, GSI_SAME_STMT); ! gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR, ! tem, NULL_TREE, NULL_TREE); ! update_stmt (gsi_stmt (*gsi)); ! return true; ! } } } return false; --- 1658,1759 } } + def1_code = TREE_CODE (arg1); + def1_arg1 = arg1; + if (TREE_CODE (arg1) == SSA_NAME) + { + def1 = SSA_NAME_DEF_STMT (arg1); + if (is_gimple_assign (def1)) + { + def1_code = gimple_assign_rhs_code (def1); + def1_arg1 = gimple_assign_rhs1 (def1); + } + } + + def2_code = TREE_CODE (arg2); + def2_arg1 = arg2; + if (TREE_CODE (arg2) == SSA_NAME) + { + def2 = SSA_NAME_DEF_STMT (arg2); + if (is_gimple_assign (def2)) + { + def2_code = gimple_assign_rhs_code (def2); + def2_arg1 = gimple_assign_rhs1 (def2); + } + } + /* For bitwise binary operations apply operand conversions to the binary operation result instead of to the operands. This allows to combine successive conversions and bitwise binary operations. */ ! if (CONVERT_EXPR_CODE_P (def1_code) !CONVERT_EXPR_CODE_P (def2_code) !types_compatible_p (TREE_TYPE (def1_arg1), TREE_TYPE (def2_arg1)) ! /* Make sure that the conversion widens the operands or that it !changes the operation to a bitfield precision. */ !((TYPE_PRECISION (TREE_TYPE (def1_arg1)) ! TYPE_PRECISION (TREE_TYPE (arg1))) ! || (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (arg1))) ! != MODE_INT) ! || (TYPE_PRECISION (TREE_TYPE (arg1)) ! != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg1)) { ! gimple newop; ! tree tem = create_tmp_reg (TREE_TYPE (def1_arg1), !NULL); ! newop =
Re: [ARM] TLS Descriptor support
On 05/10/11 12:36, Joseph S. Myers wrote: thanks for the review. I've addressed these issues, but will wait for arm-specific review before reposting (I presume you want the chance to check the non-mechanical opt-machinery changes) nathan -- Nathan Sidwell
Re: [PATCH, ARM] ISO/IEC TR 18037 fixed-point support
Julian Brown jul...@codesourcery.com writes: Tested with cross to ARM Linux. OK to apply? Just out of interest, are you able to test the patch on MIPS as well? I was wondering whether the fixed-point results there change after the target-independent parts of the patch. (I think MIPS is still the only port with in-tree fixed-point support.) Thanks, Richard
Re: [Patch, IRA] Fix a function accessing beyond end-of-array
* ira.c (clarify_prohibited_class_mode_regs): Prevent the function from accessing beyond the end of REGNO_REG_CLASS array by stopping the loop early. Just fine (the ChangeLog only of course, the patch is Vlad's), thanks. -- Eric Botcazou
Fix minor oversight in stack checking patch series
We don't need to initialize stack_check_probe_note in all cases now, but only if the mechanism is the generic one. Tested on i586-suse-linux, applied on the mainline as obvious. 2011-05-11 Eric Botcazou ebotca...@adacore.com * function.c (expand_function_start): Initialize stack_check_probe_note only if the generic stack checking mechanism is used. -- Eric Botcazou Index: function.c === --- function.c (revision 173643) +++ function.c (working copy) @@ -4813,9 +4813,8 @@ expand_function_start (tree subr) #endif } - /* After the display initializations is where the stack checking - probe should go. */ - if(flag_stack_check) + /* If we are doing generic stack checking, the probe should go here. */ + if (flag_stack_check == GENERIC_STACK_CHECK) stack_check_probe_note = emit_note (NOTE_INSN_DELETED); /* Make sure there is a line number after the function entry setup code. */
Re: [PATCH, ARM] ISO/IEC TR 18037 fixed-point support
On Wed, 11 May 2011, Julian Brown wrote: non-saturating variants where appropriate). Other functionality is provided by support functions in libgcc (type conversions, comparisons, and so on). Although more efficient versions of some of these could be implemented inline, it seems to me they would mostly use regular integer operations: I'm not at all sure that building that into each target rather than teaching generic code how to do it is a sensible way to go. Indeed, the original fixed-point code seems rather badly thought out in that way. Ideally you wouldn't have special machine modes at all; you'd have extra operations on ordinary modes, and some GIMPLE pass, or expand at the latest, would lower operations on fixed-point types into operations on ordinary types. (You'd want appropriate representations in GIMPLE for e.g. saturating operations, see PR 48580; in addition to basic saturating operations, multiplication on fixed-point types corresponds to multiply/shift on generic types.) I think that would do a better job of making instruction set features available to C code - ordinary C code using existing C idioms for saturation or overflow checks in some cases, rather than just code using these special extensions - where appropriate descriptions have been added to the target. But it's certainly a lot more work. There's currently no support for long long fixed-point types, since those imply support for TImode arithmetic, which isn't sensible on ARM. I've modified tests to make optional the requirement for long long support. I wonder how those tests work, or don't work, on 32-bit MIPS, which ought to have the same issue * optabs.c (prepare_cmp_insn): Use correct biasing for fixed-point comparison helpers. * final.c (output_addr_const): Print fixed-point constants as decimal not hex (avoiding an assembler overflow warning for negative byte constants). * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Support FIXED_CST. * config/fixed-bit.h (fixed-bit-machine.h): Include. (DECORATE_FIXED_NAME): Conditionally define if undefined. Use throughout file to decorate function names. * config/fixed-bit-mach-generic.h: New. It might make sense to send the machine-independent parts separately, under a separate subject heading, with an explanation for why each bit is needed. libgcc/ * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*) (arm*-*-nucleuseabi*, arm*-*-symbianelf*): Add arm/t-fixed-point The arm*-*-nucleuseabi* reference seems bogus. +/* Return TRUE if fixed-point operations are supported. */ + +bool +arm_fixed_point_supported_p (void) +{ + /* At least some operations helpful for fixed-point support are available + from arch3m onwards -- 32 bit x 32 bit - 64 bit multiplies. There's not + much point in arbitrarily restricting fixed-point support to particular + architecture versions though since gaps can be filled by libcalls, so + return TRUE unconditionally. */ + return true; +} Is there a reason for having a separate function, rather than just using hook_bool_void_true (with this comment going on the definition of TARGET_FIXED_POINT_SUPPORTED_P)? I don't see any change to the code in gcc/configure.ac that handles --enable-fixed-point to know that ARM targets now support it. Since the default hook returns ENABLE_FIXED_POINT, maybe if you fixed the configure test you wouldn't need to define the hook for ARM at all diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 40ebf35..8a1dd76 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -10751,3 +10751,5 @@ (include neon.md) ;; Synchronization Primitives (include sync.md) +;; Fixed-point patterns +(include arm-fixed.md) Should MD_INCLUDES in t-arm be updated? diff --git a/gcc/config/arm/fixed-bit-machine.h b/gcc/config/arm/fixed-bit-machine.h new file mode 100644 index 000..c7ce8ec --- /dev/null +++ b/gcc/config/arm/fixed-bit-machine.h @@ -0,0 +1,29 @@ +/* Machine-specific override for fixed-point support routine names. + Copyright (C) 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public
Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
On Thu, Mar 10, 2011 at 8:23 PM, Nathan Froyd froy...@codesourcery.com wrote: Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR. Nothing to see here. -Nathan gcc/ * tree.def (CASE_LABEL_EXPR): Add an operand. * tree.h (CASE_CHAIN): Use TREE_OPERAND instead of TREE_CHAIN. This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48965 This failure is kind of random. We may have some invalid memory access. -- H.J.
[PATCH, i386]: Cleanup TARGET_GNU2_TLS usage
Hello! Attached patch cleans legitimize_tls_address and corresponding expanders to call gen_tls_dynamic_gnu2_{32,64} directly in case of TARGET_GNU2_TLS target. The patch also changes unique REG_EQUIV note to __tls_get_addr call to UNSPEC (the same approach MIPS does) instead of some strange nested EXPR_LISTs. Additionally, ix86_tls_get_address is now used only in i386.c, so it can be declared static. The patch does not introduce any functional change, leaving also previous ICE on 64bit targets with -mcmodel=large and -mtls-dialect=gnu: tls.c:6:1: error: unrecognizable insn: (call_insn/u 5 4 6 3 (parallel [ (set (reg:DI 0 ax) (call:DI (mem:QI (symbol_ref:DI (__tls_get_addr)) [0 S1 A8]) (const_int 0 [0]))) (unspec:DI [ (symbol_ref:DI (tls_gd) [flags 0x12] var_decl 0x7f3846c08000 tls_gd) ] UNSPEC_TLS_GD) ]) tls.c:5 -1 (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (nil)) The test (tls.c), used to check all TLS models is attached to the message. I plan to convert it to proper dg test... ;) 2011-05-11 Uros Bizjak ubiz...@gmail.com * config/i386/i386.c (legitimize_tls_address) TLS_MODEL_GLOBAL_DYNAMIC: Call gen_tls_dynamic_gnu2_{32,64} expanders directly for TARGET_GNU2_TLS. Determine pic and __tls_get_addr symbol reference here. Update call to gen_tls_global_dynamic_{32,64} for added arguments. TLS_MODEL_LOCAL_DYNAMIC: Call gen_tls_dynamic_gnu2_{32,64} expanders directly for TARGET_GNU2_TLS. Determine __tls_get_addr symbol reference here. Update call to gen_tls_local_dynamic_base_{32,64} for added arguments. Attach unique UNSPEC REG_EQUIV to libcall block. (ix86_tls_get_addr): Declare static. * config/i386/i386-protos.h (ix86_tls_get_addr): Remove declaration. * config/i386/i386.md (tls_global_dynamic_32): Add operand 2 and 3. Do not determine pic and __tls_get_addr symbol reference here. Do not call gen_tls_dynamic_gnu2_32 for TARGET_GNU2_TLS. (tls_local_dynamic_base_32): Ditto for operands 1 and 2. (tls_global_dynamic_64): Add operand 2. Do not determine __tls_get_addr symbol reference here. Do not call gen_tls_dynamic_gnu2_64 for TARGET_GNU2_TLS here. (tls_local_dynamic_base64): Ditto for operand 1. Patch was tested on x86_64-pc-linux-gnu {,-m32} and committed to mainline SVN. Uros. Index: i386.md === --- i386.md (revision 173620) +++ i386.md (working copy) @@ -12555,30 +12555,13 @@ (define_expand tls_global_dynamic_32 [(parallel [(set (match_operand:SI 0 register_operand ) (unspec:SI - [(match_dup 2) + [(match_operand:SI 2 register_operand ) (match_operand:SI 1 tls_symbolic_operand ) -(match_dup 3)] +(match_operand:SI 3 call_insn_operand )] UNSPEC_TLS_GD)) (clobber (match_scratch:SI 4 )) (clobber (match_scratch:SI 5 )) - (clobber (reg:CC FLAGS_REG))])] - -{ - if (flag_pic) -operands[2] = pic_offset_table_rtx; - else -{ - operands[2] = gen_reg_rtx (Pmode); - emit_insn (gen_set_got (operands[2])); -} - if (TARGET_GNU2_TLS) -{ - emit_insn (gen_tls_dynamic_gnu2_32 - (operands[0], operands[1], operands[2])); - DONE; -} - operands[3] = ix86_tls_get_addr (); -}) + (clobber (reg:CC FLAGS_REG))])]) (define_insn *tls_global_dynamic_64 [(set (match_operand:DI 0 register_operand =a) @@ -12593,19 +12576,11 @@ (define_expand tls_global_dynamic_64 [(parallel [(set (match_operand:DI 0 register_operand ) - (call:DI (mem:QI (match_dup 2)) (const_int 0))) + (call:DI +(mem:QI (match_operand:DI 2 call_insn_operand )) +(const_int 0))) (unspec:DI [(match_operand:DI 1 tls_symbolic_operand )] -UNSPEC_TLS_GD)])] - -{ - if (TARGET_GNU2_TLS) -{ - emit_insn (gen_tls_dynamic_gnu2_64 - (operands[0], operands[1])); - DONE; -} - operands[2] = ix86_tls_get_addr (); -}) +UNSPEC_TLS_GD)])]) (define_insn *tls_local_dynamic_base_32_gnu [(set (match_operand:SI 0 register_operand =a) @@ -12622,28 +12597,12 @@ (define_expand tls_local_dynamic_base_32 [(parallel [(set (match_operand:SI 0 register_operand ) - (unspec:SI [(match_dup 1) (match_dup 2)] + (unspec:SI [(match_operand:SI 1 register_operand ) + (match_operand:SI 2 call_insn_operand )] UNSPEC_TLS_LD_BASE)) (clobber (match_scratch:SI 3 ))
Re: [patch gimplifier]: Boolify more strict conditional expressions and transform simple form to binary
2011/5/11 Richard Guenther richard.guent...@gmail.com: The most important thing is to get predicate types sane - that affects tcc_comparison codes and the TRUTH_* codes. After that, the TRUTH_* codes are redundant with the BIT_* ones which already are always validly typed. As fold already converts some TRUTH_* to BIT_* variants we usually have a mix of both which is not handled very well by tree optimizers. Well, to boolify comparisions isn't that hard at all, but I don't see here much improvement, as it will lead necessarily for uses without boolean-type always in gimple as '(type) comparison_tcc-ssa', which seems to me like trying to put the cart before the horse. So updated patch inlined (and attached). The type-casting for TRUTH_ANDIF/ORIF is still necessary (without it I get bootstrap failures due perfectly working gimple_cond_expr function, which is producing here happily iftmp variables assigning later on wrong type. Regards, Kai Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-11 17:03:24.853377700 +0200 +++ gcc/gcc/gimplify.c 2011-05-11 17:11:02.018281300 +0200 @@ -2824,9 +2824,6 @@ gimple_boolify (tree expr) } } - if (TREE_CODE (type) == BOOLEAN_TYPE) -return expr; - switch (TREE_CODE (expr)) { case TRUTH_AND_EXPR: @@ -2851,6 +2848,8 @@ gimple_boolify (tree expr) default: /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return expr; return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -6762,6 +6761,21 @@ gimplify_expr (tree *expr_p, gimple_seq case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: + { + tree org_type = TREE_TYPE (*expr_p); + + *expr_p = gimple_boolify (*expr_p); + + /* This shouldn't happen, but due fold-const (and here especially + fold_truth_not_expr) happily uses operand type and doesn't + automatically uses boolean_type as result, this happens. */ + if (TREE_CODE (org_type) != BOOLEAN_TYPE) + { + *expr_p = fold_convert (org_type, *expr_p); + ret = GS_OK; + break; + } + } /* Pass the source location of the outer expression. */ ret = gimplify_boolean_expr (expr_p, saved_location); break; @@ -7203,6 +7217,22 @@ gimplify_expr (tree *expr_p, gimple_seq case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: + { + tree org_type = TREE_TYPE (*expr_p); + + *expr_p = gimple_boolify (*expr_p); + + /* This shouldn't happen, but due fold-const (and here especially + fold_truth_not_expr) happily uses operand type and doesn't + automatically uses boolean_type as result, this happens. */ + if (TREE_CODE (org_type) != BOOLEAN_TYPE) + { + *expr_p = fold_convert (org_type, *expr_p); + ret = GS_OK; + break; + } + } + /* Classified as tcc_expression. */ goto expr_2; Index: gcc/gcc/tree-cfg.c === --- gcc.orig/gcc/tree-cfg.c 2011-05-11 17:03:24.863377700 +0200 +++ gcc/gcc/tree-cfg.c 2011-05-11 17:04:32.293292500 +0200 @@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: { - /* We allow any kind of integral typed argument and result. */ - if (!INTEGRAL_TYPE_P (rhs1_type) - || !INTEGRAL_TYPE_P (rhs2_type) - || !INTEGRAL_TYPE_P (lhs_type)) + /* We allow only boolean typed argument and result. */ + if (TREE_CODE (rhs1_type) != BOOLEAN_TYPE + || TREE_CODE (rhs2_type) != BOOLEAN_TYPE + || TREE_CODE (lhs_type) != BOOLEAN_TYPE) { error (type mismatch in binary truth expression); debug_generic_expr (lhs_type); Index: gcc/gcc/gimplify.c === --- gcc.orig/gcc/gimplify.c 2011-05-10 15:44:49.0 +0200 +++ gcc/gcc/gimplify.c 2011-05-10 15:46:58.365473600 +0200 @@ -4710,6 +4716,7 @@ gimplify_boolean_expr (tree *expr_p, loc { /* Preserve the original type of the expression. */ tree type = TREE_TYPE (*expr_p); + *expr_p = gimple_boolify (*expr_p); *expr_p = build3 (COND_EXPR, type, *expr_p, fold_convert_loc (locus, type, boolean_true_node), @@ -6762,6 +6769,13 @@ gimplify_expr (tree *expr_p, gimple_seq case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: + if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE) + { + tree type = TREE_TYPE (*expr_p); +
Re: [Patch,AVR]: Fix PR27663
Denis Chertykov schrieb: 2011/5/2 Georg-Johann Lay a...@gjlay.de: This is a fix for an optimization flaw when a long value is composed from byte values. For -fsplit-wide-types (which is still default for avr) the code is worse than with -fno-split-wide-types. The code for the test case is better in either situations, i.e. compared to code without the patch, but it is still not optimal. Fixing this by some combine patterns is the only thing the BE can do. I did not write more complex patterns because things get too complex with little performance gain. Tested without regressions. Johann 2011-05-02 Georg-Johann Lay a...@gjlay.de PR target/27663 * config/avr/predicates.md (const_8_16_24_operand): New predicate. * config/avr/avr.md (*iormodeqi.byte0, *iormodeqi.byte1-3): New define_insn_and_split patterns. I'm sorry, but I dot'n like to have a both combiner related patches in port because code improvement isn't much and your patterns are difficult to understand and maintain. May be somebody else have a different oppinion ? I'm open to discussion. Denis. Let me add that the patch is generic enough to also improve ORing HI against QI like described in http://gcc.gnu.org/PR41076 which is not uncommon on avr. Johann
[PATCH] Fix ICE in use_narrower_mode (PR debug/48967)
Hi! My http://gcc.gnu.org/ml/gcc-patches/2010-03/msg01379.html debug info optimization (meant primarily for x86_64) as the following testcase shows unfortunately breaks on powerpc64-linux and can in theory everywhere where lowpart_subreg of some REG accepted by use_narrower_mode_test isn't valid and thus returns NULL. This patch fixes it by not optimizing if the SUBREG isn't valid. Bootstrapped/regtested on x86_64-linux and i686-linux (where it never hits though) and on the testcase on powerpc64-linux. Ok for trunk/4.6? 2011-05-11 Jakub Jelinek ja...@redhat.com PR debug/48967 * var-tracking.c (use_narrower_mode_test) case REG: Return 1 if validate_subreg fails. * g++.dg/opt/pr48967.C: New test. --- gcc/var-tracking.c.jj 2011-05-11 19:39:04.0 +0200 +++ gcc/var-tracking.c 2011-05-11 19:51:48.0 +0200 @@ -745,6 +745,10 @@ use_narrower_mode_test (rtx *loc, void * case REG: if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode)) return 1; + if (!validate_subreg (GET_MODE (subreg), GET_MODE (*loc), + *loc, subreg_lowpart_offset (GET_MODE (subreg), +GET_MODE (*loc + return 1; return -1; case PLUS: case MINUS: --- gcc/testsuite/g++.dg/opt/pr48967.C.jj 2011-05-11 19:52:56.0 +0200 +++ gcc/testsuite/g++.dg/opt/pr48967.C 2011-05-11 19:52:27.0 +0200 @@ -0,0 +1,98 @@ +// PR debug/48967 +// { dg-do compile } +// { dg-options -g -O2 } + +template typename struct A; +template typename T struct A T * +{ + typedef T ref; +}; +template typename T, typename struct B +{ + typedef A T t; + typedef typename t::ref ref; + ref operator * () { return ref (); } +}; +template typename T struct I +{ + typedef T *cp; + template typename T1 struct J + { +typedef I T1 other; + }; +}; +template typename T struct S : public I T +{ +}; +template typename T, typename _A struct E +{ + typedef typename _A::template J T::other at; +}; +template typename T, typename _A = S T struct D +{ + typedef E T, _A _Base; + typedef typename _Base::at at; + typedef typename at::cp cp; + typedef B cp, D H; +}; +template class T struct F +{ + T *operator - () { return __null; } +}; +template typename T long +lfloor (T x) +{ + return static_cast long(x) - (x x != static_cast long(x)); +} +template typename T long +lround (T x) +{ + return lfloor (x - 0.5) + 1; +} +class M; +template typename class P; +typedef P M Q; +template typename struct P +{ + float x (); +}; +struct CV +{ + Q c; +}; +struct C +{ + void foo (const CV ) const; + class O; + typedef D F O R; + R n; +}; +struct S3 +{ + S3 (int, int); +}; +struct S2 +{ + S3 sx, sy; + S2 (int x = 0, int y = 0, int s = 0, int t = 0) : sx (x, y), sy (s, t) {} +}; +template typename struct N +{ + int bar (); +}; +struct C::O +{ + N float o; + void foo (CV r, int) + { +Q c = r.c; +float t = 0.5 * (o.bar ()); +S2 (lround (c.x ()), t); + } +}; +void +C::foo (const CV w) const +{ + R::H m; + (*m)-foo (w, 8); +} Jakub
Re: [Patch, IRA] Fix a function accessing beyond end-of-array
On 05/11/2011 10:07 AM, Hari Sandanagobalane wrote: Hello, I discussed this problem with Vlad in http://gcc.gnu.org/ml/gcc/2011-05/msg00131.html. I propose the following patch to fix it. Okay to commit? Revised the ChangeLog. Thanks Hari ChangeLog: * ira.c (clarify_prohibited_class_mode_regs): Prevent the function from accessing beyond the end of REGNO_REG_CLASS array by stopping the loop early. Patch: Index: gcc/ira.c === --- gcc/ira.c (revision 173654) +++ gcc/ira.c (working copy) @@ -1422,6 +1422,12 @@ if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) continue; nregs = hard_regno_nregs[hard_regno][j]; + if (hard_regno + nregs = FIRST_PSEUDO_REGISTER) I think it should be '' not '=' With this change, the patch is ok. Thanks for the patch. +{ + SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], +hard_regno); + continue; +} pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; for (nregs-- ;nregs = 0; nregs--) if (((enum reg_class) pclass
Re: [PATCH, SMS 2/3] Skip DEBUG_INSNs while recognizing doloop
On May 8, 2011, Revital Eres revital.e...@linaro.org wrote: +if (reg_mentioned_p (reg, insn) !DEBUG_INSN_P (insn)) It probably makes sense to test for !DEBUG_INSN_P first, since it's much cheaper. -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer
[4.6,trunk,rx] avoid LABEL_NUSES on barriers
Occasionally, gcc passes a barrier instead of a label. This accomodates such an event. Applies to 4.6 and trunk, and needed on both to build newlib. Ok? * config/rx/rx.c (rx_align_for_label): Don't test for LABEL_NUSES on a barrier. Index: gcc/config/rx/rx.c === --- gcc/config/rx/rx.c (revision 173669) +++ gcc/config/rx/rx.c (working copy) @@ -2755,13 +2755,13 @@ int rx_align_for_label (rtx lab, int uses_threshold) { /* This is a simple heuristic to guess when an alignment would not be useful because the delay due to the inserted NOPs would be greater than the delay due to the misaligned branch. If uses_threshold is zero then the alignment is always useful. */ - if (LABEL_NUSES (lab) uses_threshold) + if (LABEL_P (lab) LABEL_NUSES (lab) uses_threshold) return 0; return optimize_size ? 1 : 3; } static int
[PATCH] fix PR middle-end/48965, CASE_CHAIN fallout
The comment for pointer_map_traverse says: /* Pass each pointer in PMAP to the function in FN, together with the pointer to the value and the fixed parameter DATA. If FN returns false, the iteration stops. */ However, the code in tree-cfg:edge_to_cases_cleanup does: static bool edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value, void *data ATTRIBUTE_UNUSED) { tree t, next; for (t = (tree) *value; t; t = next) { next = CASE_CHAIN (t); CASE_CHAIN (t) = NULL; } *value = NULL; return false; } ... pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL); which means that we're only cleaning up one of the case chains stored in EDGE_TO_CASES. Since it's a pointer_map, we can potentially get different chains selected each time. Under -fcompare-debug, this leads to problems later on when we walk the function body and collect all the DECLs referenced therein; we might walk non-NULL CASE_CHAINs and reach more DECLs, depending on the memory layout. This wouldn't have shown up previously, since TREE_CHAIN was used, and we wouldn't walk TREE_CHAIN of expressions to find DECLs. The fix is simple: return true from the above function! I've added logic to verify_expr to catch this sort of thing. Tested on x86_64-unknown-linux-gnu. OK to commit? -Nathan gcc/ PR middle-end/48965 * tree-cfg.c (edge_to_cases_cleanup): Return true. (verify_expr) [CASE_LABEL_EXPR]: Add checking. diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index e1f8707..e2e84a2 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -843,7 +843,7 @@ edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value, } *value = NULL; - return false; + return true; } /* Start recording information mapping edges to case labels. */ @@ -2830,6 +2830,14 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) *walk_subtrees = 0; break; +case CASE_LABEL_EXPR: + if (CASE_CHAIN (t)) + { + error (invalid CASE_CHAIN); + return t; + } + break; + default: break; }
Re: [PATCH] Fix up typed DWARF stack support for POINTERS_EXTEND_UNSIGNED targets (PR debug/48853)
On Thu, May 5, 2011 at 2:20 AM, Jakub Jelinek ja...@redhat.com wrote: Hi! My typed DWARF stack changes apparently broke ia64-hpux and H.J.'s out of tree x32 target. There are several issues: 1) for SUBREG mem_loc_descriptor's 3rd argument was wrong, found by code inspection 2) CONST/SYMBOL_REF/LABEL_REF when in MEM addresses on POINTERS_EXTEND_UNSIGNED targets are often Pmode, which is unfortunately larger than DWARF2_ADDR_SIZE and my conditional would just return NULL in that case instead of emitting DW_OP_addr. 3) and, when mem_loc_descriptor is called from unwind code, Pmodes larger than DWARF2_ADDR_SIZE would result in the new DW_OP_GNU_*_type etc. ops which are not allowed in .eh_frame/.debug_frame The following patch ought to fix that, bootstrapped/regtested on x86_64-linux and i686-linux and Steve tested it on ia64-hpux and H.J. on his port. Ok for trunk? 2011-05-05 Jakub Jelinek ja...@redhat.com PR debug/48853 * dwarf2out.c (mem_loc_descriptor) case SUBREG: Pass mem_mode instead of mode as 3rd argument to recursive call. (mem_loc_descriptor) case REG: If POINTERS_EXTEND_UNSIGNED, don't emit DW_OP_GNU_regval_type if mode is Pmode and mem_mode is not VOIDmode. (mem_loc_descriptor) case SYMBOL_REF: If POINTERS_EXTEND_UNSIGNED, don't give up if mode is Pmode and mem_mode is not VOIDmode. (mem_loc_descriptor) case CONST_INT: If POINTERS_EXTEND_UNSIGNED, use int_loc_descriptor if mode is Pmode and mem_mode is not VOIDmode. Another problem. This patch http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01730.html has @@ -14562,7 +15110,10 @@ loc_descriptor (rtx rtl, enum machine_mo up an entire register. For now, just assume that it is legitimate to make the Dwarf info refer to the whole register which contains the given subreg. */ - loc_result = loc_descriptor (SUBREG_REG (rtl), mode, initialized); + if (REG_P (SUBREG_REG (rtl)) subreg_lowpart_p (rtl)) + loc_result = loc_descriptor (SUBREG_REG (rtl), mode, initialized); + else + goto do_default; break; case REG: It doesn't work with Pmode != ptr_mode. I got Breakpoint 5, loc_descriptor (rtl=0x70acc900, mode=SImode, initialized=VAR_INIT_STATUS_INITIALIZED) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15027 15027 if ((REG_P (SUBREG_REG (rtl)) (gdb) bt #0 loc_descriptor (rtl=0x70acc900, mode=SImode, initialized=VAR_INIT_STATUS_INITIALIZED) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15027 #1 0x006dae2a in loc_descriptor (rtl=0x70a6c660, mode=SImode, initialized=VAR_INIT_STATUS_INITIALIZED) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15071 #2 0x006dbc69 in dw_loc_list_1 (loc=0x70a87320, varloc=0x70a6c660, want_address=2, initialized=VAR_INIT_STATUS_INITIALIZED) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15346 #3 0x006dc5b2 in dw_loc_list (loc_list=0x70a6c800, decl=0x70a87320, want_address=2) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15602 #4 0x006dd920 in loc_list_from_tree (loc=0x70a87320, want_address=2) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15990 #5 0x006e3d81 in add_location_or_const_value_attribute ( die=0x70acd640, decl=0x70a87320, cache_p=0 '\000', attr=DW_AT_location) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:17500 #6 0x006eae13 in gen_formal_parameter_die (node=0x70a87320, origin=0x70b71d48, emit_name_p=1 '\001', context_die=0x70acd5a0) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:19244 #7 0x006f6432 in gen_decl_die (decl=0x70a87320, origin=0x0, ---Type return to continue, or q return to quit---q contextQuit (gdb) call debug_rtx (rtl) (subreg:SI (symbol_ref:DI (a) [flags 0x2] var_decl 0x70a87000 a) 0) (gdb) f 1 #1 0x006dae2a in loc_descriptor (rtl=0x70a6c660, mode=SImode, initialized=VAR_INIT_STATUS_INITIALIZED) at /export/gnu/import/git/gcc-x32/gcc/dwarf2out.c:15071 15071 loc_result = loc_descriptor (loc, mode, initialized); (gdb) call debug_rtx (rtl) (var_location x (subreg:SI (symbol_ref:DI (a) [flags 0x2] var_decl 0x70a87000 a) 0)) This patch restores the old behavior for Pmode. OK for trunk if there are no regressions? Thanks. -- H.J. 2011-05-11 H.J. Lu hongjiu...@intel.com PR debug/48853 * dwarf2out.c (loc_descriptor) case SUBREG: If POINTERS_EXTEND_UNSIGNED is defined, don't give up if mode of SUBREG is Pmode. 2011-05-11 H.J. Lu hongjiu...@intel.com PR debug/48853 * dwarf2out.c (loc_descriptor) case SUBREG: If POINTERS_EXTEND_UNSIGNED is defined, don't give up if mode of SUBREG is Pmode. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b85a55e..03d12de 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -15024,7
Go patch committed: Don't crash ranging over call to builtin function
This patch to the Go frontend fixes a compiler crash for code like for i, v := range append(a, b...) { } The problem is that for a case like this there are multiple pointers to the call expression, which interacts poorly with lowering in which the call expression is replaced. This patch papers over the problem. It's not a particularly clean fix but I can't think of any way that it will actually fail. The patch also includes a couple of minor cleanups. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r ddb4e0e9b3e8 go/expressions.cc --- a/go/expressions.cc Fri May 06 17:09:43 2011 -0700 +++ b/go/expressions.cc Wed May 11 11:38:53 2011 -0700 @@ -8527,9 +8527,9 @@ new_args-push_back(Expression::make_nil(loc)); // We can't return a new call expression here, because this one may - // be referenced by Call_result expressions. FIXME. - if (old_args != NULL) -delete old_args; + // be referenced by Call_result expressions. FIXME. We can't + // delete OLD_ARGS because we may have both a Call_expression and a + // Builtin_call_expression which refer to them. FIXME. this-args_ = new_args; this-varargs_are_lowered_ = true; @@ -9250,8 +9250,8 @@ error_at(location, invalid slice of map); return Expression::make_error(location); } - Map_index_expression* ret= Expression::make_map_index(left, start, - location); + Map_index_expression* ret = Expression::make_map_index(left, start, + location); if (this-is_lvalue_) ret-set_is_lvalue(); return ret; diff -r ddb4e0e9b3e8 go/statements.cc --- a/go/statements.cc Fri May 06 17:09:43 2011 -0700 +++ b/go/statements.cc Wed May 11 11:38:53 2011 -0700 @@ -4536,7 +4536,7 @@ else { this-report_error(_(range clause must have - array, slice, setring, map, or channel type)); + array, slice, string, map, or channel type)); return Statement::make_error_statement(this-location()); } @@ -4552,6 +4552,7 @@ { range_temp = Statement::make_temporary(NULL, this-range_, loc); temp_block-add_statement(range_temp); + this-range_ = NULL; } Temporary_statement* index_temp = Statement::make_temporary(index_type,
Re: pb_ds debug mode patch
Attached patch applied. 2011-05-11 François Dumont francois.cppd...@free.fr * include/ext/pb_ds/detail/resize_policy/ hash_load_check_resize_trigger_imp.hpp (assert_valid): Replace _GLIBCXX_DEBUG_ASSERT calls with PB_DS_DEBUG_VERIFY. * include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp, find_fn_imps.hpp, insert_fn_imps.hpp, binomial_heap_base_.hpp, constructors_destructor_fn_imps.hpp, split_join_fn_imps.hpp (PB_DS_ASSERT_VALID): Rename in PB_DS_ASSERT_VALID_COND. * include/ext/pb_ds/detail/debug_map_base.hpp, splay_tree_/splay_tree_.hpp, ov_tree_map_/ov_tree_map_.hpp, cc_hash_table_map_/cc_ht_map_.hpp, pat_trie_/pat_trie_.hpp, leaf.hpp, internal_node.hpp, gp_hash_table_map_/gp_ht_map_.hpp, bin_search_tree_/bin_search_tree_.hpp, list_update_map_/lu_map_.hpp, rb_tree_map_/rb_tree_.hpp (PB_DS_ASSERT_VALID, PB_DS_DEBUG_VERIFY, PB_DS_CHECK_KEY_EXISTS, PB_DS_CHECK_KEY_DOES_NOT_EXIST): Duplicate macro definitions move... * include/ext/pb_ds/detail/container_base_dispatch.hpp: ... here... * include/ext/pb_ds/detail/basic_tree_policy/traits.hpp: ... and here. * include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp, resize_policy.hpp, pairing_heap_/pairing_heap_.hpp, left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp, binomial_heap_/binomial_heap_.hpp, thin_heap_/thin_heap_.hpp, rc_binomial_heap_/rc_binomial_heap_.hpp, rc.hpp (PB_DS_ASSERT_VALID, PB_DS_DEBUG_VERIFY): Duplicate macro definitions move... * include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp: ...here. Regards On 05/11/2011 06:36 AM, Benjamin Kosnik wrote: Ok to commit ? Yes, thanks. Note that I just had a testsuite failure regarding pb_ds code that looks rather serious because it doesn't seem to come from pb_ds debug code: Pre-existing. -benjamin Index: include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp === --- include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp (revision 173552) +++ include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp (working copy) @@ -286,8 +286,8 @@ PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { - _GLIBCXX_DEBUG_ASSERT(m_load_max m_load_min); - _GLIBCXX_DEBUG_ASSERT(m_next_grow_size = m_next_shrink_size); + PB_DS_DEBUG_VERIFY(m_load_max m_load_min); + PB_DS_DEBUG_VERIFY(m_next_grow_size = m_next_shrink_size); } # undef PB_DS_DEBUG_VERIFY #endif Index: include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp === --- include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp (revision 173552) +++ include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp (working copy) @@ -43,7 +43,7 @@ PB_DS_CLASS_C_DEC:: pop() { - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) @@ -59,7 +59,7 @@ m_p_max = 0; - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC @@ -113,7 +113,7 @@ PB_DS_CLASS_C_DEC:: erase(point_iterator it) { - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::bubble_to_top(it.m_p_nd); @@ -124,7 +124,7 @@ m_p_max = 0; - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC @@ -133,11 +133,11 @@ PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) if (base_type::empty()) { - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) return 0; } @@ -185,7 +185,7 @@ m_p_max = 0; - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true) return ersd; } Index: include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp === --- include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp (revision 173552) +++ include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp (working copy) @@ -43,7 +43,7 @@ PB_DS_CLASS_C_DEC:: top() const { - PB_DS_ASSERT_VALID((*this),false) + PB_DS_ASSERT_VALID_COND((*this),false) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) Index: include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp === --- include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp (revision 173552) +++ include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp (working copy) @@ -43,7 +43,7 @@ PB_DS_CLASS_C_DEC:: push(const_reference r_val) { - PB_DS_ASSERT_VALID((*this),true) + PB_DS_ASSERT_VALID_COND((*this),true)
Re: [Patch, Fortran] PR 48889 - fix 4.6/4.7 regression: ICE in generics' resolution
On Wednesday 11 May 2011 15:20:38 Tobias Burnus wrote: As the PR shows, in the function the gfc_expr can be such that expr-value.function.esym points to the correct specific function but the generic expr-symtree-n.sym does not exist (expr-symtree == NULL). However, also the opposite can happen that only expr-symtree is set and neither esym nor isym is (yet) set. Build and regtested on x86-64-linux. OK for the trunk and 4.6? In the test, it should be cleanup-modules instead of cleanup-tree-dump. Ok with that change. Thanks. Mikael
Go patch committed: Permit calling new with a function type
The Go frontend incorrectly rejects calling new with a function type. That was a holdover from a long time ago, before function types were essentially pointers. This patch removes the unnecessary check. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r 2c65483561e2 go/expressions.cc --- a/go/expressions.cc Wed May 11 12:37:53 2011 -0700 +++ b/go/expressions.cc Wed May 11 12:46:50 2011 -0700 @@ -10624,9 +10624,6 @@ do_determine_type(const Type_context*) { } - void - do_check_types(Gogo*); - Expression* do_copy() { return new Allocation_expression(this-type_, this-location()); } @@ -10639,15 +10636,6 @@ Type* type_; }; -// Check the type of an allocation expression. - -void -Allocation_expression::do_check_types(Gogo*) -{ - if (this-type_-function_type() != NULL) -this-report_error(_(invalid new of function type)); -} - // Return a tree for an allocation expression. tree
C++ PATCH for c++/48745 (ICE with list-initialization in SFINAE context)
Here we just needed to handle CONSTRUCTOR in value_dependent_expression_p. It is also the case that a lot of crashes have been happening because build_non_dependent_expr calls null_ptr_cst_p, which wants to try to get a constant value for any expression. That's not actually necessary for semantics, so we can remove it. But it has been helpful for finding bugs, so I'm going to leave in the call to maybe_constant_value when ENABLE_CHECKING is defined. Tested x86_64-pc-linux-gnu, applying to trunk. commit 05a558e5467af165052855f290f11b20e7009450 Author: Jason Merrill ja...@redhat.com Date: Tue May 10 16:40:54 2011 -0400 PR c++/48745 * pt.c (value_dependent_expr_p): Handle CONSTRUCTOR. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5e24977..74d4cbf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18273,6 +18273,16 @@ value_dependent_expression_p (tree expression) type-dependent. */ return type_dependent_expression_p (expression); +case CONSTRUCTOR: + { + unsigned ix; + tree val; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), ix, val) + if (value_dependent_expression_p (val)) + return true; + return false; + } + default: /* A constant expression is value-dependent if any subexpression is value-dependent. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae22.C b/gcc/testsuite/g++.dg/cpp0x/sfinae22.C new file mode 100644 index 000..1c3efd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae22.C @@ -0,0 +1,23 @@ +// PR c++/48745 +// { dg-options -std=c++0x } + +templateclass T +struct add_rval_ref { + typedef T type; +}; + +template +struct add_rval_refvoid { + typedef void type; +}; + +templateclass T +typename add_rval_refT::type create(); + +templateclass T, class... Args +decltype(T{createArgs()...}, char()) f(int); + +templateclass, class... +char (f(...))[2]; + +static_assert(sizeof(fint, void(0)) != 1, Error); // # commit 98b2007f0a05f07cf79711c1d29cc228cb5e9946 Author: Jason Merrill ja...@redhat.com Date: Tue May 10 16:42:31 2011 -0400 * pt.c (build_non_dependent_expr): Don't check null_ptr_cst_p, do call maybe_constant_value in C++0x mode. * semantics.c (cxx_eval_constant_expression): Handle TEMPLATE_DECL. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 74d4cbf..4b32ce9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18871,10 +18871,13 @@ build_non_dependent_expr (tree expr) { tree inner_expr; - /* Preserve null pointer constants so that the type of things like - p == 0 where p is a pointer can be determined. */ - if (null_ptr_cst_p (expr)) -return expr; +#ifdef ENABLE_CHECKING + /* Try to get a constant value for all non-type-dependent expressions in + order to expose bugs in *_dependent_expression_p and constexpr. */ + if (cxx_dialect = cxx0x) +maybe_constant_value (fold_non_dependent_expr (expr)); +#endif + /* Preserve OVERLOADs; the functions must be available to resolve types. */ inner_expr = expr; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0ba0370..bfe233e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6911,6 +6911,7 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, break; case FUNCTION_DECL: +case TEMPLATE_DECL: case LABEL_DECL: return t;
C++ PATCH for c++/48948 (rejecting constexpr friend that takes the current class)
We want to allow a constexpr friend function that takes the current class, so we need to defer checking the literality of parameter types until any classes involved are complete. I broke the changes into a few different commits: 1) Only set DECL_DECLARED_CONSTEXPR_P in one place in grokdeclarator (so that it isn't re-set after validate_constexpr_fundecl clears it). 2) Add constexpr functions to the hash table when they're defined, not when they're declared. 3) Check DECL_TEMPLATE_INFO rather than DECL_TEMPLATE_INSTANTIATION when deciding whether to give an error for a function that doesn't satisfy the constexpr requirements. 4) Actually do the deferral, by deferring any function that we find to have a parameter type that's currently being defined and then trying again when we complete a class. Tested x86_64-pc-linux-gnu, applying to trunk. commit 63f5464dc11fef107096efbcf2a75ef3b792db57 Author: Jason Merrill ja...@redhat.com Date: Wed May 11 00:29:14 2011 -0400 * decl.c (grokdeclarator): Only set DECL_DECLARED_CONSTEXPR_P once. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index eff2360..ad816f1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9933,7 +9933,6 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } -DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p; decl = do_friend (ctype, unqualified_id, decl, *attrlist, flags, funcdef_flag); @@ -10183,8 +10182,11 @@ grokdeclarator (const cp_declarator *declarator, } } else if (constexpr_p DECL_EXTERNAL (decl)) - error (declaration of constexpr variable %qD is not a definition, -decl); + { + error (declaration of constexpr variable %qD is not a definition, + decl); + constexpr_p = false; + } } if (storage_class == sc_extern initialized !funcdef_flag) @@ -10213,8 +10215,8 @@ grokdeclarator (const cp_declarator *declarator, else if (storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; -/* Don't forget constexprness. */ -if (constexpr_p) +/* Set constexpr flag on vars (functions got it in grokfndecl). */ +if (constexpr_p TREE_CODE (decl) == VAR_DECL) DECL_DECLARED_CONSTEXPR_P (decl) = true; /* Record constancy and volatility on the DECL itself . There's commit 90613a6af841f2a8563c0669be47211c52a08d35 Author: Jason Merrill ja...@redhat.com Date: Wed May 11 00:31:29 2011 -0400 * semantics.c (register_constexpr_fundef): Add to hash table here. (validate_constexpr_fundecl): Not here. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bfe233e..e12f036 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5456,9 +5456,6 @@ is_valid_constexpr_fn (tree fun, bool complain) tree validate_constexpr_fundecl (tree fun) { - constexpr_fundef entry; - constexpr_fundef **slot; - if (processing_template_decl || !DECL_DECLARED_CONSTEXPR_P (fun)) return NULL; else if (DECL_CLONED_FUNCTION_P (fun)) @@ -5471,21 +5468,6 @@ validate_constexpr_fundecl (tree fun) return NULL; } - /* Create the constexpr function table if necessary. */ - if (constexpr_fundef_table == NULL) -constexpr_fundef_table = htab_create_ggc (101, - constexpr_fundef_hash, - constexpr_fundef_equal, - ggc_free); - entry.decl = fun; - entry.body = NULL; - slot = (constexpr_fundef **) -htab_find_slot (constexpr_fundef_table, entry, INSERT); - if (*slot == NULL) -{ - *slot = ggc_alloc_constexpr_fundef (); - **slot = entry; -} return fun; } @@ -5722,8 +5704,8 @@ constexpr_fn_retval (tree body) tree register_constexpr_fundef (tree fun, tree body) { - constexpr_fundef *fundef = retrieve_constexpr_fundef (fun); - gcc_assert (fundef != NULL fundef-body == NULL); + constexpr_fundef entry; + constexpr_fundef **slot; if (DECL_CONSTRUCTOR_P (fun)) body = build_constexpr_constructor_member_initializers @@ -5754,7 +5736,22 @@ register_constexpr_fundef (tree fun, tree body) require_potential_rvalue_constant_expression (body); return NULL; } - fundef-body = body; + + /* Create the constexpr function table if necessary. */ + if (constexpr_fundef_table == NULL) +constexpr_fundef_table = htab_create_ggc (101, + constexpr_fundef_hash, + constexpr_fundef_equal, + ggc_free); + entry.decl = fun; + entry.body = body; + slot = (constexpr_fundef **) +htab_find_slot (constexpr_fundef_table, entry, INSERT); + + gcc_assert (*slot == NULL); + *slot =
[rx] simulated conditional exec
This adds a simulated conditional execution option to the RX backend. The RX can do a short conditional forward branch faster than a regular conditional branch (1 byte, 1 cycle!), as long as it's only branching across one or two insns. This patch encourages this behavior via the condexec support, and gives a 1% performance improvement. The patch is against 4.6 but applies to trunk also. Ok? * config/rx/rx.opt (mcondexec): New. * config/rx/rx-protos.h (rx_condexec_prescan): Declare. * config/rx/rx.md (predicable): New. (define_cond_exec): New. (define_asm_attributes): New. (pop_and_return): Manually call rx_condexec_prescan() (*movregister_modes:mode_internal): Likewise. (extendsmall_int_modes:modesi2): Likewise. (zero_extendsmall_int_modes:modesi2): Likewise. (stack_pushm): Likewise. (stack_popm): Likewise. (*stcc): Likewise. (*insv_imm): Likewise. * config/rx/rx.c (TARGET_DEFAULT_TARGET_FLAGS): New. (rx_print_operand): Add %b for a reversed conditional. (rx_condexec_prescan): New. (TARGET_ASM_FINAL_POSTSCAN_INSN): Define. (rx_final_postscan): New. Index: gcc/config/rx/rx-protos.h === --- gcc/config/rx/rx-protos.h (revision 173670) +++ gcc/config/rx/rx-protos.h (working copy) @@ -28,6 +28,7 @@ extern voidrx_expand_prologue (void); extern int rx_initial_elimination_offset (int, int); +extern voidrx_condexec_prescan (void); #ifdef RTX_CODE extern int rx_align_for_label (rtx, int); Index: gcc/config/rx/rx.md === --- gcc/config/rx/rx.md (revision 173670) +++ gcc/config/rx/rx.md (working copy) @@ -135,6 +135,21 @@ ;; +(define_attr predicable no,yes (const_string yes)) + +(define_cond_exec + [(match_operator 0 comparison_operator + [(reg CC_REG) (const_int 0)])] + TARGET_CONDEXEC + b%b0 1f ! + ) + +(define_asm_attributes + [(set_attr predicable no)] + ) + +;; + ;; Comparisons ;; Note - we do not specify the two instructions necessary to perform @@ -364,6 +379,7 @@ (return)] reload_completed { +rx_condexec_prescan (); rx_emit_stack_popm (operands, false); return ; } @@ -567,7 +583,9 @@ (match_operand:register_modes 1 general_operand Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i))] - { return rx_gen_move_template (operands, false); } + { +rx_condexec_prescan (); +return rx_gen_move_template (operands, false); } [(set_attr length 3,4,5,6,2,4,6,5,6,7,8) (set_attr timings 11,11,11,11,11,12,11,11,11,11,11)] ) @@ -577,7 +595,8 @@ (sign_extend:SI (match_operand:small_int_modes 1 nonimmediate_operand r,m)))] - { return rx_gen_move_template (operands, false); } + { rx_condexec_prescan (); +return rx_gen_move_template (operands, false); } [(set_attr length 2,6) (set_attr timings 11,12)] ) @@ -587,7 +606,8 @@ (zero_extend:SI (match_operand:small_int_modes 1 nonimmediate_operand r,m)))] - { return rx_gen_move_template (operands, true); } + { rx_condexec_prescan (); +return rx_gen_move_template (operands, true); } [(set_attr length 2,4) (set_attr timings 11,12)] ) @@ -610,6 +630,7 @@ (match_operand:SI 0 const_int_operand n)))])] reload_completed { +rx_condexec_prescan (); rx_emit_stack_pushm (operands); return ; } @@ -636,6 +657,7 @@ (match_operand:SI 0 const_int_operand n)))])] reload_completed { +rx_condexec_prescan (); rx_emit_stack_popm (operands, true); return ; } @@ -770,6 +792,7 @@ (match_dup 0)))] reload_completed { + rx_condexec_prescan (); if (GET_CODE (operands[2]) == EQ) return stz\t%1, %0; else @@ -1833,6 +1856,7 @@ (match_operand:SI 2 const_int_operand ))] { + rx_condexec_prescan (); if (INTVAL (operands[2]) 1) return bset\t%1, %0; else Index: gcc/config/rx/rx.c === --- gcc/config/rx/rx.c (revision 173670) +++ gcc/config/rx/rx.c (working copy) @@ -385,6 +385,7 @@ %A Print an operand without a leading # character. %B Print an integer comparison name. + %b Print an integer comparison name, reversed. %C Print a control register name. %F Print a condition code flag name. %H Print high part of a DImode register, integer or address. @@ -499,7 +500,85 @@ fputs (ret, file); break; } +case 'b': + { + enum rtx_code code = GET_CODE (op); + enum
Re: [PATCH][4/n] Cleanup LTO type merging
This removes the mode param from the generic type merging machinery and simplifies code accordingly. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Hi, looks the cleanup series makes a progress, now I get 459s for Mozilla WPA (it was 540 last time I tried). Out of that 262s is still ipa lto decl in. oprofile is as follows: 123230 20.1719 lto1 htab_find_slot_with_hash 58203 9.5274 lto1 gimple_type_eq 50017 8.1874 lto1 iterative_hash_hashval_t 40099 6.5639 libc-2.11.1.so _int_malloc 24792 4.0583 libc-2.11.1.so memset 22604 3.7001 lto1 gtc_visit 18746 3.0686 lto1 lto_input_tree 17962 2.9403 lto1 type_pair_eq 17560 2.8744 lto1 gimple_type_hash 16383 2.6818 lto1 gt_ggc_mx_lang_tree_node 15485 2.5348 lto1 ggc_set_mark 12617 2.0653 lto1 inflate_fast Honza
[Patch, Fortran] PR 48961 - Fix EXECUTE_COMMAND_LINE w/ wait=.false. for non-fork systems
The attached patch fixes three issues: a) If fork() is not supported, CMDSTAT is -2 (as required by the standard) - and everything is executed synchronously. However, set_cmdstat will abort if the cmdstat value is not 0. b) The cmdstat value should be set to an error if system returns an error (-1) -- also for WAIT=.false. c) In the synchronous case with WAIT=.false. the EXITSTAT= value was not set. Additionally, I converted some literals to the EXEC_* enum values. Build on x86-64-linux. OK for the trunk? Tobias PS: The next step would be to add support for asynchronous execution under Windows, cf. PR. 2011-05-12 Tobias Burnus bur...@net-b.de PR fortran/48961 * intrinsics/execute_command_line.c (set_cmdstat): Don't abort if synchronously executing with WAIT=.false. (execute_command_line): Fix setting of cmdstat and exitstat. diff --git a/libgfortran/intrinsics/execute_command_line.c b/libgfortran/intrinsics/execute_command_line.c index 4e3c445..d0b79a4 100644 --- a/libgfortran/intrinsics/execute_command_line.c +++ b/libgfortran/intrinsics/execute_command_line.c @@ -38,9 +38,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif -enum { EXEC_NOERROR = 0, EXEC_SYSTEMFAILED }; +enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED, + EXEC_CHILDFAILED }; static const char *cmdmsg_values[] = - { , Execution of child process impossible }; + { , +Termination status of the command-language interpreter cannot be obtained, +Execution of child process impossible }; @@ -49,7 +52,7 @@ set_cmdstat (int *cmdstat, int value) { if (cmdstat) *cmdstat = value; - else if (value != 0) + else if (value EXEC_NOERROR) runtime_error (Could not execute command line); } @@ -74,10 +77,10 @@ execute_command_line (const char *command, bool wait, int *exitstat, /* Asynchronous execution. */ pid_t pid; - set_cmdstat (cmdstat, 0); + set_cmdstat (cmdstat, EXEC_NOERROR); if ((pid = fork()) 0) - set_cmdstat (cmdstat, EXEC_SYSTEMFAILED); + set_cmdstat (cmdstat, EXEC_CHILDFAILED); else if (pid == 0) { /* Child process. */ @@ -91,13 +94,15 @@ execute_command_line (const char *command, bool wait, int *exitstat, /* Synchronous execution. */ int res = system (cmd); - if (!wait) - set_cmdstat (cmdstat, -2); - else if (res == -1) + if (res == -1) set_cmdstat (cmdstat, EXEC_SYSTEMFAILED); + else if (!wait) + set_cmdstat (cmdstat, EXEC_SYNCHRONOUS); else + set_cmdstat (cmdstat, EXEC_NOERROR); + + if (res != -1) { - set_cmdstat (cmdstat, 0); #if defined(WEXITSTATUS) defined(WIFEXITED) *exitstat = WIFEXITED(res) ? WEXITSTATUS(res) : res; #else @@ -107,7 +112,7 @@ execute_command_line (const char *command, bool wait, int *exitstat, } /* Now copy back to the Fortran string if needed. */ - if (cmdstat *cmdstat 0) + if (cmdstat *cmdstat EXEC_NOERROR) { if (cmdmsg) fstrcpy (cmdmsg, cmdmsg_len, cmdmsg_values[*cmdstat],
[v3] Tweak to testcases
Hi, I committed this small tweak to two recent testcases of mine. Paolo. // 2011-05-11 Paolo Carlini paolo.carl...@oracle.com * testsuite/26_numerics/headers/cmath/overloads_c++0x_neg.cc: Use dg-require-cmath. * testsuite/tr1/8_c_compatibility/cmath/overloads_neg.cc: Likewise. Index: testsuite/26_numerics/headers/cmath/overloads_c++0x_neg.cc === --- testsuite/26_numerics/headers/cmath/overloads_c++0x_neg.cc (revision 173683) +++ testsuite/26_numerics/headers/cmath/overloads_c++0x_neg.cc (working copy) @@ -1,5 +1,6 @@ -// { dg-options -std=gnu++0x } // { dg-do compile } +// { dg-options -std=gnu++0x } +// { dg-require-cmath } // Copyright (C) 2011 Free Software Foundation, Inc. // @@ -22,8 +23,6 @@ // libstdc++/48933 -#ifdef _GLIBCXX_USE_C99_MATH_TR1 - struct Foo { }; template Foo std::atan2Foo, Foo(Foo, Foo); // { dg-error not match } @@ -61,5 +60,3 @@ template Foo std::scalbnFoo(Foo, int); // { dg-error not match } template Foo std::tgammaFoo(Foo); // { dg-error not match } template Foo std::truncFoo(Foo); // { dg-error not match } - -#endif Index: testsuite/tr1/8_c_compatibility/cmath/overloads_neg.cc === --- testsuite/tr1/8_c_compatibility/cmath/overloads_neg.cc (revision 173683) +++ testsuite/tr1/8_c_compatibility/cmath/overloads_neg.cc (working copy) @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-require-cmath } // Copyright (C) 2011 Free Software Foundation, Inc. // @@ -23,8 +24,6 @@ // libstdc++/48933 -#ifdef _GLIBCXX_USE_C99_MATH_TR1 - struct Foo { }; template Foo std::tr1::atan2Foo, Foo(Foo, Foo); // { dg-error not match } @@ -62,5 +61,3 @@ template Foo std::tr1::scalbnFoo(Foo, int); // { dg-error not match } template Foo std::tr1::tgammaFoo(Foo); // { dg-error not match } template Foo std::tr1::truncFoo(Foo); // { dg-error not match } - -#endif
Re: [PATCH] split tree_type, a.k.a. tuplifying types
I'm checking this in to fix build with --enable-gather-detailed-mem-stats. Jason commit 091ac850cf8830722c9bae83232f0d95ccd45b2a Author: Jason Merrill ja...@redhat.com Date: Wed May 11 21:36:09 2011 -0400 * tree.c (type_hash_canon): Use struct tree_type_non_common. diff --git a/gcc/tree.c b/gcc/tree.c index c38d24b..3357d84 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6217,7 +6217,7 @@ type_hash_canon (unsigned int hashcode, tree type) #ifdef GATHER_STATISTICS tree_code_counts[(int) TREE_CODE (type)]--; tree_node_counts[(int) t_kind]--; - tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type); + tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common); #endif return t1; }