00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #include "coretypes.h"
00030 #include "tm.h"
00031 #include "tree.h"
00032 #include "rtl.h"
00033 #include "varray.h"
00034 #include "tree-gimple.h"
00035 #include "tree-inline.h"
00036 #include "diagnostic.h"
00037 #include "langhooks.h"
00038 #include "langhooks-def.h"
00039 #include "tree-flow.h"
00040 #include "cgraph.h"
00041 #include "timevar.h"
00042 #include "except.h"
00043 #include "hashtab.h"
00044 #include "flags.h"
00045 #include "real.h"
00046 #include "function.h"
00047 #include "output.h"
00048 #include "expr.h"
00049 #include "ggc.h"
00050 #include "toplev.h"
00051 #include "target.h"
00052 #include "optabs.h"
00053 #include "pointer-set.h"
00054
00055 #ifdef KEY
00056 #include "gspin-gcc-interface.h"
00057 #endif
00058
00059 enum gimplify_omp_var_data
00060 {
00061 GOVD_SEEN = 1,
00062 GOVD_EXPLICIT = 2,
00063 GOVD_SHARED = 4,
00064 GOVD_PRIVATE = 8,
00065 GOVD_FIRSTPRIVATE = 16,
00066 GOVD_LASTPRIVATE = 32,
00067 GOVD_REDUCTION = 64,
00068 GOVD_LOCAL = 128,
00069 GOVD_DEBUG_PRIVATE = 256,
00070 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
00071 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
00072 };
00073
00074 struct gimplify_omp_ctx
00075 {
00076 struct gimplify_omp_ctx *outer_context;
00077 splay_tree variables;
00078 struct pointer_set_t *privatized_types;
00079 location_t location;
00080 enum omp_clause_default_kind default_kind;
00081 bool is_parallel;
00082 bool is_combined_parallel;
00083 };
00084
00085 struct gimplify_ctx
00086 {
00087 struct gimplify_ctx *prev_context;
00088
00089 tree current_bind_expr;
00090 tree temps;
00091 tree conditional_cleanups;
00092 tree exit_label;
00093 tree return_temp;
00094
00095 VEC(tree,heap) *case_labels;
00096
00097 htab_t temp_htab;
00098
00099 int conditions;
00100 bool save_stack;
00101 bool into_ssa;
00102 };
00103
00104 static struct gimplify_ctx *gimplify_ctxp;
00105 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
00106
00107
00108
00109
00110
00111
00112 typedef struct gimple_temp_hash_elt
00113 {
00114 tree val;
00115 tree temp;
00116 } elt_t;
00117
00118
00119 static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
00120 #ifdef ENABLE_CHECKING
00121 static bool cpt_same_type (tree a, tree b);
00122 #endif
00123
00124
00125
00126
00127 static hashval_t
00128 gimple_tree_hash (const void *p)
00129 {
00130 tree t = ((const elt_t *) p)->val;
00131 return iterative_hash_expr (t, 0);
00132 }
00133
00134
00135
00136 static int
00137 gimple_tree_eq (const void *p1, const void *p2)
00138 {
00139 tree t1 = ((const elt_t *) p1)->val;
00140 tree t2 = ((const elt_t *) p2)->val;
00141 enum tree_code code = TREE_CODE (t1);
00142
00143 if (TREE_CODE (t2) != code
00144 || TREE_TYPE (t1) != TREE_TYPE (t2))
00145 return 0;
00146
00147 if (!operand_equal_p (t1, t2, 0))
00148 return 0;
00149
00150
00151
00152 gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2));
00153
00154 return 1;
00155 }
00156
00157
00158
00159 void
00160 push_gimplify_context (void)
00161 {
00162 struct gimplify_ctx *c;
00163
00164 c = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
00165 c->prev_context = gimplify_ctxp;
00166 if (optimize)
00167 c->temp_htab = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
00168
00169 gimplify_ctxp = c;
00170 }
00171
00172
00173
00174
00175
00176 void
00177 pop_gimplify_context (tree body)
00178 {
00179 struct gimplify_ctx *c = gimplify_ctxp;
00180 tree t;
00181
00182 gcc_assert (c && !c->current_bind_expr);
00183 gimplify_ctxp = c->prev_context;
00184
00185 for (t = c->temps; t ; t = TREE_CHAIN (t))
00186 DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
00187
00188 if (body)
00189 declare_vars (c->temps, body, false);
00190 else
00191 record_vars (c->temps);
00192
00193 if (optimize)
00194 htab_delete (c->temp_htab);
00195 free (c);
00196 }
00197
00198 static void
00199 gimple_push_bind_expr (tree bind)
00200 {
00201 TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
00202 gimplify_ctxp->current_bind_expr = bind;
00203 }
00204
00205 static void
00206 gimple_pop_bind_expr (void)
00207 {
00208 gimplify_ctxp->current_bind_expr
00209 = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
00210 }
00211
00212 tree
00213 gimple_current_bind_expr (void)
00214 {
00215 return gimplify_ctxp->current_bind_expr;
00216 }
00217
00218
00219
00220
00221 static bool
00222 gimple_conditional_context (void)
00223 {
00224 return gimplify_ctxp->conditions > 0;
00225 }
00226
00227
00228
00229 static void
00230 gimple_push_condition (void)
00231 {
00232 #ifdef ENABLE_CHECKING
00233 if (gimplify_ctxp->conditions == 0)
00234 gcc_assert (!gimplify_ctxp->conditional_cleanups);
00235 #endif
00236 ++(gimplify_ctxp->conditions);
00237 }
00238
00239
00240
00241
00242 static void
00243 gimple_pop_condition (tree *pre_p)
00244 {
00245 int conds = --(gimplify_ctxp->conditions);
00246
00247 gcc_assert (conds >= 0);
00248 if (conds == 0)
00249 {
00250 append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
00251 gimplify_ctxp->conditional_cleanups = NULL_TREE;
00252 }
00253 }
00254
00255
00256
00257 static int
00258 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
00259 {
00260 tree a = (tree) xa;
00261 tree b = (tree) xb;
00262
00263 return DECL_UID (a) - DECL_UID (b);
00264 }
00265
00266
00267
00268 static struct gimplify_omp_ctx *
00269 new_omp_context (bool is_parallel, bool is_combined_parallel)
00270 {
00271 struct gimplify_omp_ctx *c;
00272
00273 c = XCNEW (struct gimplify_omp_ctx);
00274 c->outer_context = gimplify_omp_ctxp;
00275 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
00276 c->privatized_types = pointer_set_create ();
00277 c->location = input_location;
00278 c->is_parallel = is_parallel;
00279 c->is_combined_parallel = is_combined_parallel;
00280 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
00281
00282 return c;
00283 }
00284
00285
00286
00287 static void
00288 delete_omp_context (struct gimplify_omp_ctx *c)
00289 {
00290 splay_tree_delete (c->variables);
00291 pointer_set_destroy (c->privatized_types);
00292 XDELETE (c);
00293 }
00294
00295 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
00296 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
00297
00298
00299
00300 static void
00301 append_to_statement_list_1 (tree t, tree *list_p)
00302 {
00303 tree list = *list_p;
00304 tree_stmt_iterator i;
00305
00306 if (!list)
00307 {
00308 if (t && TREE_CODE (t) == STATEMENT_LIST)
00309 {
00310 *list_p = t;
00311 return;
00312 }
00313 *list_p = list = alloc_stmt_list ();
00314 }
00315
00316 i = tsi_last (list);
00317 tsi_link_after (&i, t, TSI_CONTINUE_LINKING);
00318 }
00319
00320
00321
00322
00323 void
00324 append_to_statement_list (tree t, tree *list_p)
00325 {
00326 if (t && TREE_SIDE_EFFECTS (t))
00327 append_to_statement_list_1 (t, list_p);
00328 }
00329
00330
00331
00332 void
00333 append_to_statement_list_force (tree t, tree *list_p)
00334 {
00335 if (t != NULL_TREE)
00336 append_to_statement_list_1 (t, list_p);
00337 }
00338
00339
00340
00341 void
00342 gimplify_and_add (tree t, tree *list_p)
00343 {
00344 gimplify_stmt (&t);
00345 append_to_statement_list (t, list_p);
00346 }
00347
00348
00349
00350
00351
00352
00353 static inline void
00354 remove_suffix (char *name, int len)
00355 {
00356 int i;
00357
00358 for (i = 2; i < 8 && len > i; i++)
00359 {
00360 if (name[len - i] == '.')
00361 {
00362 name[len - i] = '\0';
00363 break;
00364 }
00365 }
00366 }
00367
00368
00369
00370
00371 tree
00372 create_artificial_label (void)
00373 {
00374 tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
00375
00376 DECL_ARTIFICIAL (lab) = 1;
00377 DECL_IGNORED_P (lab) = 1;
00378 DECL_CONTEXT (lab) = current_function_decl;
00379 return lab;
00380 }
00381
00382
00383
00384 static tree
00385 find_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00386 void *data)
00387 {
00388 tree *pdecl = (tree *) data;
00389
00390 if (DECL_P (*tp) && POINTER_TYPE_P (TREE_TYPE (*tp)))
00391 {
00392 if (*pdecl)
00393 {
00394
00395
00396
00397 return *tp;
00398 }
00399 *pdecl = *tp;
00400 }
00401
00402 return NULL_TREE;
00403 }
00404
00405
00406
00407
00408 static tree
00409 find_single_pointer_decl (tree t)
00410 {
00411 tree decl = NULL_TREE;
00412
00413 if (walk_tree (&t, find_single_pointer_decl_1, &decl, NULL))
00414 {
00415
00416
00417
00418 return NULL_TREE;
00419 }
00420
00421 return decl;
00422 }
00423
00424
00425
00426 static GTY(()) unsigned int tmp_var_id_num;
00427
00428 tree
00429 create_tmp_var_name (const char *prefix)
00430 {
00431 char *tmp_name;
00432
00433 if (prefix)
00434 {
00435 char *preftmp = ASTRDUP (prefix);
00436
00437 remove_suffix (preftmp, strlen (preftmp));
00438 prefix = preftmp;
00439 }
00440
00441 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
00442 return get_identifier (tmp_name);
00443 }
00444
00445
00446
00447
00448
00449 tree
00450 create_tmp_var_raw (tree type, const char *prefix)
00451 {
00452 tree tmp_var;
00453 tree new_type;
00454
00455
00456 new_type = build_type_variant (type, 0, 0);
00457 TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type);
00458
00459 tmp_var = build_decl (VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
00460 type);
00461
00462
00463 DECL_ARTIFICIAL (tmp_var) = 1;
00464
00465 DECL_IGNORED_P (tmp_var) = 1;
00466
00467
00468 TREE_READONLY (tmp_var) = 0;
00469
00470 DECL_EXTERNAL (tmp_var) = 0;
00471 TREE_STATIC (tmp_var) = 0;
00472 TREE_USED (tmp_var) = 1;
00473
00474 return tmp_var;
00475 }
00476
00477
00478
00479
00480
00481
00482 tree
00483 create_tmp_var (tree type, const char *prefix)
00484 {
00485 tree tmp_var;
00486
00487
00488
00489
00490
00491
00492
00493 gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
00494
00495 tmp_var = create_tmp_var_raw (type, prefix);
00496 gimple_add_tmp_var (tmp_var);
00497 return tmp_var;
00498 }
00499
00500
00501
00502
00503
00504 const char *
00505 get_name (tree t)
00506 {
00507 tree stripped_decl;
00508
00509 stripped_decl = t;
00510 STRIP_NOPS (stripped_decl);
00511 if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
00512 return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
00513 else
00514 {
00515 switch (TREE_CODE (stripped_decl))
00516 {
00517 case ADDR_EXPR:
00518 return get_name (TREE_OPERAND (stripped_decl, 0));
00519 break;
00520 default:
00521 return NULL;
00522 }
00523 }
00524 }
00525
00526
00527
00528
00529 static inline tree
00530 create_tmp_from_val (tree val)
00531 {
00532 return create_tmp_var (TYPE_MAIN_VARIANT (TREE_TYPE (val)), get_name (val));
00533 }
00534
00535
00536
00537
00538 static tree
00539 lookup_tmp_var (tree val, bool is_formal)
00540 {
00541 tree ret;
00542
00543
00544
00545
00546
00547
00548 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
00549 ret = create_tmp_from_val (val);
00550 else
00551 {
00552 elt_t elt, *elt_p;
00553 void **slot;
00554
00555 elt.val = val;
00556 slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
00557 if (*slot == NULL)
00558 {
00559 elt_p = XNEW (elt_t);
00560 elt_p->val = val;
00561 elt_p->temp = ret = create_tmp_from_val (val);
00562 *slot = (void *) elt_p;
00563 }
00564 else
00565 {
00566 elt_p = (elt_t *) *slot;
00567 ret = elt_p->temp;
00568 }
00569 }
00570
00571 if (is_formal)
00572 DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
00573
00574 return ret;
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 static tree
00590 internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
00591 {
00592 tree t, mod;
00593
00594 gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
00595
00596 t = lookup_tmp_var (val, is_formal);
00597
00598 if (is_formal)
00599 {
00600 tree u = find_single_pointer_decl (val);
00601
00602 if (u && TREE_CODE (u) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (u))
00603 u = DECL_GET_RESTRICT_BASE (u);
00604 if (u && TYPE_RESTRICT (TREE_TYPE (u)))
00605 {
00606 if (DECL_BASED_ON_RESTRICT_P (t))
00607 gcc_assert (u == DECL_GET_RESTRICT_BASE (t));
00608 else
00609 {
00610 DECL_BASED_ON_RESTRICT_P (t) = 1;
00611 SET_DECL_RESTRICT_BASE (t, u);
00612 }
00613 }
00614 }
00615
00616 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
00617 DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
00618
00619 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, val);
00620
00621 if (EXPR_HAS_LOCATION (val))
00622 SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
00623 else
00624 SET_EXPR_LOCATION (mod, input_location);
00625
00626
00627 gimplify_and_add (mod, pre_p);
00628
00629
00630
00631 if (gimplify_ctxp->into_ssa)
00632 t = TREE_OPERAND (mod, 0);
00633
00634 return t;
00635 }
00636
00637
00638
00639
00640
00641 tree
00642 get_formal_tmp_var (tree val, tree *pre_p)
00643 {
00644 return internal_get_tmp_var (val, pre_p, NULL, true);
00645 }
00646
00647
00648
00649
00650 tree
00651 get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
00652 {
00653 return internal_get_tmp_var (val, pre_p, post_p, false);
00654 }
00655
00656
00657
00658
00659 void
00660 declare_vars (tree vars, tree scope, bool debug_info)
00661 {
00662 tree last = vars;
00663 if (last)
00664 {
00665 tree temps, block;
00666
00667
00668
00669 while (TREE_CODE (scope) == COMPOUND_EXPR)
00670 scope = TREE_OPERAND (scope, 0);
00671
00672 gcc_assert (TREE_CODE (scope) == BIND_EXPR);
00673
00674 temps = nreverse (last);
00675
00676 block = BIND_EXPR_BLOCK (scope);
00677 if (!block || !debug_info)
00678 {
00679 TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
00680 BIND_EXPR_VARS (scope) = temps;
00681 }
00682 else
00683 {
00684
00685
00686
00687
00688 if (BLOCK_VARS (block))
00689 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
00690 else
00691 {
00692 BIND_EXPR_VARS (scope) = chainon (BIND_EXPR_VARS (scope), temps);
00693 BLOCK_VARS (block) = temps;
00694 }
00695 }
00696 }
00697 }
00698
00699
00700
00701
00702
00703 static void
00704 force_constant_size (tree var)
00705 {
00706
00707
00708
00709 HOST_WIDE_INT max_size;
00710
00711 gcc_assert (TREE_CODE (var) == VAR_DECL);
00712
00713 max_size = max_int_size_in_bytes (TREE_TYPE (var));
00714
00715 gcc_assert (max_size >= 0);
00716
00717 DECL_SIZE_UNIT (var)
00718 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
00719 DECL_SIZE (var)
00720 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
00721 }
00722
00723 void
00724 gimple_add_tmp_var (tree tmp)
00725 {
00726 gcc_assert (!TREE_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
00727
00728
00729
00730
00731 if (!host_integerp (DECL_SIZE_UNIT (tmp), 1))
00732 force_constant_size (tmp);
00733
00734 DECL_CONTEXT (tmp) = current_function_decl;
00735 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
00736
00737 if (gimplify_ctxp)
00738 {
00739 TREE_CHAIN (tmp) = gimplify_ctxp->temps;
00740 gimplify_ctxp->temps = tmp;
00741
00742
00743 if (gimplify_omp_ctxp)
00744 {
00745 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
00746 while (ctx && !ctx->is_parallel)
00747 ctx = ctx->outer_context;
00748 if (ctx)
00749 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
00750 }
00751 }
00752 else if (cfun)
00753 record_vars (tmp);
00754 else
00755 declare_vars (tmp, DECL_SAVED_TREE (current_function_decl), false);
00756 }
00757
00758
00759
00760 static bool
00761 should_carry_locus_p (tree stmt)
00762 {
00763
00764
00765
00766 if (TREE_CODE (stmt) == LABEL_EXPR)
00767 return false;
00768
00769
00770 if (!TREE_SIDE_EFFECTS (stmt))
00771 return false;
00772
00773 return true;
00774 }
00775
00776 static void
00777 annotate_one_with_locus (tree t, location_t locus)
00778 {
00779 if (EXPR_P (t) && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
00780 SET_EXPR_LOCATION (t, locus);
00781 }
00782
00783 void
00784 annotate_all_with_locus (tree *stmt_p, location_t locus)
00785 {
00786 tree_stmt_iterator i;
00787
00788 if (!*stmt_p)
00789 return;
00790
00791 for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
00792 {
00793 tree t = tsi_stmt (i);
00794
00795
00796
00797 gcc_assert (TREE_CODE (t) != STATEMENT_LIST
00798 && TREE_CODE (t) != COMPOUND_EXPR);
00799
00800 annotate_one_with_locus (t, locus);
00801 }
00802 }
00803
00804
00805
00806
00807
00808
00809 static tree
00810 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
00811 {
00812 enum tree_code code = TREE_CODE (*tp);
00813
00814 if (TREE_CODE_CLASS (code) == tcc_type
00815 || TREE_CODE_CLASS (code) == tcc_declaration
00816 || TREE_CODE_CLASS (code) == tcc_constant
00817 || code == SAVE_EXPR || code == TARGET_EXPR
00818
00819
00820
00821 || code == BLOCK)
00822 *walk_subtrees = 0;
00823 else
00824 {
00825 gcc_assert (code != BIND_EXPR);
00826 copy_tree_r (tp, walk_subtrees, data);
00827 }
00828
00829 return NULL_TREE;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841 static tree
00842 copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00843 void *data ATTRIBUTE_UNUSED)
00844 {
00845 tree t = *tp;
00846 enum tree_code code = TREE_CODE (t);
00847
00848
00849
00850
00851
00852 if (TREE_CODE_CLASS (code) == tcc_type
00853 || TREE_CODE_CLASS (code) == tcc_declaration
00854 || TREE_CODE_CLASS (code) == tcc_constant)
00855 {
00856 if (TREE_VISITED (t))
00857 *walk_subtrees = 0;
00858 else
00859 TREE_VISITED (t) = 1;
00860 }
00861
00862
00863
00864 else if (TREE_VISITED (t))
00865 {
00866 walk_tree (tp, mostly_copy_tree_r, NULL, NULL);
00867 *walk_subtrees = 0;
00868 }
00869
00870
00871 else
00872 TREE_VISITED (t) = 1;
00873
00874 return NULL_TREE;
00875 }
00876
00877 static tree
00878 unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00879 void *data ATTRIBUTE_UNUSED)
00880 {
00881 if (TREE_VISITED (*tp))
00882 TREE_VISITED (*tp) = 0;
00883 else
00884 *walk_subtrees = 0;
00885
00886 return NULL_TREE;
00887 }
00888
00889
00890
00891
00892
00893 static void
00894 unshare_body (tree *body_p, tree fndecl)
00895 {
00896 struct cgraph_node *cgn = cgraph_node (fndecl);
00897
00898 walk_tree (body_p, copy_if_shared_r, NULL, NULL);
00899 if (body_p == &DECL_SAVED_TREE (fndecl))
00900 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
00901 unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
00902 }
00903
00904
00905
00906 static void
00907 unvisit_body (tree *body_p, tree fndecl)
00908 {
00909 struct cgraph_node *cgn = cgraph_node (fndecl);
00910
00911 walk_tree (body_p, unmark_visited_r, NULL, NULL);
00912 if (body_p == &DECL_SAVED_TREE (fndecl))
00913 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
00914 unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
00915 }
00916
00917
00918
00919 static void
00920 unshare_all_trees (tree t)
00921 {
00922 walk_tree (&t, copy_if_shared_r, NULL, NULL);
00923 walk_tree (&t, unmark_visited_r, NULL, NULL);
00924 }
00925
00926
00927
00928
00929
00930 tree
00931 unshare_expr (tree expr)
00932 {
00933 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
00934 return expr;
00935 }
00936
00937
00938
00939
00940 tree
00941 gimple_build_eh_filter (tree body, tree allowed, tree failure)
00942 {
00943 tree t;
00944
00945
00946 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
00947 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
00948
00949 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
00950 append_to_statement_list (body, &TREE_OPERAND (t, 0));
00951
00952 return t;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961 tree
00962 voidify_wrapper_expr (tree wrapper, tree temp)
00963 {
00964 tree type = TREE_TYPE (wrapper);
00965 if (type && !VOID_TYPE_P (type))
00966 {
00967 tree *p;
00968
00969
00970
00971 for (p = &wrapper; p && *p; )
00972 {
00973 switch (TREE_CODE (*p))
00974 {
00975 case BIND_EXPR:
00976 TREE_SIDE_EFFECTS (*p) = 1;
00977 TREE_TYPE (*p) = void_type_node;
00978
00979 p = &BIND_EXPR_BODY (*p);
00980 break;
00981
00982 case CLEANUP_POINT_EXPR:
00983 case TRY_FINALLY_EXPR:
00984 case TRY_CATCH_EXPR:
00985 TREE_SIDE_EFFECTS (*p) = 1;
00986 TREE_TYPE (*p) = void_type_node;
00987 p = &TREE_OPERAND (*p, 0);
00988 break;
00989
00990 case STATEMENT_LIST:
00991 {
00992 tree_stmt_iterator i = tsi_last (*p);
00993 TREE_SIDE_EFFECTS (*p) = 1;
00994 TREE_TYPE (*p) = void_type_node;
00995 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
00996 }
00997 break;
00998
00999 case COMPOUND_EXPR:
01000
01001 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
01002 {
01003 TREE_SIDE_EFFECTS (*p) = 1;
01004 TREE_TYPE (*p) = void_type_node;
01005 }
01006 break;
01007
01008 default:
01009 goto out;
01010 }
01011 }
01012
01013 out:
01014 if (p == NULL || IS_EMPTY_STMT (*p))
01015 temp = NULL_TREE;
01016 else if (temp)
01017 {
01018
01019
01020 gcc_assert (TREE_CODE (temp) == INIT_EXPR
01021 || TREE_CODE (temp) == MODIFY_EXPR);
01022 TREE_OPERAND (temp, 1) = *p;
01023 *p = temp;
01024 }
01025 else
01026 {
01027 temp = create_tmp_var (type, "retval");
01028 *p = build2 (INIT_EXPR, type, temp, *p);
01029 }
01030
01031 return temp;
01032 }
01033
01034 return NULL_TREE;
01035 }
01036
01037
01038
01039
01040 static void
01041 build_stack_save_restore (tree *save, tree *restore)
01042 {
01043 tree save_call, tmp_var;
01044
01045 save_call =
01046 build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE],
01047 NULL_TREE);
01048 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
01049
01050 *save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
01051 *restore =
01052 build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
01053 tree_cons (NULL_TREE, tmp_var, NULL_TREE));
01054 }
01055
01056
01057
01058 static enum gimplify_status
01059 gimplify_bind_expr (tree *expr_p, tree *pre_p)
01060 {
01061 tree bind_expr = *expr_p;
01062 bool old_save_stack = gimplify_ctxp->save_stack;
01063 tree t;
01064
01065 tree temp = voidify_wrapper_expr (bind_expr, NULL);
01066
01067
01068 for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
01069 {
01070 if (TREE_CODE (t) == VAR_DECL)
01071 {
01072 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
01073
01074
01075 if (ctx && !is_global_var (t)
01076 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
01077 || splay_tree_lookup (ctx->variables,
01078 (splay_tree_key) t) == NULL))
01079 omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN);
01080
01081 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
01082 }
01083
01084
01085
01086
01087 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
01088 && !TREE_THIS_VOLATILE (t)
01089 && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
01090 && !needs_to_live_in_memory (t))
01091 DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
01092 }
01093
01094 gimple_push_bind_expr (bind_expr);
01095 gimplify_ctxp->save_stack = false;
01096
01097 gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
01098
01099 if (gimplify_ctxp->save_stack)
01100 {
01101 tree stack_save, stack_restore;
01102
01103
01104
01105
01106 build_stack_save_restore (&stack_save, &stack_restore);
01107
01108 t = build2 (TRY_FINALLY_EXPR, void_type_node,
01109 BIND_EXPR_BODY (bind_expr), NULL_TREE);
01110 append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
01111
01112 BIND_EXPR_BODY (bind_expr) = NULL_TREE;
01113 append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
01114 append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
01115 }
01116
01117 gimplify_ctxp->save_stack = old_save_stack;
01118 gimple_pop_bind_expr ();
01119
01120 if (temp)
01121 {
01122 *expr_p = temp;
01123 append_to_statement_list (bind_expr, pre_p);
01124 return GS_OK;
01125 }
01126 else
01127 return GS_ALL_DONE;
01128 }
01129
01130
01131
01132
01133
01134
01135
01136
01137 static enum gimplify_status
01138 gimplify_return_expr (tree stmt, tree *pre_p)
01139 {
01140 tree ret_expr = TREE_OPERAND (stmt, 0);
01141 tree result_decl, result;
01142
01143 if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
01144 || ret_expr == error_mark_node)
01145 return GS_ALL_DONE;
01146
01147 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
01148 result_decl = NULL_TREE;
01149 else
01150 {
01151 result_decl = TREE_OPERAND (ret_expr, 0);
01152 if (TREE_CODE (result_decl) == INDIRECT_REF)
01153
01154 result_decl = TREE_OPERAND (result_decl, 0);
01155
01156 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
01157 || TREE_CODE (ret_expr) == INIT_EXPR)
01158 && TREE_CODE (result_decl) == RESULT_DECL);
01159 }
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 if (!result_decl
01170 || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
01171 result = result_decl;
01172 else if (gimplify_ctxp->return_temp)
01173 result = gimplify_ctxp->return_temp;
01174 else
01175 {
01176 result = create_tmp_var (TREE_TYPE (result_decl), NULL);
01177
01178
01179
01180
01181
01182 TREE_NO_WARNING (result) = 1;
01183
01184 gimplify_ctxp->return_temp = result;
01185 }
01186
01187
01188
01189 if (result != result_decl)
01190 TREE_OPERAND (ret_expr, 0) = result;
01191
01192 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
01193
01194
01195
01196 if (result == result_decl)
01197 ret_expr = result;
01198 else
01199 ret_expr = build2 (MODIFY_EXPR, TREE_TYPE (result), result_decl, result);
01200 TREE_OPERAND (stmt, 0) = ret_expr;
01201
01202 return GS_ALL_DONE;
01203 }
01204
01205
01206
01207
01208 static enum gimplify_status
01209 gimplify_decl_expr (tree *stmt_p)
01210 {
01211 tree stmt = *stmt_p;
01212 tree decl = DECL_EXPR_DECL (stmt);
01213
01214 *stmt_p = NULL_TREE;
01215
01216 if (TREE_TYPE (decl) == error_mark_node)
01217 return GS_ERROR;
01218
01219 if ((TREE_CODE (decl) == TYPE_DECL
01220 || TREE_CODE (decl) == VAR_DECL)
01221 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
01222 gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
01223
01224 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
01225 {
01226 tree init = DECL_INITIAL (decl);
01227
01228 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
01229 {
01230
01231
01232
01233 tree t, args, addr, ptr_type;
01234
01235 gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
01236 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
01237
01238
01239
01240
01241
01242
01243 ptr_type = build_pointer_type (TREE_TYPE (decl));
01244 addr = create_tmp_var (ptr_type, get_name (decl));
01245 DECL_IGNORED_P (addr) = 0;
01246 t = build_fold_indirect_ref (addr);
01247 SET_DECL_VALUE_EXPR (decl, t);
01248 DECL_HAS_VALUE_EXPR_P (decl) = 1;
01249
01250 args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
01251 t = built_in_decls[BUILT_IN_ALLOCA];
01252 t = build_function_call_expr (t, args);
01253 t = fold_convert (ptr_type, t);
01254 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
01255
01256 gimplify_and_add (t, stmt_p);
01257
01258
01259
01260 gimplify_ctxp->save_stack = true;
01261 }
01262
01263 if (init && init != error_mark_node)
01264 {
01265 if (!TREE_STATIC (decl))
01266 {
01267 DECL_INITIAL (decl) = NULL_TREE;
01268 init = build2 (INIT_EXPR, void_type_node, decl, init);
01269 gimplify_and_add (init, stmt_p);
01270 }
01271 else
01272
01273
01274 walk_tree (&init, force_labels_r, NULL, NULL);
01275 }
01276
01277
01278
01279
01280
01281 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
01282 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
01283 gimple_add_tmp_var (decl);
01284 }
01285
01286 return GS_ALL_DONE;
01287 }
01288
01289
01290
01291
01292
01293 static enum gimplify_status
01294 gimplify_loop_expr (tree *expr_p, tree *pre_p)
01295 {
01296 tree saved_label = gimplify_ctxp->exit_label;
01297 tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
01298 tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
01299
01300 append_to_statement_list (start_label, pre_p);
01301
01302 gimplify_ctxp->exit_label = NULL_TREE;
01303
01304 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
01305
01306 if (gimplify_ctxp->exit_label)
01307 {
01308 append_to_statement_list (jump_stmt, pre_p);
01309 *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
01310 }
01311 else
01312 *expr_p = jump_stmt;
01313
01314 gimplify_ctxp->exit_label = saved_label;
01315
01316 return GS_ALL_DONE;
01317 }
01318
01319
01320
01321
01322
01323 static int
01324 compare_case_labels (const void *p1, const void *p2)
01325 {
01326 tree case1 = *(tree *)p1;
01327 tree case2 = *(tree *)p2;
01328
01329 return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
01330 }
01331
01332
01333
01334 void
01335 sort_case_labels (tree label_vec)
01336 {
01337 size_t len = TREE_VEC_LENGTH (label_vec);
01338 tree default_case = TREE_VEC_ELT (label_vec, len - 1);
01339
01340 if (CASE_LOW (default_case))
01341 {
01342 size_t i;
01343
01344
01345
01346 for (i = 0; i < len; ++i)
01347 {
01348 tree t = TREE_VEC_ELT (label_vec, i);
01349 if (!CASE_LOW (t))
01350 {
01351 default_case = t;
01352 TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
01353 TREE_VEC_ELT (label_vec, len - 1) = default_case;
01354 break;
01355 }
01356 }
01357 }
01358
01359 qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
01360 compare_case_labels);
01361 }
01362
01363
01364
01365
01366 static enum gimplify_status
01367 gimplify_switch_expr (tree *expr_p, tree *pre_p)
01368 {
01369 tree switch_expr = *expr_p;
01370 enum gimplify_status ret;
01371
01372 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
01373 is_gimple_val, fb_rvalue);
01374
01375 if (SWITCH_BODY (switch_expr))
01376 {
01377 VEC(tree,heap) *labels, *saved_labels;
01378 tree label_vec, default_case = NULL_TREE;
01379 size_t i, len;
01380
01381
01382
01383 gcc_assert (!SWITCH_LABELS (switch_expr));
01384
01385 saved_labels = gimplify_ctxp->case_labels;
01386 gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
01387
01388 gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
01389
01390 labels = gimplify_ctxp->case_labels;
01391 gimplify_ctxp->case_labels = saved_labels;
01392
01393 i = 0;
01394 while (i < VEC_length (tree, labels))
01395 {
01396 tree elt = VEC_index (tree, labels, i);
01397 tree low = CASE_LOW (elt);
01398 bool remove_element = FALSE;
01399
01400 if (low)
01401 {
01402
01403 tree high = CASE_HIGH (elt);
01404 if (high && INT_CST_LT (high, low))
01405 remove_element = TRUE;
01406 }
01407 else
01408 {
01409
01410 gcc_assert (!default_case);
01411 default_case = elt;
01412 remove_element = TRUE;
01413 }
01414
01415 if (remove_element)
01416 VEC_ordered_remove (tree, labels, i);
01417 else
01418 i++;
01419 }
01420 len = i;
01421
01422 label_vec = make_tree_vec (len + 1);
01423 SWITCH_LABELS (*expr_p) = label_vec;
01424 append_to_statement_list (switch_expr, pre_p);
01425
01426 if (! default_case)
01427 {
01428
01429
01430 default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
01431 NULL_TREE, create_artificial_label ());
01432 append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
01433 *expr_p = build1 (LABEL_EXPR, void_type_node,
01434 CASE_LABEL (default_case));
01435 }
01436 else
01437 *expr_p = SWITCH_BODY (switch_expr);
01438
01439 for (i = 0; i < len; ++i)
01440 TREE_VEC_ELT (label_vec, i) = VEC_index (tree, labels, i);
01441 TREE_VEC_ELT (label_vec, len) = default_case;
01442
01443 VEC_free (tree, heap, labels);
01444
01445 sort_case_labels (label_vec);
01446
01447 SWITCH_BODY (switch_expr) = NULL;
01448 }
01449 else
01450 gcc_assert (SWITCH_LABELS (switch_expr));
01451
01452 return ret;
01453 }
01454
01455 static enum gimplify_status
01456 gimplify_case_label_expr (tree *expr_p)
01457 {
01458 tree expr = *expr_p;
01459 struct gimplify_ctx *ctxp;
01460
01461
01462
01463
01464 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
01465 if (ctxp->case_labels)
01466 break;
01467
01468 VEC_safe_push (tree, heap, ctxp->case_labels, expr);
01469 *expr_p = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
01470 return GS_ALL_DONE;
01471 }
01472
01473
01474
01475
01476 tree
01477 build_and_jump (tree *label_p)
01478 {
01479 if (label_p == NULL)
01480
01481 return NULL_TREE;
01482
01483 if (*label_p == NULL_TREE)
01484 {
01485 tree label = create_artificial_label ();
01486 *label_p = label;
01487 }
01488
01489 return build1 (GOTO_EXPR, void_type_node, *label_p);
01490 }
01491
01492
01493
01494
01495
01496 static enum gimplify_status
01497 gimplify_exit_expr (tree *expr_p)
01498 {
01499 tree cond = TREE_OPERAND (*expr_p, 0);
01500 tree expr;
01501
01502 expr = build_and_jump (&gimplify_ctxp->exit_label);
01503 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
01504 *expr_p = expr;
01505
01506 return GS_OK;
01507 }
01508
01509
01510
01511
01512 tree
01513 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
01514 {
01515 if (TYPE_P (*tp))
01516 *walk_subtrees = 0;
01517 if (TREE_CODE (*tp) == LABEL_DECL)
01518 FORCED_LABEL (*tp) = 1;
01519
01520 return NULL_TREE;
01521 }
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533 static void
01534 canonicalize_component_ref (tree *expr_p)
01535 {
01536 tree expr = *expr_p;
01537 tree type;
01538
01539 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
01540
01541 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
01542 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
01543 else
01544 type = TREE_TYPE (TREE_OPERAND (expr, 1));
01545
01546 if (TREE_TYPE (expr) != type)
01547 {
01548 tree old_type = TREE_TYPE (expr);
01549
01550
01551 TREE_TYPE (expr) = type;
01552
01553
01554 expr = build1 (NOP_EXPR, old_type, expr);
01555
01556 *expr_p = expr;
01557 }
01558 }
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 static void
01570 canonicalize_addr_expr (tree *expr_p)
01571 {
01572 tree expr = *expr_p;
01573 tree ctype = TREE_TYPE (expr);
01574 tree addr_expr = TREE_OPERAND (expr, 0);
01575 tree atype = TREE_TYPE (addr_expr);
01576 tree dctype, datype, ddatype, otype, obj_expr;
01577
01578
01579 if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
01580 return;
01581
01582
01583 datype = TREE_TYPE (atype);
01584 if (TREE_CODE (datype) != ARRAY_TYPE)
01585 return;
01586
01587
01588 dctype = TREE_TYPE (ctype);
01589 ddatype = TREE_TYPE (datype);
01590 if (!lang_hooks.types_compatible_p (ddatype, dctype))
01591 return;
01592
01593
01594 obj_expr = TREE_OPERAND (addr_expr, 0);
01595 otype = TREE_TYPE (obj_expr);
01596 if (!lang_hooks.types_compatible_p (otype, datype))
01597 return;
01598
01599
01600 if (!TYPE_SIZE_UNIT (dctype)
01601 || TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
01602 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
01603 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
01604 return;
01605
01606
01607 *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
01608 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
01609 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
01610 size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
01611 size_int (TYPE_ALIGN_UNIT (dctype))));
01612 *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
01613 }
01614
01615
01616
01617
01618 static enum gimplify_status
01619 gimplify_conversion (tree *expr_p)
01620 {
01621 gcc_assert (TREE_CODE (*expr_p) == NOP_EXPR
01622 || TREE_CODE (*expr_p) == CONVERT_EXPR);
01623
01624
01625 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
01626
01627
01628 if (tree_ssa_useless_type_conversion (*expr_p))
01629 *expr_p = TREE_OPERAND (*expr_p, 0);
01630
01631
01632
01633 if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR)
01634 {
01635 tree sub = TREE_OPERAND (*expr_p, 0);
01636
01637
01638
01639
01640 if (TREE_CODE (sub) == COMPONENT_REF)
01641 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
01642
01643
01644
01645 else if (TREE_CODE (sub) == ADDR_EXPR)
01646 canonicalize_addr_expr (expr_p);
01647 }
01648
01649 return GS_OK;
01650 }
01651
01652
01653
01654
01655 static enum gimplify_status
01656 gimplify_var_or_parm_decl (tree *expr_p)
01657 {
01658 tree decl = *expr_p;
01659
01660
01661
01662
01663
01664
01665
01666 if (TREE_CODE (decl) == VAR_DECL
01667 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
01668 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
01669 && decl_function_context (decl) == current_function_decl)
01670 {
01671 gcc_assert (errorcount || sorrycount);
01672 return GS_ERROR;
01673 }
01674
01675
01676 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
01677 return GS_ALL_DONE;
01678
01679
01680 if (DECL_HAS_VALUE_EXPR_P (decl))
01681 {
01682 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
01683 return GS_OK;
01684 }
01685
01686 return GS_ALL_DONE;
01687 }
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712 static enum gimplify_status
01713 gimplify_compound_lval (tree *expr_p, tree *pre_p,
01714 tree *post_p, fallback_t fallback)
01715 {
01716 tree *p;
01717 VEC(tree,heap) *stack;
01718 enum gimplify_status ret = GS_OK, tret;
01719 int i;
01720
01721
01722
01723 stack = VEC_alloc (tree, heap, 10);
01724
01725
01726 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
01727 {
01728 restart:
01729
01730 if (TREE_CODE (*p) == INDIRECT_REF)
01731 *p = fold_indirect_ref (*p);
01732
01733 if (handled_component_p (*p))
01734 ;
01735
01736
01737 else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL)
01738 && gimplify_var_or_parm_decl (p) == GS_OK)
01739 goto restart;
01740 else
01741 break;
01742
01743 VEC_safe_push (tree, heap, stack, *p);
01744 }
01745
01746 gcc_assert (VEC_length (tree, stack));
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760 for (i = VEC_length (tree, stack) - 1; i >= 0; i--)
01761 {
01762 tree t = VEC_index (tree, stack, i);
01763
01764 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
01765 {
01766
01767
01768
01769 if (!TREE_OPERAND (t, 2))
01770 {
01771 tree low = unshare_expr (array_ref_low_bound (t));
01772 if (!is_gimple_min_invariant (low))
01773 {
01774 TREE_OPERAND (t, 2) = low;
01775 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01776 is_gimple_formal_tmp_reg, fb_rvalue);
01777 ret = MIN (ret, tret);
01778 }
01779 }
01780
01781 if (!TREE_OPERAND (t, 3))
01782 {
01783 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
01784 tree elmt_size = unshare_expr (array_ref_element_size (t));
01785 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
01786
01787
01788
01789 elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
01790
01791 if (!is_gimple_min_invariant (elmt_size))
01792 {
01793 TREE_OPERAND (t, 3) = elmt_size;
01794 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
01795 is_gimple_formal_tmp_reg, fb_rvalue);
01796 ret = MIN (ret, tret);
01797 }
01798 }
01799 }
01800 else if (TREE_CODE (t) == COMPONENT_REF)
01801 {
01802
01803 if (!TREE_OPERAND (t, 2))
01804 {
01805 tree offset = unshare_expr (component_ref_field_offset (t));
01806 tree field = TREE_OPERAND (t, 1);
01807 tree factor
01808 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
01809
01810
01811 offset = size_binop (EXACT_DIV_EXPR, offset, factor);
01812
01813 if (!is_gimple_min_invariant (offset))
01814 {
01815 TREE_OPERAND (t, 2) = offset;
01816 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01817 is_gimple_formal_tmp_reg, fb_rvalue);
01818 ret = MIN (ret, tret);
01819 }
01820 }
01821 }
01822 }
01823
01824
01825
01826
01827 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
01828 fallback | fb_lvalue);
01829 ret = MIN (ret, tret);
01830
01831
01832
01833 for (; VEC_length (tree, stack) > 0; )
01834 {
01835 tree t = VEC_pop (tree, stack);
01836
01837 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
01838 {
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
01849 {
01850 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
01851 is_gimple_formal_tmp_reg, fb_rvalue);
01852 ret = MIN (ret, tret);
01853 }
01854 }
01855 else if (TREE_CODE (t) == BIT_FIELD_REF)
01856 {
01857 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
01858 is_gimple_val, fb_rvalue);
01859 ret = MIN (ret, tret);
01860 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01861 is_gimple_val, fb_rvalue);
01862 ret = MIN (ret, tret);
01863 }
01864
01865 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
01866
01867
01868
01869
01870 recalculate_side_effects (t);
01871 }
01872
01873 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
01874 ret = MIN (ret, tret);
01875
01876
01877 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
01878 {
01879 canonicalize_component_ref (expr_p);
01880 ret = MIN (ret, GS_OK);
01881 }
01882
01883 VEC_free (tree, heap, stack);
01884
01885 return ret;
01886 }
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900 static enum gimplify_status
01901 gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
01902 bool want_value)
01903 {
01904 enum tree_code code;
01905 tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p;
01906 bool postfix;
01907 enum tree_code arith_code;
01908 enum gimplify_status ret;
01909
01910 code = TREE_CODE (*expr_p);
01911
01912 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
01913 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
01914
01915
01916 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
01917
01918 postfix = want_value;
01919 else
01920 postfix = false;
01921
01922
01923
01924 if (postfix)
01925 post_p = &post;
01926
01927
01928 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
01929 arith_code = PLUS_EXPR;
01930 else
01931 arith_code = MINUS_EXPR;
01932
01933
01934 lvalue = TREE_OPERAND (*expr_p, 0);
01935 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
01936 if (ret == GS_ERROR)
01937 return ret;
01938
01939
01940 lhs = lvalue;
01941 rhs = TREE_OPERAND (*expr_p, 1);
01942
01943
01944
01945 if (postfix)
01946 {
01947 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
01948 if (ret == GS_ERROR)
01949 return ret;
01950 }
01951
01952 t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
01953 t1 = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
01954
01955 if (postfix)
01956 {
01957 gimplify_and_add (t1, orig_post_p);
01958 append_to_statement_list (post, orig_post_p);
01959 *expr_p = lhs;
01960 return GS_ALL_DONE;
01961 }
01962 else
01963 {
01964 *expr_p = t1;
01965 return GS_OK;
01966 }
01967 }
01968
01969
01970
01971 static void
01972 maybe_with_size_expr (tree *expr_p)
01973 {
01974 tree expr = *expr_p;
01975 tree type = TREE_TYPE (expr);
01976 tree size;
01977
01978
01979
01980 if (TREE_CODE (expr) == WITH_SIZE_EXPR
01981 || type == error_mark_node)
01982 return;
01983
01984
01985 size = TYPE_SIZE_UNIT (type);
01986 if (!size || TREE_CODE (size) == INTEGER_CST)
01987 return;
01988
01989
01990 size = unshare_expr (size);
01991 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
01992 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
01993 }
01994
01995
01996
01997 static enum gimplify_status
01998 gimplify_arg (tree *expr_p, tree *pre_p)
01999 {
02000 bool (*test) (tree);
02001 fallback_t fb;
02002
02003
02004
02005
02006
02007
02008 if (is_gimple_reg_type (TREE_TYPE (*expr_p)))
02009 test = is_gimple_val, fb = fb_rvalue;
02010 else
02011 test = is_gimple_lvalue, fb = fb_either;
02012
02013
02014 maybe_with_size_expr (expr_p);
02015
02016
02017
02018
02019
02020 return gimplify_expr (expr_p, pre_p, NULL, test, fb);
02021 }
02022
02023
02024
02025
02026
02027 static enum gimplify_status
02028 gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
02029 {
02030 tree decl;
02031 tree arglist;
02032 enum gimplify_status ret;
02033
02034 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
02035
02036
02037
02038 if (! EXPR_HAS_LOCATION (*expr_p))
02039 SET_EXPR_LOCATION (*expr_p, input_location);
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053 decl = get_callee_fndecl (*expr_p);
02054 if (decl && DECL_BUILT_IN (decl))
02055 {
02056 tree arglist = TREE_OPERAND (*expr_p, 1);
02057 tree new = fold_builtin (decl, arglist, !want_value);
02058
02059 if (new && new != *expr_p)
02060 {
02061
02062
02063
02064 *expr_p = new;
02065 return GS_OK;
02066 }
02067
02068 if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
02069 && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
02070 {
02071 if (!arglist || !TREE_CHAIN (arglist))
02072 {
02073 error ("too few arguments to function %<va_start%>");
02074 *expr_p = build_empty_stmt ();
02075 return GS_OK;
02076 }
02077
02078 #ifdef KEY
02079
02080
02081
02082
02083
02084 if (!flag_spin_file)
02085 #endif
02086 if (fold_builtin_next_arg (TREE_CHAIN (arglist)))
02087 {
02088 *expr_p = build_empty_stmt ();
02089 return GS_OK;
02090 }
02091
02092
02093 return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p);
02094 }
02095 }
02096
02097
02098
02099
02100 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
02101 is_gimple_call_addr, fb_rvalue);
02102
02103 if (PUSH_ARGS_REVERSED)
02104 TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
02105 for (arglist = TREE_OPERAND (*expr_p, 1); arglist;
02106 arglist = TREE_CHAIN (arglist))
02107 {
02108 enum gimplify_status t;
02109
02110 t = gimplify_arg (&TREE_VALUE (arglist), pre_p);
02111
02112 if (t == GS_ERROR)
02113 ret = GS_ERROR;
02114 }
02115 if (PUSH_ARGS_REVERSED)
02116 TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
02117
02118
02119 if (ret != GS_ERROR)
02120 {
02121 decl = get_callee_fndecl (*expr_p);
02122 if (decl && DECL_BUILT_IN (decl))
02123 {
02124 tree arglist = TREE_OPERAND (*expr_p, 1);
02125 tree new = fold_builtin (decl, arglist, !want_value);
02126
02127 if (new && new != *expr_p)
02128 {
02129
02130
02131
02132 *expr_p = new;
02133 return GS_OK;
02134 }
02135 }
02136 }
02137
02138
02139
02140
02141 if (TREE_CODE (*expr_p) == CALL_EXPR
02142 && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
02143 TREE_SIDE_EFFECTS (*expr_p) = 0;
02144
02145 return ret;
02146 }
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 static tree
02160 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
02161 {
02162 tree local_label = NULL_TREE;
02163 tree t, expr = NULL;
02164
02165
02166
02167
02168 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
02169 {
02170
02171
02172
02173
02174
02175
02176 if (false_label_p == NULL)
02177 false_label_p = &local_label;
02178
02179 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p);
02180 append_to_statement_list (t, &expr);
02181
02182 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
02183 false_label_p);
02184 append_to_statement_list (t, &expr);
02185 }
02186 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
02187 {
02188
02189
02190
02191
02192
02193
02194 if (true_label_p == NULL)
02195 true_label_p = &local_label;
02196
02197 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL);
02198 append_to_statement_list (t, &expr);
02199
02200 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
02201 false_label_p);
02202 append_to_statement_list (t, &expr);
02203 }
02204 else if (TREE_CODE (pred) == COND_EXPR)
02205 {
02206
02207
02208
02209
02210
02211 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
02212 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
02213 false_label_p),
02214 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
02215 false_label_p));
02216 }
02217 else
02218 {
02219 expr = build3 (COND_EXPR, void_type_node, pred,
02220 build_and_jump (true_label_p),
02221 build_and_jump (false_label_p));
02222 }
02223
02224 if (local_label)
02225 {
02226 t = build1 (LABEL_EXPR, void_type_node, local_label);
02227 append_to_statement_list (t, &expr);
02228 }
02229
02230 return expr;
02231 }
02232
02233 static tree
02234 shortcut_cond_expr (tree expr)
02235 {
02236 tree pred = TREE_OPERAND (expr, 0);
02237 tree then_ = TREE_OPERAND (expr, 1);
02238 tree else_ = TREE_OPERAND (expr, 2);
02239 tree true_label, false_label, end_label, t;
02240 tree *true_label_p;
02241 tree *false_label_p;
02242 bool emit_end, emit_false, jump_over_else;
02243 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
02244 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
02245
02246
02247 if (!else_se)
02248 {
02249
02250 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
02251 {
02252 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
02253 then_ = shortcut_cond_expr (expr);
02254 then_se = then_ && TREE_SIDE_EFFECTS (then_);
02255 pred = TREE_OPERAND (pred, 0);
02256 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
02257 }
02258 }
02259 if (!then_se)
02260 {
02261
02262
02263
02264
02265 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
02266 {
02267 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
02268 else_ = shortcut_cond_expr (expr);
02269 else_se = else_ && TREE_SIDE_EFFECTS (else_);
02270 pred = TREE_OPERAND (pred, 0);
02271 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
02272 }
02273 }
02274
02275
02276 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
02277 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
02278 return expr;
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288 true_label = false_label = end_label = NULL_TREE;
02289
02290
02291
02292
02293 if (then_
02294 && TREE_CODE (then_) == GOTO_EXPR
02295 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
02296 {
02297 true_label = GOTO_DESTINATION (then_);
02298 then_ = NULL;
02299 then_se = false;
02300 }
02301
02302 if (else_
02303 && TREE_CODE (else_) == GOTO_EXPR
02304 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
02305 {
02306 false_label = GOTO_DESTINATION (else_);
02307 else_ = NULL;
02308 else_se = false;
02309 }
02310
02311
02312 if (true_label)
02313 true_label_p = &true_label;
02314 else
02315 true_label_p = NULL;
02316
02317
02318 if (false_label || else_se)
02319 false_label_p = &false_label;
02320 else
02321 false_label_p = NULL;
02322
02323
02324 if (!then_se && !else_se)
02325 return shortcut_cond_r (pred, true_label_p, false_label_p);
02326
02327
02328 if (else_se)
02329 expr = expr_last (else_);
02330 else if (then_se)
02331 expr = expr_last (then_);
02332 else
02333 expr = NULL;
02334 if (expr && TREE_CODE (expr) == LABEL_EXPR)
02335 end_label = LABEL_EXPR_LABEL (expr);
02336
02337
02338
02339 if (!false_label_p)
02340 false_label_p = &end_label;
02341
02342
02343 emit_end = (end_label == NULL_TREE);
02344 emit_false = (false_label == NULL_TREE);
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354 jump_over_else = block_may_fallthru (then_);
02355
02356 pred = shortcut_cond_r (pred, true_label_p, false_label_p);
02357
02358 expr = NULL;
02359 append_to_statement_list (pred, &expr);
02360
02361 append_to_statement_list (then_, &expr);
02362 if (else_se)
02363 {
02364 if (jump_over_else)
02365 {
02366 t = build_and_jump (&end_label);
02367 append_to_statement_list (t, &expr);
02368 }
02369 if (emit_false)
02370 {
02371 t = build1 (LABEL_EXPR, void_type_node, false_label);
02372 append_to_statement_list (t, &expr);
02373 }
02374 append_to_statement_list (else_, &expr);
02375 }
02376 if (emit_end && end_label)
02377 {
02378 t = build1 (LABEL_EXPR, void_type_node, end_label);
02379 append_to_statement_list (t, &expr);
02380 }
02381
02382 return expr;
02383 }
02384
02385
02386
02387 tree
02388 gimple_boolify (tree expr)
02389 {
02390 tree type = TREE_TYPE (expr);
02391
02392 if (TREE_CODE (type) == BOOLEAN_TYPE)
02393 return expr;
02394
02395 switch (TREE_CODE (expr))
02396 {
02397 case TRUTH_AND_EXPR:
02398 case TRUTH_OR_EXPR:
02399 case TRUTH_XOR_EXPR:
02400 case TRUTH_ANDIF_EXPR:
02401 case TRUTH_ORIF_EXPR:
02402
02403 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
02404
02405
02406 case TRUTH_NOT_EXPR:
02407 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
02408
02409
02410 case EQ_EXPR: case NE_EXPR:
02411 case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
02412
02413 TREE_TYPE (expr) = boolean_type_node;
02414 return expr;
02415
02416 default:
02417
02418
02419 return fold_convert (boolean_type_node, expr);
02420 }
02421 }
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439 static enum gimplify_status
02440 gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
02441 {
02442 tree expr = *expr_p;
02443 tree tmp, tmp2, type;
02444 enum gimplify_status ret;
02445
02446 type = TREE_TYPE (expr);
02447
02448
02449
02450 if (! VOID_TYPE_P (type))
02451 {
02452 tree result;
02453
02454 if ((fallback & fb_lvalue) == 0)
02455 {
02456 result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
02457 ret = GS_ALL_DONE;
02458 }
02459 else
02460 {
02461 tree type = build_pointer_type (TREE_TYPE (expr));
02462
02463 if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
02464 TREE_OPERAND (expr, 1) =
02465 build_fold_addr_expr (TREE_OPERAND (expr, 1));
02466
02467 if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
02468 TREE_OPERAND (expr, 2) =
02469 build_fold_addr_expr (TREE_OPERAND (expr, 2));
02470
02471 tmp2 = tmp = create_tmp_var (type, "iftmp");
02472
02473 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
02474 TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
02475
02476 result = build_fold_indirect_ref (tmp);
02477 ret = GS_ALL_DONE;
02478 }
02479
02480
02481
02482 if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
02483 TREE_OPERAND (expr, 1)
02484 = build2 (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
02485
02486
02487 if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
02488 TREE_OPERAND (expr, 2)
02489 = build2 (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2));
02490
02491 TREE_TYPE (expr) = void_type_node;
02492 recalculate_side_effects (expr);
02493
02494
02495 gimplify_and_add (expr, pre_p);
02496
02497 *expr_p = result;
02498 return ret;
02499 }
02500
02501
02502 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
02503
02504
02505 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
02506 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
02507 {
02508 expr = shortcut_cond_expr (expr);
02509
02510 if (expr != *expr_p)
02511 {
02512 *expr_p = expr;
02513
02514
02515
02516
02517
02518 gimple_push_condition ();
02519 gimplify_stmt (expr_p);
02520 gimple_pop_condition (pre_p);
02521
02522 return GS_ALL_DONE;
02523 }
02524 }
02525
02526
02527 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
02528 is_gimple_condexpr, fb_rvalue);
02529
02530 gimple_push_condition ();
02531
02532 gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
02533 gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
02534 recalculate_side_effects (expr);
02535
02536 gimple_pop_condition (pre_p);
02537
02538 if (ret == GS_ERROR)
02539 ;
02540 else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
02541 ret = GS_ALL_DONE;
02542 else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))
02543
02544 {
02545 TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0));
02546 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
02547 is_gimple_condexpr, fb_rvalue);
02548
02549 tmp = TREE_OPERAND (expr, 1);
02550 TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2);
02551 TREE_OPERAND (expr, 2) = tmp;
02552 }
02553 else
02554
02555 expr = TREE_OPERAND (expr, 0);
02556
02557 *expr_p = expr;
02558 return ret;
02559 }
02560
02561
02562
02563
02564 static enum gimplify_status
02565 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
02566 {
02567 tree args, t, to, to_ptr, from;
02568
02569 to = TREE_OPERAND (*expr_p, 0);
02570 from = TREE_OPERAND (*expr_p, 1);
02571
02572 args = tree_cons (NULL, size, NULL);
02573
02574 t = build_fold_addr_expr (from);
02575 args = tree_cons (NULL, t, args);
02576
02577 to_ptr = build_fold_addr_expr (to);
02578 args = tree_cons (NULL, to_ptr, args);
02579 t = implicit_built_in_decls[BUILT_IN_MEMCPY];
02580 t = build_function_call_expr (t, args);
02581
02582 if (want_value)
02583 {
02584 t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
02585 t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
02586 }
02587
02588 *expr_p = t;
02589 return GS_OK;
02590 }
02591
02592
02593
02594
02595
02596 static enum gimplify_status
02597 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
02598 {
02599 tree args, t, to, to_ptr;
02600
02601 to = TREE_OPERAND (*expr_p, 0);
02602
02603 args = tree_cons (NULL, size, NULL);
02604
02605 args = tree_cons (NULL, integer_zero_node, args);
02606
02607 to_ptr = build_fold_addr_expr (to);
02608 args = tree_cons (NULL, to_ptr, args);
02609 t = implicit_built_in_decls[BUILT_IN_MEMSET];
02610 t = build_function_call_expr (t, args);
02611
02612 if (want_value)
02613 {
02614 t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
02615 t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
02616 }
02617
02618 *expr_p = t;
02619 return GS_OK;
02620 }
02621
02622
02623
02624
02625
02626 struct gimplify_init_ctor_preeval_data
02627 {
02628
02629
02630 tree lhs_base_decl;
02631
02632
02633 int lhs_alias_set;
02634 };
02635
02636 static tree
02637 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
02638 {
02639 struct gimplify_init_ctor_preeval_data *data
02640 = (struct gimplify_init_ctor_preeval_data *) xdata;
02641 tree t = *tp;
02642
02643
02644 if (data->lhs_base_decl == t)
02645 return t;
02646
02647
02648
02649
02650 if (TREE_CODE (t) == INDIRECT_REF
02651 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
02652 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
02653 return t;
02654
02655
02656
02657 if (TREE_CODE (t) == CALL_EXPR)
02658 {
02659 tree type, fntype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
02660
02661 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
02662 if (POINTER_TYPE_P (TREE_VALUE (type))
02663 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
02664 && alias_sets_conflict_p (data->lhs_alias_set,
02665 get_alias_set
02666 (TREE_TYPE (TREE_VALUE (type)))))
02667 return t;
02668 }
02669
02670 if (IS_TYPE_OR_DECL_P (t))
02671 *walk_subtrees = 0;
02672 return NULL;
02673 }
02674
02675
02676
02677
02678
02679 static void
02680 gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
02681 struct gimplify_init_ctor_preeval_data *data)
02682 {
02683 enum gimplify_status one;
02684
02685
02686
02687
02688
02689 if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p))
02690 return;
02691
02692
02693 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
02694 return;
02695
02696
02697 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
02698 {
02699 unsigned HOST_WIDE_INT ix;
02700 constructor_elt *ce;
02701 VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (*expr_p);
02702
02703 for (ix = 0; VEC_iterate (constructor_elt, v, ix, ce); ix++)
02704 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
02705 return;
02706 }
02707
02708
02709 maybe_with_size_expr (expr_p);
02710
02711
02712
02713
02714
02715
02716
02717 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
02718 if (one == GS_ERROR)
02719 {
02720 *expr_p = NULL;
02721 return;
02722 }
02723
02724
02725
02726
02727
02728 if (DECL_P (*expr_p))
02729 return;
02730
02731
02732
02733 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
02734 return;
02735
02736
02737 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
02738 return;
02739
02740
02741 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
02742 }
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762 static void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *,
02763 tree *, bool);
02764
02765 static void
02766 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
02767 tree value, tree array_elt_type,
02768 tree *pre_p, bool cleared)
02769 {
02770 tree loop_entry_label, loop_exit_label;
02771 tree var, var_type, cref;
02772
02773 loop_entry_label = create_artificial_label ();
02774 loop_exit_label = create_artificial_label ();
02775
02776
02777 var_type = TREE_TYPE (upper);
02778 var = create_tmp_var (var_type, NULL);
02779 append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
02780
02781
02782 append_to_statement_list (build1 (LABEL_EXPR,
02783 void_type_node,
02784 loop_entry_label),
02785 pre_p);
02786
02787
02788 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
02789 var, NULL_TREE, NULL_TREE);
02790
02791
02792
02793
02794 if (TREE_CODE (value) == CONSTRUCTOR)
02795
02796
02797 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
02798 pre_p, cleared);
02799 else
02800 append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
02801 cref, value),
02802 pre_p);
02803
02804
02805 gimplify_and_add (build3 (COND_EXPR, void_type_node,
02806 build2 (EQ_EXPR, boolean_type_node,
02807 var, upper),
02808 build1 (GOTO_EXPR,
02809 void_type_node,
02810 loop_exit_label),
02811 NULL_TREE),
02812 pre_p);
02813
02814
02815 append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
02816 build2 (PLUS_EXPR, var_type, var,
02817 fold_convert (var_type,
02818 integer_one_node))),
02819 pre_p);
02820
02821
02822 append_to_statement_list (build1 (GOTO_EXPR,
02823 void_type_node,
02824 loop_entry_label),
02825 pre_p);
02826
02827
02828 append_to_statement_list (build1 (LABEL_EXPR,
02829 void_type_node,
02830 loop_exit_label),
02831 pre_p);
02832 }
02833
02834
02835
02836 static bool
02837 zero_sized_field_decl (tree fdecl)
02838 {
02839 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
02840 && integer_zerop (DECL_SIZE (fdecl)))
02841 return true;
02842 return false;
02843 }
02844
02845
02846
02847 static bool
02848 zero_sized_type (tree type)
02849 {
02850 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
02851 && integer_zerop (TYPE_SIZE (type)))
02852 return true;
02853 return false;
02854 }
02855
02856
02857
02858
02859
02860
02861
02862 static void
02863 gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
02864 tree *pre_p, bool cleared)
02865 {
02866 tree array_elt_type = NULL;
02867 unsigned HOST_WIDE_INT ix;
02868 tree purpose, value;
02869
02870 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
02871 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
02872
02873 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
02874 {
02875 tree cref, init;
02876
02877
02878 if (value == NULL)
02879 continue;
02880
02881 if (cleared && initializer_zerop (value))
02882 continue;
02883
02884
02885
02886 gcc_assert (purpose);
02887
02888
02889
02890
02891
02892
02893 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
02894 continue;
02895
02896
02897
02898 if (TREE_CODE (purpose) == RANGE_EXPR)
02899 {
02900 tree lower = TREE_OPERAND (purpose, 0);
02901 tree upper = TREE_OPERAND (purpose, 1);
02902
02903
02904
02905 if (simple_cst_equal (lower, upper))
02906 purpose = upper;
02907 else
02908 {
02909 gimplify_init_ctor_eval_range (object, lower, upper, value,
02910 array_elt_type, pre_p, cleared);
02911 continue;
02912 }
02913 }
02914
02915 if (array_elt_type)
02916 {
02917 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
02918 purpose, NULL_TREE, NULL_TREE);
02919 }
02920 else
02921 {
02922 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
02923 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
02924 unshare_expr (object), purpose, NULL_TREE);
02925 }
02926
02927 if (TREE_CODE (value) == CONSTRUCTOR
02928 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
02929 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
02930 pre_p, cleared);
02931 else
02932 {
02933 init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
02934 gimplify_and_add (init, pre_p);
02935 }
02936 }
02937 }
02938
02939
02940
02941
02942
02943
02944
02945
02946 static enum gimplify_status
02947 gimplify_init_constructor (tree *expr_p, tree *pre_p,
02948 tree *post_p, bool want_value)
02949 {
02950 tree object;
02951 tree ctor = TREE_OPERAND (*expr_p, 1);
02952 tree type = TREE_TYPE (ctor);
02953 enum gimplify_status ret;
02954 VEC(constructor_elt,gc) *elts;
02955
02956 if (TREE_CODE (ctor) != CONSTRUCTOR)
02957 return GS_UNHANDLED;
02958
02959 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
02960 is_gimple_lvalue, fb_lvalue);
02961 if (ret == GS_ERROR)
02962 return ret;
02963 object = TREE_OPERAND (*expr_p, 0);
02964
02965 elts = CONSTRUCTOR_ELTS (ctor);
02966
02967 ret = GS_ALL_DONE;
02968 switch (TREE_CODE (type))
02969 {
02970 case RECORD_TYPE:
02971 case UNION_TYPE:
02972 case QUAL_UNION_TYPE:
02973 case ARRAY_TYPE:
02974 {
02975 struct gimplify_init_ctor_preeval_data preeval_data;
02976 HOST_WIDE_INT num_type_elements, num_ctor_elements;
02977 HOST_WIDE_INT num_nonzero_elements;
02978 bool cleared, valid_const_initializer;
02979
02980
02981
02982
02983 if (VEC_empty (constructor_elt, elts))
02984 break;
02985
02986
02987
02988
02989 valid_const_initializer
02990 = categorize_ctor_elements (ctor, &num_nonzero_elements,
02991 &num_ctor_elements, &cleared);
02992
02993
02994
02995 if (valid_const_initializer
02996 && num_nonzero_elements > 1
02997 && TREE_READONLY (object)
02998 && TREE_CODE (object) == VAR_DECL)
02999 {
03000 DECL_INITIAL (object) = ctor;
03001 TREE_STATIC (object) = 1;
03002 if (!DECL_NAME (object))
03003 DECL_NAME (object) = create_tmp_var_name ("C");
03004 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
03005
03006
03007
03008
03009
03010
03011
03012
03013 lhd_set_decl_assembler_name (object);
03014
03015 *expr_p = NULL_TREE;
03016 break;
03017 }
03018
03019
03020
03021
03022
03023
03024
03025
03026 num_type_elements = count_type_elements (type, true);
03027
03028
03029
03030
03031
03032 if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
03033 cleared = true;
03034
03035 else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
03036 && num_nonzero_elements < num_type_elements/4)
03037 cleared = true;
03038
03039
03040
03041
03042
03043 else if (num_ctor_elements < num_type_elements)
03044 cleared = true;
03045
03046
03047
03048
03049
03050
03051
03052 if (valid_const_initializer && !cleared)
03053 {
03054 HOST_WIDE_INT size = int_size_in_bytes (type);
03055 unsigned int align;
03056
03057
03058
03059
03060 if (size < 0)
03061 {
03062 size = int_size_in_bytes (TREE_TYPE (object));
03063 if (size >= 0)
03064 TREE_TYPE (ctor) = type = TREE_TYPE (object);
03065 }
03066
03067
03068
03069 if (DECL_P (object))
03070 align = DECL_ALIGN (object);
03071 else
03072 align = TYPE_ALIGN (type);
03073
03074 if (size > 0 && !can_move_by_pieces (size, align))
03075 {
03076 tree new = create_tmp_var_raw (type, "C");
03077
03078 gimple_add_tmp_var (new);
03079 TREE_STATIC (new) = 1;
03080 TREE_READONLY (new) = 1;
03081 DECL_INITIAL (new) = ctor;
03082 if (align > DECL_ALIGN (new))
03083 {
03084 DECL_ALIGN (new) = align;
03085 DECL_USER_ALIGN (new) = 1;
03086 }
03087 walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
03088
03089 TREE_OPERAND (*expr_p, 1) = new;
03090
03091
03092
03093
03094 return GS_UNHANDLED;
03095 }
03096 }
03097
03098
03099
03100
03101 if (num_nonzero_elements > 0)
03102 {
03103 preeval_data.lhs_base_decl = get_base_address (object);
03104 if (!DECL_P (preeval_data.lhs_base_decl))
03105 preeval_data.lhs_base_decl = NULL;
03106 preeval_data.lhs_alias_set = get_alias_set (object);
03107
03108 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
03109 pre_p, post_p, &preeval_data);
03110 }
03111
03112 if (cleared)
03113 {
03114
03115
03116
03117 CONSTRUCTOR_ELTS (ctor) = NULL;
03118 object = unshare_expr (object);
03119 gimplify_stmt (expr_p);
03120 append_to_statement_list (*expr_p, pre_p);
03121 }
03122
03123
03124
03125
03126 if (!cleared || num_nonzero_elements > 0)
03127 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
03128
03129 *expr_p = NULL_TREE;
03130 }
03131 break;
03132
03133 case COMPLEX_TYPE:
03134 {
03135 tree r, i;
03136
03137
03138 gcc_assert (VEC_length (constructor_elt, elts) == 2);
03139 r = VEC_index (constructor_elt, elts, 0)->value;
03140 i = VEC_index (constructor_elt, elts, 1)->value;
03141 if (r == NULL || i == NULL)
03142 {
03143 tree zero = fold_convert (TREE_TYPE (type), integer_zero_node);
03144 if (r == NULL)
03145 r = zero;
03146 if (i == NULL)
03147 i = zero;
03148 }
03149
03150
03151
03152 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
03153 {
03154 ctor = build_complex (type, r, i);
03155 TREE_OPERAND (*expr_p, 1) = ctor;
03156 }
03157 else
03158 {
03159 ctor = build2 (COMPLEX_EXPR, type, r, i);
03160 TREE_OPERAND (*expr_p, 1) = ctor;
03161 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
03162 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
03163 fb_rvalue);
03164 }
03165 }
03166 break;
03167
03168 case VECTOR_TYPE:
03169 {
03170 unsigned HOST_WIDE_INT ix;
03171 constructor_elt *ce;
03172
03173
03174 if (TREE_CONSTANT (ctor))
03175 {
03176 bool constant_p = true;
03177 tree value;
03178
03179
03180
03181
03182 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
03183 if (!CONSTANT_CLASS_P (value))
03184 {
03185 constant_p = false;
03186 break;
03187 }
03188
03189 if (constant_p)
03190 {
03191 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
03192 break;
03193 }
03194
03195
03196
03197
03198 break;
03199 }
03200
03201
03202
03203 for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++)
03204 {
03205 enum gimplify_status tret;
03206 tret = gimplify_expr (&ce->value, pre_p, post_p,
03207 is_gimple_val, fb_rvalue);
03208 if (tret == GS_ERROR)
03209 ret = GS_ERROR;
03210 }
03211 }
03212 break;
03213
03214 default:
03215
03216 gcc_unreachable ();
03217 }
03218
03219 if (ret == GS_ERROR)
03220 return GS_ERROR;
03221 else if (want_value)
03222 {
03223 append_to_statement_list (*expr_p, pre_p);
03224 *expr_p = object;
03225 return GS_OK;
03226 }
03227 else
03228 return GS_ALL_DONE;
03229 }
03230
03231
03232
03233
03234
03235
03236
03237
03238 static tree
03239 fold_indirect_ref_rhs (tree t)
03240 {
03241 tree type = TREE_TYPE (TREE_TYPE (t));
03242 tree sub = t;
03243 tree subtype;
03244
03245 STRIP_USELESS_TYPE_CONVERSION (sub);
03246 subtype = TREE_TYPE (sub);
03247 if (!POINTER_TYPE_P (subtype))
03248 return NULL_TREE;
03249
03250 if (TREE_CODE (sub) == ADDR_EXPR)
03251 {
03252 tree op = TREE_OPERAND (sub, 0);
03253 tree optype = TREE_TYPE (op);
03254
03255 if (lang_hooks.types_compatible_p (type, optype))
03256 return op;
03257
03258 else if (TREE_CODE (optype) == ARRAY_TYPE
03259 && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
03260 {
03261 tree type_domain = TYPE_DOMAIN (optype);
03262 tree min_val = size_zero_node;
03263 if (type_domain && TYPE_MIN_VALUE (type_domain))
03264 min_val = TYPE_MIN_VALUE (type_domain);
03265 return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
03266 }
03267 }
03268
03269
03270 if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
03271 && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
03272 {
03273 tree type_domain;
03274 tree min_val = size_zero_node;
03275 tree osub = sub;
03276 sub = fold_indirect_ref_rhs (sub);
03277 if (! sub)
03278 sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
03279 type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
03280 if (type_domain && TYPE_MIN_VALUE (type_domain))
03281 min_val = TYPE_MIN_VALUE (type_domain);
03282 return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
03283 }
03284
03285 return NULL_TREE;
03286 }
03287
03288
03289
03290
03291 static enum gimplify_status
03292 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
03293 tree *post_p, bool want_value)
03294 {
03295 enum gimplify_status ret = GS_OK;
03296
03297 while (ret != GS_UNHANDLED)
03298 switch (TREE_CODE (*from_p))
03299 {
03300 case INDIRECT_REF:
03301 {
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311 tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
03312 if (t)
03313 {
03314 *from_p = t;
03315 ret = GS_OK;
03316 }
03317 else
03318 ret = GS_UNHANDLED;
03319 break;
03320 }
03321
03322 case TARGET_EXPR:
03323 {
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334 tree init = TARGET_EXPR_INITIAL (*from_p);
03335
03336 if (!VOID_TYPE_P (TREE_TYPE (init)))
03337 {
03338 *from_p = init;
03339 ret = GS_OK;
03340 }
03341 else
03342 ret = GS_UNHANDLED;
03343 }
03344 break;
03345
03346 case COMPOUND_EXPR:
03347
03348
03349 gimplify_compound_expr (from_p, pre_p, true);
03350 ret = GS_OK;
03351 break;
03352
03353 case CONSTRUCTOR:
03354
03355
03356 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
03357
03358 case COND_EXPR:
03359
03360
03361
03362
03363 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
03364 {
03365
03366 enum tree_code code = TREE_CODE (*expr_p);
03367 tree cond = *from_p;
03368 tree result = *to_p;
03369
03370 ret = gimplify_expr (&result, pre_p, post_p,
03371 is_gimple_min_lval, fb_lvalue);
03372 if (ret != GS_ERROR)
03373 ret = GS_OK;
03374
03375 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
03376 TREE_OPERAND (cond, 1)
03377 = build2 (code, void_type_node, result,
03378 TREE_OPERAND (cond, 1));
03379 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
03380 TREE_OPERAND (cond, 2)
03381 = build2 (code, void_type_node, unshare_expr (result),
03382 TREE_OPERAND (cond, 2));
03383
03384 TREE_TYPE (cond) = void_type_node;
03385 recalculate_side_effects (cond);
03386
03387 if (want_value)
03388 {
03389 gimplify_and_add (cond, pre_p);
03390 *expr_p = unshare_expr (result);
03391 }
03392 else
03393 *expr_p = cond;
03394 return ret;
03395 }
03396 else
03397 ret = GS_UNHANDLED;
03398 break;
03399
03400 case CALL_EXPR:
03401
03402
03403 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
03404 && aggregate_value_p (*from_p, *from_p))
03405 {
03406 bool use_target;
03407
03408 if (!(rhs_predicate_for (*to_p))(*from_p))
03409
03410 use_target = false;
03411 else if (TREE_CODE (*to_p) == RESULT_DECL
03412 && DECL_NAME (*to_p) == NULL_TREE
03413 && needs_to_live_in_memory (*to_p))
03414
03415 use_target = true;
03416 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
03417 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
03418
03419 use_target = false;
03420 else if (TREE_CODE (*to_p) == VAR_DECL
03421 && DECL_GIMPLE_FORMAL_TEMP_P (*to_p))
03422
03423
03424 use_target = false;
03425 else if (TREE_CODE (*expr_p) == INIT_EXPR)
03426
03427
03428 use_target = true;
03429 else if (!is_gimple_non_addressable (*to_p))
03430
03431
03432
03433
03434
03435
03436 use_target = false;
03437 else
03438 use_target = true;
03439
03440 if (use_target)
03441 {
03442 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
03443 lang_hooks.mark_addressable (*to_p);
03444 }
03445 }
03446
03447 ret = GS_UNHANDLED;
03448 break;
03449
03450
03451
03452 case CLEANUP_POINT_EXPR:
03453 case BIND_EXPR:
03454 case STATEMENT_LIST:
03455 {
03456 tree wrap = *from_p;
03457 tree t;
03458
03459 ret = gimplify_expr (to_p, pre_p, post_p,
03460 is_gimple_min_lval, fb_lvalue);
03461 if (ret != GS_ERROR)
03462 ret = GS_OK;
03463
03464 t = voidify_wrapper_expr (wrap, *expr_p);
03465 gcc_assert (t == *expr_p);
03466
03467 if (want_value)
03468 {
03469 gimplify_and_add (wrap, pre_p);
03470 *expr_p = unshare_expr (*to_p);
03471 }
03472 else
03473 *expr_p = wrap;
03474 return GS_OK;
03475 }
03476
03477 default:
03478 ret = GS_UNHANDLED;
03479 break;
03480 }
03481
03482 return ret;
03483 }
03484
03485
03486
03487
03488
03489 static enum gimplify_status
03490 gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
03491 {
03492 enum tree_code code, ocode;
03493 tree lhs, rhs, new_rhs, other, realpart, imagpart;
03494
03495 lhs = TREE_OPERAND (*expr_p, 0);
03496 rhs = TREE_OPERAND (*expr_p, 1);
03497 code = TREE_CODE (lhs);
03498 lhs = TREE_OPERAND (lhs, 0);
03499
03500 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
03501 other = build1 (ocode, TREE_TYPE (rhs), lhs);
03502 other = get_formal_tmp_var (other, pre_p);
03503
03504 realpart = code == REALPART_EXPR ? rhs : other;
03505 imagpart = code == REALPART_EXPR ? other : rhs;
03506
03507 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
03508 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
03509 else
03510 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
03511
03512 TREE_OPERAND (*expr_p, 0) = lhs;
03513 TREE_OPERAND (*expr_p, 1) = new_rhs;
03514
03515 if (want_value)
03516 {
03517 append_to_statement_list (*expr_p, pre_p);
03518 *expr_p = rhs;
03519 }
03520
03521 return GS_ALL_DONE;
03522 }
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539 static enum gimplify_status
03540 gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
03541 {
03542 tree *from_p = &TREE_OPERAND (*expr_p, 1);
03543 tree *to_p = &TREE_OPERAND (*expr_p, 0);
03544 enum gimplify_status ret = GS_UNHANDLED;
03545
03546 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
03547 || TREE_CODE (*expr_p) == INIT_EXPR);
03548
03549
03550
03551 if (zero_sized_type (TREE_TYPE (*from_p)))
03552 {
03553 gimplify_stmt (from_p);
03554 gimplify_stmt (to_p);
03555 append_to_statement_list (*from_p, pre_p);
03556 append_to_statement_list (*to_p, pre_p);
03557 *expr_p = NULL_TREE;
03558 return GS_ALL_DONE;
03559 }
03560
03561
03562 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
03563 want_value);
03564 if (ret != GS_UNHANDLED)
03565 return ret;
03566
03567
03568
03569
03570
03571
03572
03573 maybe_with_size_expr (from_p);
03574
03575 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
03576 if (ret == GS_ERROR)
03577 return ret;
03578
03579 ret = gimplify_expr (from_p, pre_p, post_p,
03580 rhs_predicate_for (*to_p), fb_rvalue);
03581 if (ret == GS_ERROR)
03582 return ret;
03583
03584
03585 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
03586 want_value);
03587 if (ret != GS_UNHANDLED)
03588 return ret;
03589
03590
03591
03592
03593 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
03594 {
03595 tree from = TREE_OPERAND (*from_p, 0);
03596 tree size = TREE_OPERAND (*from_p, 1);
03597
03598 if (TREE_CODE (from) == CONSTRUCTOR)
03599 return gimplify_modify_expr_to_memset (expr_p, size, want_value);
03600 if (is_gimple_addressable (from))
03601 {
03602 *from_p = from;
03603 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
03604 }
03605 }
03606
03607
03608
03609
03610 if ((TREE_CODE (*to_p) == REALPART_EXPR
03611 || TREE_CODE (*to_p) == IMAGPART_EXPR)
03612 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
03613 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
03614
03615 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
03616 {
03617
03618
03619 gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
03620 *to_p = make_ssa_name (*to_p, *expr_p);
03621 }
03622
03623 if (want_value)
03624 {
03625 append_to_statement_list (*expr_p, pre_p);
03626 *expr_p = *to_p;
03627 return GS_OK;
03628 }
03629
03630 return GS_ALL_DONE;
03631 }
03632
03633
03634
03635
03636 static enum gimplify_status
03637 gimplify_variable_sized_compare (tree *expr_p)
03638 {
03639 tree op0 = TREE_OPERAND (*expr_p, 0);
03640 tree op1 = TREE_OPERAND (*expr_p, 1);
03641 tree args, t, dest;
03642
03643 t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
03644 t = unshare_expr (t);
03645 t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
03646 args = tree_cons (NULL, t, NULL);
03647 t = build_fold_addr_expr (op1);
03648 args = tree_cons (NULL, t, args);
03649 dest = build_fold_addr_expr (op0);
03650 args = tree_cons (NULL, dest, args);
03651 t = implicit_built_in_decls[BUILT_IN_MEMCMP];
03652 t = build_function_call_expr (t, args);
03653 *expr_p
03654 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
03655
03656 return GS_OK;
03657 }
03658
03659
03660
03661
03662 static enum gimplify_status
03663 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
03664 {
03665 tree op0 = TREE_OPERAND (*expr_p, 0);
03666 tree op1 = TREE_OPERAND (*expr_p, 1);
03667
03668 tree type = TREE_TYPE (op0);
03669 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
03670
03671 op0 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op0);
03672 op1 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op1);
03673
03674 *expr_p
03675 = fold_build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
03676
03677 return GS_OK;
03678 }
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692 static enum gimplify_status
03693 gimplify_boolean_expr (tree *expr_p)
03694 {
03695
03696 tree type = TREE_TYPE (*expr_p);
03697
03698 *expr_p = build3 (COND_EXPR, type, *expr_p,
03699 fold_convert (type, boolean_true_node),
03700 fold_convert (type, boolean_false_node));
03701
03702 return GS_OK;
03703 }
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717 static enum gimplify_status
03718 gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
03719 {
03720 tree t = *expr_p;
03721
03722 do
03723 {
03724 tree *sub_p = &TREE_OPERAND (t, 0);
03725
03726 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
03727 gimplify_compound_expr (sub_p, pre_p, false);
03728 else
03729 gimplify_stmt (sub_p);
03730 append_to_statement_list (*sub_p, pre_p);
03731
03732 t = TREE_OPERAND (t, 1);
03733 }
03734 while (TREE_CODE (t) == COMPOUND_EXPR);
03735
03736 *expr_p = t;
03737 if (want_value)
03738 return GS_OK;
03739 else
03740 {
03741 gimplify_stmt (expr_p);
03742 return GS_ALL_DONE;
03743 }
03744 }
03745
03746
03747
03748
03749 static enum gimplify_status
03750 gimplify_statement_list (tree *expr_p, tree *pre_p)
03751 {
03752 tree temp = voidify_wrapper_expr (*expr_p, NULL);
03753
03754 tree_stmt_iterator i = tsi_start (*expr_p);
03755
03756 while (!tsi_end_p (i))
03757 {
03758 tree t;
03759
03760 gimplify_stmt (tsi_stmt_ptr (i));
03761
03762 t = tsi_stmt (i);
03763 if (t == NULL)
03764 tsi_delink (&i);
03765 else if (TREE_CODE (t) == STATEMENT_LIST)
03766 {
03767 tsi_link_before (&i, t, TSI_SAME_STMT);
03768 tsi_delink (&i);
03769 }
03770 else
03771 tsi_next (&i);
03772 }
03773
03774 if (temp)
03775 {
03776 append_to_statement_list (*expr_p, pre_p);
03777 *expr_p = temp;
03778 return GS_OK;
03779 }
03780
03781 return GS_ALL_DONE;
03782 }
03783
03784
03785
03786
03787
03788
03789
03790
03791 static enum gimplify_status
03792 gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
03793 {
03794 enum gimplify_status ret = GS_ALL_DONE;
03795 tree val;
03796
03797 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
03798 val = TREE_OPERAND (*expr_p, 0);
03799
03800
03801 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
03802 {
03803
03804
03805
03806 if (TREE_TYPE (val) == void_type_node)
03807 {
03808 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
03809 is_gimple_stmt, fb_none);
03810 append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p);
03811 val = NULL;
03812 }
03813 else
03814 val = get_initialized_tmp_var (val, pre_p, post_p);
03815
03816 TREE_OPERAND (*expr_p, 0) = val;
03817 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
03818 }
03819
03820 *expr_p = val;
03821
03822 return ret;
03823 }
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838 static enum gimplify_status
03839 gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
03840 {
03841 tree expr = *expr_p;
03842 tree op0 = TREE_OPERAND (expr, 0);
03843 enum gimplify_status ret;
03844
03845 switch (TREE_CODE (op0))
03846 {
03847 case INDIRECT_REF:
03848 case MISALIGNED_INDIRECT_REF:
03849 do_indirect_ref:
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859 {
03860 tree op00 = TREE_OPERAND (op0, 0);
03861 tree t_expr = TREE_TYPE (expr);
03862 tree t_op00 = TREE_TYPE (op00);
03863
03864 if (!lang_hooks.types_compatible_p (t_expr, t_op00))
03865 {
03866 #ifdef ENABLE_CHECKING
03867 tree t_op0 = TREE_TYPE (op0);
03868 gcc_assert (POINTER_TYPE_P (t_expr)
03869 && cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE
03870 ? TREE_TYPE (t_op0) : t_op0,
03871 TREE_TYPE (t_expr))
03872 && POINTER_TYPE_P (t_op00)
03873 && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
03874 #endif
03875 op00 = fold_convert (TREE_TYPE (expr), op00);
03876 }
03877 *expr_p = op00;
03878 ret = GS_OK;
03879 }
03880 break;
03881
03882 case VIEW_CONVERT_EXPR:
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
03893 op0 = TREE_OPERAND (op0, 0);
03894
03895 *expr_p = fold_convert (TREE_TYPE (expr),
03896 build_fold_addr_expr (TREE_OPERAND (op0, 0)));
03897 ret = GS_OK;
03898 break;
03899
03900 default:
03901
03902
03903
03904
03905 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
03906 is_gimple_addressable, fb_either);
03907 if (ret != GS_ERROR)
03908 {
03909 op0 = TREE_OPERAND (expr, 0);
03910
03911
03912
03913 if (TREE_CODE (op0) == INDIRECT_REF)
03914 goto do_indirect_ref;
03915
03916
03917
03918 recompute_tree_invariant_for_addr_expr (expr);
03919
03920
03921 lang_hooks.mark_addressable (TREE_OPERAND (expr, 0));
03922 }
03923 break;
03924 }
03925
03926 return ret;
03927 }
03928
03929
03930
03931
03932 static enum gimplify_status
03933 gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
03934 {
03935 tree expr = *expr_p;
03936 int noutputs = list_length (ASM_OUTPUTS (expr));
03937 const char **oconstraints
03938 = (const char **) alloca ((noutputs) * sizeof (const char *));
03939 int i;
03940 tree link;
03941 const char *constraint;
03942 bool allows_mem, allows_reg, is_inout;
03943 enum gimplify_status ret, tret;
03944
03945 ret = GS_ALL_DONE;
03946 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
03947 {
03948 size_t constraint_len;
03949 oconstraints[i] = constraint
03950 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
03951 constraint_len = strlen (constraint);
03952 if (constraint_len == 0)
03953 continue;
03954
03955 parse_output_constraint (&constraint, i, 0, 0,
03956 &allows_mem, &allows_reg, &is_inout);
03957
03958 if (!allows_reg && allows_mem)
03959 lang_hooks.mark_addressable (TREE_VALUE (link));
03960
03961 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
03962 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
03963 fb_lvalue | fb_mayfail);
03964 if (tret == GS_ERROR)
03965 {
03966 error ("invalid lvalue in asm output %d", i);
03967 ret = tret;
03968 }
03969
03970 if (is_inout)
03971 {
03972
03973
03974
03975 tree input;
03976 char buf[10];
03977
03978
03979 char *p = xstrdup (constraint);
03980 p[0] = '=';
03981 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
03982
03983
03984 if (allows_reg)
03985 {
03986 sprintf (buf, "%d", i);
03987
03988
03989
03990
03991
03992 if (strchr (p, ',') != NULL)
03993 {
03994 size_t len = 0, buflen = strlen (buf);
03995 char *beg, *end, *str, *dst;
03996
03997 for (beg = p + 1;;)
03998 {
03999 end = strchr (beg, ',');
04000 if (end == NULL)
04001 end = strchr (beg, '\0');
04002 if ((size_t) (end - beg) < buflen)
04003 len += buflen + 1;
04004 else
04005 len += end - beg + 1;
04006 if (*end)
04007 beg = end + 1;
04008 else
04009 break;
04010 }
04011
04012 str = (char *) alloca (len);
04013 for (beg = p + 1, dst = str;;)
04014 {
04015 const char *tem;
04016 bool mem_p, reg_p, inout_p;
04017
04018 end = strchr (beg, ',');
04019 if (end)
04020 *end = '\0';
04021 beg[-1] = '=';
04022 tem = beg - 1;
04023 parse_output_constraint (&tem, i, 0, 0,
04024 &mem_p, ®_p, &inout_p);
04025 if (dst != str)
04026 *dst++ = ',';
04027 if (reg_p)
04028 {
04029 memcpy (dst, buf, buflen);
04030 dst += buflen;
04031 }
04032 else
04033 {
04034 if (end)
04035 len = end - beg;
04036 else
04037 len = strlen (beg);
04038 memcpy (dst, beg, len);
04039 dst += len;
04040 }
04041 if (end)
04042 beg = end + 1;
04043 else
04044 break;
04045 }
04046 *dst = '\0';
04047 input = build_string (dst - str, str);
04048 }
04049 else
04050 input = build_string (strlen (buf), buf);
04051 }
04052 else
04053 input = build_string (constraint_len - 1, constraint + 1);
04054
04055 free (p);
04056
04057 input = build_tree_list (build_tree_list (NULL_TREE, input),
04058 unshare_expr (TREE_VALUE (link)));
04059 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
04060 }
04061 }
04062
04063 for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
04064 {
04065 constraint
04066 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
04067 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
04068 oconstraints, &allows_mem, &allows_reg);
04069
04070
04071 if (!allows_reg && allows_mem)
04072 {
04073 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
04074 is_gimple_lvalue, fb_lvalue | fb_mayfail);
04075 lang_hooks.mark_addressable (TREE_VALUE (link));
04076 if (tret == GS_ERROR)
04077 {
04078 error ("memory input %d is not directly addressable", i);
04079 ret = tret;
04080 }
04081 }
04082 else
04083 {
04084 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
04085 is_gimple_asm_val, fb_rvalue);
04086 if (tret == GS_ERROR)
04087 ret = tret;
04088 }
04089 }
04090
04091 return ret;
04092 }
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108 static enum gimplify_status
04109 gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
04110 {
04111 tree_stmt_iterator iter;
04112 tree body;
04113
04114 tree temp = voidify_wrapper_expr (*expr_p, NULL);
04115
04116
04117
04118
04119 int old_conds = gimplify_ctxp->conditions;
04120 tree old_cleanups = gimplify_ctxp->conditional_cleanups;
04121 gimplify_ctxp->conditions = 0;
04122 gimplify_ctxp->conditional_cleanups = NULL_TREE;
04123
04124 body = TREE_OPERAND (*expr_p, 0);
04125 gimplify_to_stmt_list (&body);
04126
04127 gimplify_ctxp->conditions = old_conds;
04128 gimplify_ctxp->conditional_cleanups = old_cleanups;
04129
04130 for (iter = tsi_start (body); !tsi_end_p (iter); )
04131 {
04132 tree *wce_p = tsi_stmt_ptr (iter);
04133 tree wce = *wce_p;
04134
04135 if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
04136 {
04137 if (tsi_one_before_end_p (iter))
04138 {
04139 tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT);
04140 tsi_delink (&iter);
04141 break;
04142 }
04143 else
04144 {
04145 tree sl, tfe;
04146 enum tree_code code;
04147
04148 if (CLEANUP_EH_ONLY (wce))
04149 code = TRY_CATCH_EXPR;
04150 else
04151 code = TRY_FINALLY_EXPR;
04152
04153 sl = tsi_split_statement_list_after (&iter);
04154 tfe = build2 (code, void_type_node, sl, NULL_TREE);
04155 append_to_statement_list (TREE_OPERAND (wce, 0),
04156 &TREE_OPERAND (tfe, 1));
04157 *wce_p = tfe;
04158 iter = tsi_start (sl);
04159 }
04160 }
04161 else
04162 tsi_next (&iter);
04163 }
04164
04165 if (temp)
04166 {
04167 *expr_p = temp;
04168 append_to_statement_list (body, pre_p);
04169 return GS_OK;
04170 }
04171 else
04172 {
04173 *expr_p = body;
04174 return GS_ALL_DONE;
04175 }
04176 }
04177
04178
04179
04180
04181 static void
04182 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
04183 {
04184 tree wce;
04185
04186
04187
04188 if (errorcount || sorrycount)
04189 return;
04190
04191 if (gimple_conditional_context ())
04192 {
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214 tree flag = create_tmp_var (boolean_type_node, "cleanup");
04215 tree ffalse = build2 (MODIFY_EXPR, void_type_node, flag,
04216 boolean_false_node);
04217 tree ftrue = build2 (MODIFY_EXPR, void_type_node, flag,
04218 boolean_true_node);
04219 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
04220 wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
04221 append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
04222 append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
04223 append_to_statement_list (ftrue, pre_p);
04224
04225
04226
04227
04228 TREE_NO_WARNING (var) = 1;
04229 }
04230 else
04231 {
04232 wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
04233 CLEANUP_EH_ONLY (wce) = eh_only;
04234 append_to_statement_list (wce, pre_p);
04235 }
04236
04237 gimplify_stmt (&TREE_OPERAND (wce, 0));
04238 }
04239
04240
04241
04242 static enum gimplify_status
04243 gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
04244 {
04245 tree targ = *expr_p;
04246 tree temp = TARGET_EXPR_SLOT (targ);
04247 tree init = TARGET_EXPR_INITIAL (targ);
04248 enum gimplify_status ret;
04249
04250 if (init)
04251 {
04252
04253
04254 gimple_add_tmp_var (temp);
04255
04256
04257
04258 if (VOID_TYPE_P (TREE_TYPE (init)))
04259 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
04260 else
04261 {
04262 init = build2 (INIT_EXPR, void_type_node, temp, init);
04263 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
04264 fb_none);
04265 }
04266 if (ret == GS_ERROR)
04267 {
04268
04269 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
04270 return GS_ERROR;
04271 }
04272 append_to_statement_list (init, pre_p);
04273
04274
04275 if (TARGET_EXPR_CLEANUP (targ))
04276 {
04277 gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
04278 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
04279 CLEANUP_EH_ONLY (targ), pre_p);
04280 #ifdef KEY
04281 if (flag_spin_file) {
04282 EMIT_TARGET_EXPR_CLEANUP(targ) = 1;
04283 if (gspin_invoked (targ))
04284 gs_set_flag_value (targ, GS_EMIT_TARGET_EXPR_CLEANUP, 1);
04285 }
04286 #endif
04287 }
04288
04289
04290 TREE_OPERAND (targ, 3) = init;
04291 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
04292 }
04293 else
04294
04295 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
04296
04297 *expr_p = temp;
04298 return GS_OK;
04299 }
04300
04301
04302
04303
04304
04305
04306 void
04307 gimplify_stmt (tree *stmt_p)
04308 {
04309 gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
04310 }
04311
04312
04313
04314 void
04315 gimplify_to_stmt_list (tree *stmt_p)
04316 {
04317 gimplify_stmt (stmt_p);
04318 if (!*stmt_p)
04319 *stmt_p = alloc_stmt_list ();
04320 else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
04321 {
04322 tree t = *stmt_p;
04323 *stmt_p = alloc_stmt_list ();
04324 append_to_statement_list (t, stmt_p);
04325 }
04326 }
04327
04328
04329
04330
04331
04332
04333 void
04334 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
04335 {
04336 splay_tree_node n;
04337
04338 if (decl == NULL || !DECL_P (decl))
04339 return;
04340
04341 do
04342 {
04343 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
04344 if (n != NULL)
04345 {
04346 if (n->value & GOVD_SHARED)
04347 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
04348 else
04349 return;
04350 }
04351 else if (ctx->is_parallel)
04352 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
04353
04354 ctx = ctx->outer_context;
04355 }
04356 while (ctx);
04357 }
04358
04359
04360
04361 static void
04362 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
04363 {
04364 if (type == NULL || type == error_mark_node)
04365 return;
04366 type = TYPE_MAIN_VARIANT (type);
04367
04368 if (pointer_set_insert (ctx->privatized_types, type))
04369 return;
04370
04371 switch (TREE_CODE (type))
04372 {
04373 case INTEGER_TYPE:
04374 case ENUMERAL_TYPE:
04375 case BOOLEAN_TYPE:
04376 case REAL_TYPE:
04377 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
04378 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
04379 break;
04380
04381 case ARRAY_TYPE:
04382 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
04383 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
04384 break;
04385
04386 case RECORD_TYPE:
04387 case UNION_TYPE:
04388 case QUAL_UNION_TYPE:
04389 {
04390 tree field;
04391 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
04392 if (TREE_CODE (field) == FIELD_DECL)
04393 {
04394 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
04395 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
04396 }
04397 }
04398 break;
04399
04400 case POINTER_TYPE:
04401 case REFERENCE_TYPE:
04402 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
04403 break;
04404
04405 default:
04406 break;
04407 }
04408
04409 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
04410 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
04411 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
04412 }
04413
04414
04415
04416 static void
04417 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
04418 {
04419 splay_tree_node n;
04420 unsigned int nflags;
04421 tree t;
04422
04423 if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
04424 return;
04425
04426
04427
04428 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
04429 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
04430 flags |= GOVD_SEEN;
04431
04432 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
04433 if (n != NULL)
04434 {
04435
04436
04437 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
04438
04439
04440 nflags = n->value | flags;
04441 gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
04442 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
04443 n->value = nflags;
04444 return;
04445 }
04446
04447
04448
04449
04450 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
04451 {
04452
04453
04454
04455
04456 if (!(flags & GOVD_LOCAL))
04457 {
04458 nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
04459 nflags |= flags & GOVD_SEEN;
04460 t = DECL_VALUE_EXPR (decl);
04461 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
04462 t = TREE_OPERAND (t, 0);
04463 gcc_assert (DECL_P (t));
04464 omp_add_variable (ctx, t, nflags);
04465 }
04466
04467
04468
04469 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
04470 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
04471 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
04472
04473
04474
04475
04476 if (flags & GOVD_SHARED)
04477 flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
04478 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
04479
04480
04481
04482
04483
04484
04485
04486
04487 else if (! (flags & GOVD_LOCAL))
04488 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
04489 }
04490 else if (lang_hooks.decls.omp_privatize_by_reference (decl))
04491 {
04492 gcc_assert ((flags & GOVD_LOCAL) == 0);
04493 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
04494
04495
04496
04497 if ((flags & GOVD_SHARED) == 0)
04498 {
04499 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
04500 if (TREE_CODE (t) != INTEGER_CST)
04501 omp_notice_variable (ctx, t, true);
04502 }
04503 }
04504
04505 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
04506 }
04507
04508
04509
04510
04511
04512
04513
04514 static bool
04515 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
04516 {
04517 splay_tree_node n;
04518 unsigned flags = in_code ? GOVD_SEEN : 0;
04519 bool ret = false, shared;
04520
04521 if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
04522 return false;
04523
04524
04525 if (is_global_var (decl))
04526 {
04527 if (DECL_THREAD_LOCAL_P (decl))
04528 return false;
04529
04530 if (DECL_HAS_VALUE_EXPR_P (decl))
04531 {
04532 tree value = get_base_address (DECL_VALUE_EXPR (decl));
04533
04534 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
04535 return false;
04536 }
04537 }
04538
04539 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
04540 if (n == NULL)
04541 {
04542 enum omp_clause_default_kind default_kind, kind;
04543
04544 if (!ctx->is_parallel)
04545 goto do_outer;
04546
04547
04548
04549
04550 default_kind = ctx->default_kind;
04551 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
04552 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
04553 default_kind = kind;
04554
04555 switch (default_kind)
04556 {
04557 case OMP_CLAUSE_DEFAULT_NONE:
04558 error ("%qs not specified in enclosing parallel",
04559 IDENTIFIER_POINTER (DECL_NAME (decl)));
04560 error ("%Henclosing parallel", &ctx->location);
04561
04562 case OMP_CLAUSE_DEFAULT_SHARED:
04563 flags |= GOVD_SHARED;
04564 break;
04565 case OMP_CLAUSE_DEFAULT_PRIVATE:
04566 flags |= GOVD_PRIVATE;
04567 break;
04568 default:
04569 gcc_unreachable ();
04570 }
04571
04572 omp_add_variable (ctx, decl, flags);
04573
04574 shared = (flags & GOVD_SHARED) != 0;
04575 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
04576 goto do_outer;
04577 }
04578
04579 shared = ((flags | n->value) & GOVD_SHARED) != 0;
04580 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
04581
04582
04583 if ((n->value & flags) == flags)
04584 return ret;
04585 flags |= n->value;
04586 n->value = flags;
04587
04588 do_outer:
04589
04590
04591 if (flags & GOVD_PRIVATE)
04592 return ret;
04593 if (ctx->outer_context
04594 && omp_notice_variable (ctx->outer_context, decl, in_code))
04595 return true;
04596 return ret;
04597 }
04598
04599
04600
04601
04602 static bool
04603 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
04604 {
04605 splay_tree_node n;
04606
04607 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
04608 if (n != NULL)
04609 {
04610 if (n->value & GOVD_SHARED)
04611 {
04612 if (ctx == gimplify_omp_ctxp)
04613 {
04614 error ("iteration variable %qs should be private",
04615 IDENTIFIER_POINTER (DECL_NAME (decl)));
04616 n->value = GOVD_PRIVATE;
04617 return true;
04618 }
04619 else
04620 return false;
04621 }
04622 else if ((n->value & GOVD_EXPLICIT) != 0
04623 && (ctx == gimplify_omp_ctxp
04624 || (ctx->is_combined_parallel
04625 && gimplify_omp_ctxp->outer_context == ctx)))
04626 {
04627 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
04628 error ("iteration variable %qs should not be firstprivate",
04629 IDENTIFIER_POINTER (DECL_NAME (decl)));
04630 else if ((n->value & GOVD_REDUCTION) != 0)
04631 error ("iteration variable %qs should not be reduction",
04632 IDENTIFIER_POINTER (DECL_NAME (decl)));
04633 }
04634 return true;
04635 }
04636
04637 if (ctx->is_parallel)
04638 return false;
04639 else if (ctx->outer_context)
04640 return omp_is_private (ctx->outer_context, decl);
04641 else
04642 return !is_global_var (decl);
04643 }
04644
04645
04646
04647
04648
04649 static bool
04650 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
04651 {
04652 splay_tree_node n;
04653
04654 do
04655 {
04656 ctx = ctx->outer_context;
04657 if (ctx == NULL)
04658 return !(is_global_var (decl)
04659
04660 || lang_hooks.decls.omp_privatize_by_reference (decl));
04661
04662 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
04663 if (n != NULL)
04664 return (n->value & GOVD_SHARED) == 0;
04665 }
04666 while (!ctx->is_parallel);
04667 return false;
04668 }
04669
04670
04671
04672
04673 static void
04674 gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
04675 bool in_combined_parallel)
04676 {
04677 struct gimplify_omp_ctx *ctx, *outer_ctx;
04678 tree c;
04679
04680 ctx = new_omp_context (in_parallel, in_combined_parallel);
04681 outer_ctx = ctx->outer_context;
04682
04683 while ((c = *list_p) != NULL)
04684 {
04685 enum gimplify_status gs;
04686 bool remove = false;
04687 bool notice_outer = true;
04688 const char *check_non_private = NULL;
04689 unsigned int flags;
04690 tree decl;
04691
04692 switch (OMP_CLAUSE_CODE (c))
04693 {
04694 case OMP_CLAUSE_PRIVATE:
04695 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
04696 notice_outer = false;
04697 goto do_add;
04698 case OMP_CLAUSE_SHARED:
04699 flags = GOVD_SHARED | GOVD_EXPLICIT;
04700 goto do_add;
04701 case OMP_CLAUSE_FIRSTPRIVATE:
04702 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
04703 check_non_private = "firstprivate";
04704 goto do_add;
04705 case OMP_CLAUSE_LASTPRIVATE:
04706 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
04707 check_non_private = "lastprivate";
04708 goto do_add;
04709 case OMP_CLAUSE_REDUCTION:
04710 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
04711 check_non_private = "reduction";
04712 goto do_add;
04713
04714 do_add:
04715 decl = OMP_CLAUSE_DECL (c);
04716 if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
04717 {
04718 remove = true;
04719 break;
04720 }
04721 omp_add_variable (ctx, decl, flags);
04722 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
04723 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
04724 {
04725 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
04726 GOVD_LOCAL | GOVD_SEEN);
04727 gimplify_omp_ctxp = ctx;
04728 push_gimplify_context ();
04729 gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c));
04730 pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c));
04731 push_gimplify_context ();
04732 gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c));
04733 pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
04734 gimplify_omp_ctxp = outer_ctx;
04735 }
04736 if (notice_outer)
04737 goto do_notice;
04738 break;
04739
04740 case OMP_CLAUSE_COPYIN:
04741 case OMP_CLAUSE_COPYPRIVATE:
04742 decl = OMP_CLAUSE_DECL (c);
04743 if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
04744 {
04745 remove = true;
04746 break;
04747 }
04748 do_notice:
04749 if (outer_ctx)
04750 omp_notice_variable (outer_ctx, decl, true);
04751 if (check_non_private
04752 && !in_parallel
04753 && omp_check_private (ctx, decl))
04754 {
04755 error ("%s variable %qs is private in outer context",
04756 check_non_private, IDENTIFIER_POINTER (DECL_NAME (decl)));
04757 remove = true;
04758 }
04759 break;
04760
04761 case OMP_CLAUSE_IF:
04762 OMP_CLAUSE_OPERAND (c, 0)
04763 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
04764
04765
04766 case OMP_CLAUSE_SCHEDULE:
04767 case OMP_CLAUSE_NUM_THREADS:
04768 gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
04769 is_gimple_val, fb_rvalue);
04770 if (gs == GS_ERROR)
04771 remove = true;
04772 break;
04773
04774 case OMP_CLAUSE_NOWAIT:
04775 case OMP_CLAUSE_ORDERED:
04776 break;
04777
04778 case OMP_CLAUSE_DEFAULT:
04779 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
04780 break;
04781
04782 default:
04783 gcc_unreachable ();
04784 }
04785
04786 if (remove)
04787 *list_p = OMP_CLAUSE_CHAIN (c);
04788 else
04789 list_p = &OMP_CLAUSE_CHAIN (c);
04790 }
04791
04792 gimplify_omp_ctxp = ctx;
04793 }
04794
04795
04796
04797
04798 static int
04799 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
04800 {
04801 tree *list_p = (tree *) data;
04802 tree decl = (tree) n->key;
04803 unsigned flags = n->value;
04804 enum omp_clause_code code;
04805 tree clause;
04806 bool private_debug;
04807
04808 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
04809 return 0;
04810 if ((flags & GOVD_SEEN) == 0)
04811 return 0;
04812 if (flags & GOVD_DEBUG_PRIVATE)
04813 {
04814 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
04815 private_debug = true;
04816 }
04817 else
04818 private_debug
04819 = lang_hooks.decls.omp_private_debug_clause (decl,
04820 !!(flags & GOVD_SHARED));
04821 if (private_debug)
04822 code = OMP_CLAUSE_PRIVATE;
04823 else if (flags & GOVD_SHARED)
04824 {
04825 if (is_global_var (decl))
04826 return 0;
04827 code = OMP_CLAUSE_SHARED;
04828 }
04829 else if (flags & GOVD_PRIVATE)
04830 code = OMP_CLAUSE_PRIVATE;
04831 else if (flags & GOVD_FIRSTPRIVATE)
04832 code = OMP_CLAUSE_FIRSTPRIVATE;
04833 else
04834 gcc_unreachable ();
04835
04836 clause = build_omp_clause (code);
04837 OMP_CLAUSE_DECL (clause) = decl;
04838 OMP_CLAUSE_CHAIN (clause) = *list_p;
04839 if (private_debug)
04840 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
04841 *list_p = clause;
04842
04843 return 0;
04844 }
04845
04846 static void
04847 gimplify_adjust_omp_clauses (tree *list_p)
04848 {
04849 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
04850 tree c, decl;
04851
04852 while ((c = *list_p) != NULL)
04853 {
04854 splay_tree_node n;
04855 bool remove = false;
04856
04857 switch (OMP_CLAUSE_CODE (c))
04858 {
04859 case OMP_CLAUSE_PRIVATE:
04860 case OMP_CLAUSE_SHARED:
04861 case OMP_CLAUSE_FIRSTPRIVATE:
04862 decl = OMP_CLAUSE_DECL (c);
04863 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
04864 remove = !(n->value & GOVD_SEEN);
04865 if (! remove)
04866 {
04867 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
04868 if ((n->value & GOVD_DEBUG_PRIVATE)
04869 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
04870 {
04871 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
04872 || ((n->value & GOVD_DATA_SHARE_CLASS)
04873 == GOVD_PRIVATE));
04874 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
04875 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
04876 }
04877 }
04878 break;
04879
04880 case OMP_CLAUSE_LASTPRIVATE:
04881
04882
04883 decl = OMP_CLAUSE_DECL (c);
04884 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
04885 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
04886 = (n->value & GOVD_FIRSTPRIVATE) != 0;
04887 break;
04888
04889 case OMP_CLAUSE_REDUCTION:
04890 case OMP_CLAUSE_COPYIN:
04891 case OMP_CLAUSE_COPYPRIVATE:
04892 case OMP_CLAUSE_IF:
04893 case OMP_CLAUSE_NUM_THREADS:
04894 case OMP_CLAUSE_SCHEDULE:
04895 case OMP_CLAUSE_NOWAIT:
04896 case OMP_CLAUSE_ORDERED:
04897 case OMP_CLAUSE_DEFAULT:
04898 break;
04899
04900 default:
04901 gcc_unreachable ();
04902 }
04903
04904 if (remove)
04905 *list_p = OMP_CLAUSE_CHAIN (c);
04906 else
04907 list_p = &OMP_CLAUSE_CHAIN (c);
04908 }
04909
04910
04911 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, list_p);
04912
04913 gimplify_omp_ctxp = ctx->outer_context;
04914 delete_omp_context (ctx);
04915 }
04916
04917
04918
04919
04920
04921
04922 static enum gimplify_status
04923 gimplify_omp_parallel (tree *expr_p, tree *pre_p)
04924 {
04925 tree expr = *expr_p;
04926
04927 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, true,
04928 OMP_PARALLEL_COMBINED (expr));
04929
04930 push_gimplify_context ();
04931
04932 gimplify_stmt (&OMP_PARALLEL_BODY (expr));
04933
04934 if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
04935 pop_gimplify_context (OMP_PARALLEL_BODY (expr));
04936 else
04937 pop_gimplify_context (NULL_TREE);
04938
04939 gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
04940
04941 return GS_ALL_DONE;
04942 }
04943
04944
04945
04946 static enum gimplify_status
04947 gimplify_omp_for (tree *expr_p, tree *pre_p)
04948 {
04949 tree for_stmt, decl, t;
04950 enum gimplify_status ret = 0;
04951
04952 for_stmt = *expr_p;
04953
04954 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false, false);
04955
04956 t = OMP_FOR_INIT (for_stmt);
04957 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
04958 decl = TREE_OPERAND (t, 0);
04959 gcc_assert (DECL_P (decl));
04960 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)));
04961
04962
04963 if (omp_is_private (gimplify_omp_ctxp, decl))
04964 omp_notice_variable (gimplify_omp_ctxp, decl, true);
04965 else
04966 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
04967
04968 ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
04969 NULL, is_gimple_val, fb_rvalue);
04970
04971 t = OMP_FOR_COND (for_stmt);
04972 gcc_assert (COMPARISON_CLASS_P (t));
04973 gcc_assert (TREE_OPERAND (t, 0) == decl);
04974
04975 ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
04976 NULL, is_gimple_val, fb_rvalue);
04977
04978 t = OMP_FOR_INCR (for_stmt);
04979 switch (TREE_CODE (t))
04980 {
04981 case PREINCREMENT_EXPR:
04982 case POSTINCREMENT_EXPR:
04983 t = build_int_cst (TREE_TYPE (decl), 1);
04984 goto build_modify;
04985 case PREDECREMENT_EXPR:
04986 case POSTDECREMENT_EXPR:
04987 t = build_int_cst (TREE_TYPE (decl), -1);
04988 goto build_modify;
04989 build_modify:
04990 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
04991 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
04992 OMP_FOR_INCR (for_stmt) = t;
04993 break;
04994
04995 case MODIFY_EXPR:
04996 gcc_assert (TREE_OPERAND (t, 0) == decl);
04997 t = TREE_OPERAND (t, 1);
04998 switch (TREE_CODE (t))
04999 {
05000 case PLUS_EXPR:
05001 if (TREE_OPERAND (t, 1) == decl)
05002 {
05003 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
05004 TREE_OPERAND (t, 0) = decl;
05005 break;
05006 }
05007 case MINUS_EXPR:
05008 gcc_assert (TREE_OPERAND (t, 0) == decl);
05009 break;
05010 default:
05011 gcc_unreachable ();
05012 }
05013
05014 ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
05015 NULL, is_gimple_val, fb_rvalue);
05016 break;
05017
05018 default:
05019 gcc_unreachable ();
05020 }
05021
05022 gimplify_to_stmt_list (&OMP_FOR_BODY (for_stmt));
05023 gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
05024
05025 return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
05026 }
05027
05028
05029
05030
05031 static enum gimplify_status
05032 gimplify_omp_workshare (tree *expr_p, tree *pre_p)
05033 {
05034 tree stmt = *expr_p;
05035
05036 gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false);
05037 gimplify_to_stmt_list (&OMP_BODY (stmt));
05038 gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt));
05039
05040 return GS_ALL_DONE;
05041 }
05042
05043
05044
05045
05046
05047 static bool
05048 goa_lhs_expr_p (tree expr, tree addr)
05049 {
05050
05051
05052
05053 while ((TREE_CODE (expr) == NOP_EXPR
05054 || TREE_CODE (expr) == CONVERT_EXPR
05055 || TREE_CODE (expr) == NON_LVALUE_EXPR)
05056 && TREE_OPERAND (expr, 0) != error_mark_node
05057 && (TYPE_MAIN_VARIANT (TREE_TYPE (expr))
05058 == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0)))))
05059 expr = TREE_OPERAND (expr, 0);
05060
05061 if (TREE_CODE (expr) == INDIRECT_REF && TREE_OPERAND (expr, 0) == addr)
05062 return true;
05063 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
05064 return true;
05065 return false;
05066 }
05067
05068
05069
05070
05071
05072
05073 static enum gimplify_status
05074 gimplify_omp_atomic_fetch_op (tree *expr_p, tree addr, tree rhs, int index)
05075 {
05076 enum built_in_function base;
05077 tree decl, args, itype;
05078 enum insn_code *optab;
05079
05080
05081 switch (TREE_CODE (rhs))
05082 {
05083 case PLUS_EXPR:
05084 base = BUILT_IN_FETCH_AND_ADD_N;
05085 optab = sync_add_optab;
05086 break;
05087 case MINUS_EXPR:
05088 base = BUILT_IN_FETCH_AND_SUB_N;
05089 optab = sync_add_optab;
05090 break;
05091 case BIT_AND_EXPR:
05092 base = BUILT_IN_FETCH_AND_AND_N;
05093 optab = sync_and_optab;
05094 break;
05095 case BIT_IOR_EXPR:
05096 base = BUILT_IN_FETCH_AND_OR_N;
05097 optab = sync_ior_optab;
05098 break;
05099 case BIT_XOR_EXPR:
05100 base = BUILT_IN_FETCH_AND_XOR_N;
05101 optab = sync_xor_optab;
05102 break;
05103 default:
05104 return GS_UNHANDLED;
05105 }
05106
05107
05108 if (goa_lhs_expr_p (TREE_OPERAND (rhs, 0), addr))
05109 rhs = TREE_OPERAND (rhs, 1);
05110 else if (commutative_tree_code (TREE_CODE (rhs))
05111 && goa_lhs_expr_p (TREE_OPERAND (rhs, 1), addr))
05112 rhs = TREE_OPERAND (rhs, 0);
05113 else
05114 return GS_UNHANDLED;
05115
05116 decl = built_in_decls[base + index + 1];
05117 itype = TREE_TYPE (TREE_TYPE (decl));
05118
05119 if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing)
05120 return GS_UNHANDLED;
05121
05122 args = tree_cons (NULL, fold_convert (itype, rhs), NULL);
05123 args = tree_cons (NULL, addr, args);
05124 *expr_p = build_function_call_expr (decl, args);
05125 return GS_OK;
05126 }
05127
05128
05129
05130
05131
05132
05133 static int
05134 goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
05135 {
05136 tree expr = *expr_p;
05137 int saw_lhs;
05138
05139 if (goa_lhs_expr_p (expr, lhs_addr))
05140 {
05141 *expr_p = lhs_var;
05142 return 1;
05143 }
05144 if (is_gimple_val (expr))
05145 return 0;
05146
05147 saw_lhs = 0;
05148 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
05149 {
05150 case tcc_binary:
05151 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
05152 lhs_addr, lhs_var);
05153 case tcc_unary:
05154 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
05155 lhs_addr, lhs_var);
05156 break;
05157 default:
05158 break;
05159 }
05160
05161 if (saw_lhs == 0)
05162 {
05163 enum gimplify_status gs;
05164 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
05165 if (gs != GS_ALL_DONE)
05166 saw_lhs = -1;
05167 }
05168
05169 return saw_lhs;
05170 }
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184 static enum gimplify_status
05185 gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
05186 tree rhs, int index)
05187 {
05188 tree oldval, oldival, oldival2, newval, newival, label;
05189 tree type, itype, cmpxchg, args, x, iaddr;
05190
05191 cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1];
05192 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
05193 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
05194
05195 if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing)
05196 return GS_UNHANDLED;
05197
05198 oldval = create_tmp_var (type, NULL);
05199 newval = create_tmp_var (type, NULL);
05200
05201
05202
05203 if (goa_stabilize_expr (&rhs, pre_p, addr, oldval) < 0)
05204 return GS_ERROR;
05205
05206 x = build_fold_indirect_ref (addr);
05207 x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
05208 gimplify_and_add (x, pre_p);
05209
05210
05211
05212
05213 if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
05214 {
05215 oldival = oldval;
05216 newival = newval;
05217 iaddr = addr;
05218 }
05219 else
05220 {
05221 oldival = create_tmp_var (itype, NULL);
05222 newival = create_tmp_var (itype, NULL);
05223
05224 x = build1 (VIEW_CONVERT_EXPR, itype, oldval);
05225 x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
05226 gimplify_and_add (x, pre_p);
05227 iaddr = fold_convert (build_pointer_type (itype), addr);
05228 }
05229
05230 oldival2 = create_tmp_var (itype, NULL);
05231
05232 label = create_artificial_label ();
05233 x = build1 (LABEL_EXPR, void_type_node, label);
05234 gimplify_and_add (x, pre_p);
05235
05236 x = build2 (MODIFY_EXPR, void_type_node, newval, rhs);
05237 gimplify_and_add (x, pre_p);
05238
05239 if (newval != newival)
05240 {
05241 x = build1 (VIEW_CONVERT_EXPR, itype, newval);
05242 x = build2 (MODIFY_EXPR, void_type_node, newival, x);
05243 gimplify_and_add (x, pre_p);
05244 }
05245
05246 x = build2 (MODIFY_EXPR, void_type_node, oldival2,
05247 fold_convert (itype, oldival));
05248 gimplify_and_add (x, pre_p);
05249
05250 args = tree_cons (NULL, fold_convert (itype, newival), NULL);
05251 args = tree_cons (NULL, fold_convert (itype, oldival), args);
05252 args = tree_cons (NULL, iaddr, args);
05253 x = build_function_call_expr (cmpxchg, args);
05254 if (oldval == oldival)
05255 x = fold_convert (type, x);
05256 x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
05257 gimplify_and_add (x, pre_p);
05258
05259
05260 if (oldval != oldival)
05261 {
05262 x = build1 (VIEW_CONVERT_EXPR, type, oldival);
05263 x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
05264 gimplify_and_add (x, pre_p);
05265 }
05266
05267
05268
05269
05270 x = build3 (COND_EXPR, void_type_node,
05271 build2 (NE_EXPR, boolean_type_node, oldival, oldival2),
05272 build1 (GOTO_EXPR, void_type_node, label), NULL);
05273 gimplify_and_add (x, pre_p);
05274
05275 *expr_p = NULL;
05276 return GS_ALL_DONE;
05277 }
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291 static enum gimplify_status
05292 gimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs)
05293 {
05294 tree t;
05295
05296 t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
05297 t = build_function_call_expr (t, NULL);
05298 gimplify_and_add (t, pre_p);
05299
05300 t = build_fold_indirect_ref (addr);
05301 t = build2 (MODIFY_EXPR, void_type_node, t, rhs);
05302 gimplify_and_add (t, pre_p);
05303
05304 t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
05305 t = build_function_call_expr (t, NULL);
05306 gimplify_and_add (t, pre_p);
05307
05308 *expr_p = NULL;
05309 return GS_ALL_DONE;
05310 }
05311
05312
05313
05314 static enum gimplify_status
05315 gimplify_omp_atomic (tree *expr_p, tree *pre_p)
05316 {
05317 tree addr = TREE_OPERAND (*expr_p, 0);
05318 tree rhs = TREE_OPERAND (*expr_p, 1);
05319 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
05320 HOST_WIDE_INT index;
05321
05322
05323 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
05324 index = exact_log2 (index);
05325 if (index >= 0 && index <= 4)
05326 {
05327 enum gimplify_status gs;
05328 unsigned int align;
05329
05330 if (DECL_P (TREE_OPERAND (addr, 0)))
05331 align = DECL_ALIGN_UNIT (TREE_OPERAND (addr, 0));
05332 else if (TREE_CODE (TREE_OPERAND (addr, 0)) == COMPONENT_REF
05333 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (addr, 0), 1))
05334 == FIELD_DECL)
05335 align = DECL_ALIGN_UNIT (TREE_OPERAND (TREE_OPERAND (addr, 0), 1));
05336 else
05337 align = TYPE_ALIGN_UNIT (type);
05338
05339
05340 if (exact_log2 (align) >= index)
05341 {
05342
05343 if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
05344 {
05345 gs = gimplify_omp_atomic_fetch_op (expr_p, addr, rhs, index);
05346 if (gs != GS_UNHANDLED)
05347 return gs;
05348 }
05349
05350
05351
05352 gs = gimplify_omp_atomic_pipeline (expr_p, pre_p, addr, rhs, index);
05353 if (gs != GS_UNHANDLED)
05354 return gs;
05355 }
05356 }
05357
05358
05359 return gimplify_omp_atomic_mutex (expr_p, pre_p, addr, rhs);
05360 }
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391 enum gimplify_status
05392 gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
05393 bool (* gimple_test_f) (tree), fallback_t fallback)
05394 {
05395 tree tmp;
05396 tree internal_pre = NULL_TREE;
05397 tree internal_post = NULL_TREE;
05398 tree save_expr;
05399 int is_statement = (pre_p == NULL);
05400 location_t saved_location;
05401 enum gimplify_status ret;
05402
05403 save_expr = *expr_p;
05404 if (save_expr == NULL_TREE)
05405 return GS_ALL_DONE;
05406
05407
05408
05409
05410
05411
05412
05413 if (pre_p == NULL)
05414 pre_p = &internal_pre;
05415 if (post_p == NULL)
05416 post_p = &internal_post;
05417
05418 saved_location = input_location;
05419 if (save_expr != error_mark_node
05420 && EXPR_HAS_LOCATION (*expr_p))
05421 input_location = EXPR_LOCATION (*expr_p);
05422
05423
05424
05425 do
05426 {
05427
05428
05429 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
05430
05431
05432 save_expr = *expr_p;
05433
05434
05435 if (save_expr == error_mark_node
05436 || (TREE_TYPE (save_expr)
05437 && TREE_TYPE (save_expr) == error_mark_node))
05438 {
05439 ret = GS_ERROR;
05440 break;
05441 }
05442
05443
05444 ret = lang_hooks.gimplify_expr (expr_p, pre_p, post_p);
05445 if (ret == GS_OK)
05446 {
05447 if (*expr_p == NULL_TREE)
05448 break;
05449 if (*expr_p != save_expr)
05450 continue;
05451 }
05452 else if (ret != GS_UNHANDLED)
05453 break;
05454
05455 ret = GS_OK;
05456 switch (TREE_CODE (*expr_p))
05457 {
05458
05459
05460 case POSTINCREMENT_EXPR:
05461 case POSTDECREMENT_EXPR:
05462 case PREINCREMENT_EXPR:
05463 case PREDECREMENT_EXPR:
05464 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
05465 fallback != fb_none);
05466 break;
05467
05468 case ARRAY_REF:
05469 case ARRAY_RANGE_REF:
05470 case REALPART_EXPR:
05471 case IMAGPART_EXPR:
05472 case COMPONENT_REF:
05473 case VIEW_CONVERT_EXPR:
05474 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
05475 fallback ? fallback : fb_rvalue);
05476 break;
05477
05478 case COND_EXPR:
05479 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
05480
05481
05482
05483
05484 if (fallback == fb_lvalue)
05485 {
05486 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
05487 lang_hooks.mark_addressable (*expr_p);
05488 }
05489 break;
05490
05491 case CALL_EXPR:
05492 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
05493
05494
05495
05496
05497 if (fallback == fb_lvalue)
05498 {
05499 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
05500 lang_hooks.mark_addressable (*expr_p);
05501 }
05502 break;
05503
05504 case TREE_LIST:
05505 gcc_unreachable ();
05506
05507 case COMPOUND_EXPR:
05508 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
05509 break;
05510
05511 case MODIFY_EXPR:
05512 case INIT_EXPR:
05513 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
05514 fallback != fb_none);
05515
05516
05517
05518 if (*expr_p && TREE_CODE (*expr_p) == INIT_EXPR)
05519 TREE_SET_CODE (*expr_p, MODIFY_EXPR);
05520 break;
05521
05522 case TRUTH_ANDIF_EXPR:
05523 case TRUTH_ORIF_EXPR:
05524 ret = gimplify_boolean_expr (expr_p);
05525 break;
05526
05527 case TRUTH_NOT_EXPR:
05528 TREE_OPERAND (*expr_p, 0)
05529 = gimple_boolify (TREE_OPERAND (*expr_p, 0));
05530 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05531 is_gimple_val, fb_rvalue);
05532 recalculate_side_effects (*expr_p);
05533 break;
05534
05535 case ADDR_EXPR:
05536 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
05537 break;
05538
05539 case VA_ARG_EXPR:
05540 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
05541 break;
05542
05543 case CONVERT_EXPR:
05544 case NOP_EXPR:
05545 if (IS_EMPTY_STMT (*expr_p))
05546 {
05547 ret = GS_ALL_DONE;
05548 break;
05549 }
05550
05551 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
05552 || fallback == fb_none)
05553 {
05554
05555
05556 *expr_p = TREE_OPERAND (*expr_p, 0);
05557 break;
05558 }
05559
05560 ret = gimplify_conversion (expr_p);
05561 if (ret == GS_ERROR)
05562 break;
05563 if (*expr_p != save_expr)
05564 break;
05565
05566
05567 case FIX_TRUNC_EXPR:
05568 case FIX_CEIL_EXPR:
05569 case FIX_FLOOR_EXPR:
05570 case FIX_ROUND_EXPR:
05571
05572 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05573 is_gimple_val, fb_rvalue);
05574 recalculate_side_effects (*expr_p);
05575 break;
05576
05577 case INDIRECT_REF:
05578 *expr_p = fold_indirect_ref (*expr_p);
05579 if (*expr_p != save_expr)
05580 break;
05581
05582 case ALIGN_INDIRECT_REF:
05583 case MISALIGNED_INDIRECT_REF:
05584 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05585 is_gimple_reg, fb_rvalue);
05586 recalculate_side_effects (*expr_p);
05587 break;
05588
05589
05590 case INTEGER_CST:
05591 case REAL_CST:
05592 case STRING_CST:
05593 case COMPLEX_CST:
05594 case VECTOR_CST:
05595 ret = GS_ALL_DONE;
05596 break;
05597
05598 case CONST_DECL:
05599
05600
05601
05602
05603 if (fallback & fb_lvalue)
05604 ret = GS_ALL_DONE;
05605 else
05606 *expr_p = DECL_INITIAL (*expr_p);
05607 break;
05608
05609 case DECL_EXPR:
05610 ret = gimplify_decl_expr (expr_p);
05611 break;
05612
05613 case EXC_PTR_EXPR:
05614
05615 ret = GS_ALL_DONE;
05616 break;
05617
05618 case BIND_EXPR:
05619 ret = gimplify_bind_expr (expr_p, pre_p);
05620 break;
05621
05622 case LOOP_EXPR:
05623 ret = gimplify_loop_expr (expr_p, pre_p);
05624 break;
05625
05626 case SWITCH_EXPR:
05627 ret = gimplify_switch_expr (expr_p, pre_p);
05628 break;
05629
05630 case EXIT_EXPR:
05631 ret = gimplify_exit_expr (expr_p);
05632 break;
05633
05634 case GOTO_EXPR:
05635
05636
05637 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
05638 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
05639 NULL, is_gimple_val, fb_rvalue);
05640 break;
05641
05642 case LABEL_EXPR:
05643 ret = GS_ALL_DONE;
05644 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
05645 == current_function_decl);
05646 break;
05647
05648 case CASE_LABEL_EXPR:
05649 ret = gimplify_case_label_expr (expr_p);
05650 break;
05651
05652 case RETURN_EXPR:
05653 ret = gimplify_return_expr (*expr_p, pre_p);
05654 break;
05655
05656 case CONSTRUCTOR:
05657
05658
05659
05660 if (fallback == fb_none)
05661 {
05662 unsigned HOST_WIDE_INT ix;
05663 constructor_elt *ce;
05664 tree temp = NULL_TREE;
05665 for (ix = 0;
05666 VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (*expr_p),
05667 ix, ce);
05668 ix++)
05669 if (TREE_SIDE_EFFECTS (ce->value))
05670 append_to_statement_list (ce->value, &temp);
05671
05672 *expr_p = temp;
05673 ret = GS_OK;
05674 }
05675
05676
05677
05678
05679 else if (fallback == fb_lvalue)
05680 {
05681 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
05682 lang_hooks.mark_addressable (*expr_p);
05683 }
05684 else
05685 ret = GS_ALL_DONE;
05686 break;
05687
05688
05689
05690
05691
05692
05693 case SAVE_EXPR:
05694 ret = gimplify_save_expr (expr_p, pre_p, post_p);
05695 break;
05696
05697 case BIT_FIELD_REF:
05698 {
05699 enum gimplify_status r0, r1, r2;
05700
05701 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05702 is_gimple_lvalue, fb_either);
05703 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
05704 is_gimple_val, fb_rvalue);
05705 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
05706 is_gimple_val, fb_rvalue);
05707 recalculate_side_effects (*expr_p);
05708
05709 ret = MIN (r0, MIN (r1, r2));
05710 }
05711 break;
05712
05713 case NON_LVALUE_EXPR:
05714
05715 gcc_unreachable ();
05716
05717 case ASM_EXPR:
05718 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
05719 break;
05720
05721 case TRY_FINALLY_EXPR:
05722 case TRY_CATCH_EXPR:
05723 gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0));
05724 gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1));
05725 ret = GS_ALL_DONE;
05726 break;
05727
05728 case CLEANUP_POINT_EXPR:
05729 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
05730 break;
05731
05732 case TARGET_EXPR:
05733 ret = gimplify_target_expr (expr_p, pre_p, post_p);
05734 break;
05735
05736 case CATCH_EXPR:
05737 gimplify_to_stmt_list (&CATCH_BODY (*expr_p));
05738 ret = GS_ALL_DONE;
05739 break;
05740
05741 case EH_FILTER_EXPR:
05742 gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p));
05743 ret = GS_ALL_DONE;
05744 break;
05745
05746 case OBJ_TYPE_REF:
05747 {
05748 enum gimplify_status r0, r1;
05749 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
05750 is_gimple_val, fb_rvalue);
05751 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
05752 is_gimple_val, fb_rvalue);
05753 ret = MIN (r0, r1);
05754 }
05755 break;
05756
05757 case LABEL_DECL:
05758
05759
05760
05761 FORCED_LABEL (*expr_p) = 1;
05762 ret = GS_ALL_DONE;
05763 break;
05764
05765 case STATEMENT_LIST:
05766 ret = gimplify_statement_list (expr_p, pre_p);
05767 break;
05768
05769 case WITH_SIZE_EXPR:
05770 {
05771 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
05772 post_p == &internal_post ? NULL : post_p,
05773 gimple_test_f, fallback);
05774 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
05775 is_gimple_val, fb_rvalue);
05776 }
05777 break;
05778
05779 case VAR_DECL:
05780 case PARM_DECL:
05781 ret = gimplify_var_or_parm_decl (expr_p);
05782 break;
05783
05784 case RESULT_DECL:
05785
05786 if (gimplify_omp_ctxp)
05787 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
05788 ret = GS_ALL_DONE;
05789 break;
05790
05791 case SSA_NAME:
05792
05793 ret = GS_ALL_DONE;
05794 break;
05795
05796 case OMP_PARALLEL:
05797 ret = gimplify_omp_parallel (expr_p, pre_p);
05798 break;
05799
05800 case OMP_FOR:
05801 ret = gimplify_omp_for (expr_p, pre_p);
05802 break;
05803
05804 case OMP_SECTIONS:
05805 case OMP_SINGLE:
05806 ret = gimplify_omp_workshare (expr_p, pre_p);
05807 break;
05808
05809 case OMP_SECTION:
05810 case OMP_MASTER:
05811 case OMP_ORDERED:
05812 case OMP_CRITICAL:
05813 gimplify_to_stmt_list (&OMP_BODY (*expr_p));
05814 break;
05815
05816 case OMP_ATOMIC:
05817 ret = gimplify_omp_atomic (expr_p, pre_p);
05818 break;
05819
05820 case OMP_RETURN:
05821 case OMP_CONTINUE:
05822 ret = GS_ALL_DONE;
05823 break;
05824
05825 default:
05826 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
05827 {
05828 case tcc_comparison:
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839 {
05840 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
05841
05842 if (!AGGREGATE_TYPE_P (type))
05843 goto expr_2;
05844 else if (TYPE_MODE (type) != BLKmode)
05845 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
05846 else
05847 ret = gimplify_variable_sized_compare (expr_p);
05848
05849 break;
05850 }
05851
05852
05853
05854 case tcc_unary:
05855 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
05856 post_p, is_gimple_val, fb_rvalue);
05857 break;
05858
05859 case tcc_binary:
05860 expr_2:
05861 {
05862 enum gimplify_status r0, r1;
05863
05864 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
05865 post_p, is_gimple_val, fb_rvalue);
05866 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
05867 post_p, is_gimple_val, fb_rvalue);
05868
05869 ret = MIN (r0, r1);
05870 break;
05871 }
05872
05873 case tcc_declaration:
05874 case tcc_constant:
05875 ret = GS_ALL_DONE;
05876 goto dont_recalculate;
05877
05878 default:
05879 gcc_assert (TREE_CODE (*expr_p) == TRUTH_AND_EXPR
05880 || TREE_CODE (*expr_p) == TRUTH_OR_EXPR
05881 || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR);
05882 goto expr_2;
05883 }
05884
05885 recalculate_side_effects (*expr_p);
05886 dont_recalculate:
05887 break;
05888 }
05889
05890
05891 if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr))
05892 ret = GS_ALL_DONE;
05893 }
05894 while (ret == GS_OK);
05895
05896
05897
05898 if (ret == GS_ERROR)
05899 {
05900 if (is_statement)
05901 *expr_p = NULL;
05902 goto out;
05903 }
05904
05905
05906
05907 gcc_assert (ret != GS_UNHANDLED);
05908
05909 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
05910 {
05911
05912
05913 if (!TREE_SIDE_EFFECTS (*expr_p))
05914 *expr_p = NULL;
05915 else if (!TREE_THIS_VOLATILE (*expr_p))
05916 {
05917
05918
05919 enum tree_code code = TREE_CODE (*expr_p);
05920
05921 switch (code)
05922 {
05923 case COMPONENT_REF:
05924 case REALPART_EXPR:
05925 case IMAGPART_EXPR:
05926 case VIEW_CONVERT_EXPR:
05927 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05928 gimple_test_f, fallback);
05929 break;
05930
05931 case ARRAY_REF:
05932 case ARRAY_RANGE_REF:
05933 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
05934 gimple_test_f, fallback);
05935 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
05936 gimple_test_f, fallback);
05937 break;
05938
05939 default:
05940
05941
05942 gcc_unreachable ();
05943 }
05944
05945 *expr_p = NULL;
05946 }
05947 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
05948 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
05949 {
05950
05951
05952 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
05953
05954
05955
05956
05957
05958
05959
05960 tree tmp = create_tmp_var_raw (type, "vol");
05961 gimple_add_tmp_var (tmp);
05962 *expr_p = build2 (MODIFY_EXPR, type, tmp, *expr_p);
05963 }
05964 else
05965
05966
05967
05968
05969
05970 *expr_p = NULL;
05971 }
05972
05973
05974
05975
05976 if (fallback == fb_none || is_statement)
05977 {
05978 if (internal_pre || internal_post)
05979 {
05980 append_to_statement_list (*expr_p, &internal_pre);
05981 append_to_statement_list (internal_post, &internal_pre);
05982 annotate_all_with_locus (&internal_pre, input_location);
05983 *expr_p = internal_pre;
05984 }
05985 else if (!*expr_p)
05986 ;
05987 else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
05988 annotate_all_with_locus (expr_p, input_location);
05989 else
05990 annotate_one_with_locus (*expr_p, input_location);
05991 goto out;
05992 }
05993
05994
05995
05996
05997
05998
05999
06000 if (!internal_post && (*gimple_test_f) (*expr_p))
06001 goto out;
06002
06003
06004
06005
06006
06007
06008
06009
06010 if ((fallback & fb_lvalue) && !internal_post
06011 && is_gimple_addressable (*expr_p))
06012 {
06013
06014
06015
06016 tmp = build_fold_addr_expr (*expr_p);
06017 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
06018 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
06019 }
06020 else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
06021 {
06022 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
06023
06024
06025
06026
06027 if (internal_post || (fallback & fb_lvalue))
06028
06029
06030
06031 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
06032 else
06033 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
06034
06035 if (TREE_CODE (*expr_p) != SSA_NAME)
06036 DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
06037 }
06038 else
06039 {
06040 #ifdef ENABLE_CHECKING
06041 if (!(fallback & fb_mayfail))
06042 {
06043 fprintf (stderr, "gimplification failed:\n");
06044 print_generic_expr (stderr, *expr_p, 0);
06045 debug_tree (*expr_p);
06046 internal_error ("gimplification failed");
06047 }
06048 #endif
06049 gcc_assert (fallback & fb_mayfail);
06050
06051
06052
06053 ret = GS_ERROR;
06054 goto out;
06055 }
06056
06057
06058 gcc_assert ((*gimple_test_f) (*expr_p));
06059
06060 if (internal_post)
06061 {
06062 annotate_all_with_locus (&internal_post, input_location);
06063 append_to_statement_list (internal_post, pre_p);
06064 }
06065
06066 out:
06067 input_location = saved_location;
06068 return ret;
06069 }
06070
06071
06072
06073
06074 void
06075 gimplify_type_sizes (tree type, tree *list_p)
06076 {
06077 tree field, t;
06078
06079 if (type == NULL || type == error_mark_node)
06080 return;
06081
06082
06083 type = TYPE_MAIN_VARIANT (type);
06084
06085
06086 if (TYPE_SIZES_GIMPLIFIED (type))
06087 return;
06088
06089 TYPE_SIZES_GIMPLIFIED (type) = 1;
06090
06091 switch (TREE_CODE (type))
06092 {
06093 case INTEGER_TYPE:
06094 case ENUMERAL_TYPE:
06095 case BOOLEAN_TYPE:
06096 case REAL_TYPE:
06097 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
06098 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
06099
06100 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
06101 {
06102 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
06103 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
06104 }
06105 break;
06106
06107 case ARRAY_TYPE:
06108
06109 gimplify_type_sizes (TREE_TYPE (type), list_p);
06110 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
06111 break;
06112
06113 case RECORD_TYPE:
06114 case UNION_TYPE:
06115 case QUAL_UNION_TYPE:
06116 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
06117 if (TREE_CODE (field) == FIELD_DECL)
06118 {
06119 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
06120 gimplify_type_sizes (TREE_TYPE (field), list_p);
06121 }
06122 break;
06123
06124 case POINTER_TYPE:
06125 case REFERENCE_TYPE:
06126
06127
06128
06129
06130
06131
06132
06133
06134
06135
06136
06137
06138 break;
06139
06140 default:
06141 break;
06142 }
06143
06144 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
06145 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
06146
06147 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
06148 {
06149 TYPE_SIZE (t) = TYPE_SIZE (type);
06150 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
06151 TYPE_SIZES_GIMPLIFIED (t) = 1;
06152 }
06153 }
06154
06155
06156
06157
06158
06159 void
06160 gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
06161 {
06162 tree type, expr = *expr_p;
06163
06164
06165
06166
06167
06168
06169 if (expr == NULL_TREE || TREE_CONSTANT (expr)
06170 || TREE_CODE (expr) == VAR_DECL
06171 || CONTAINS_PLACEHOLDER_P (expr))
06172 return;
06173
06174 type = TREE_TYPE (expr);
06175 *expr_p = unshare_expr (expr);
06176
06177 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
06178 expr = *expr_p;
06179
06180
06181
06182
06183
06184
06185
06186 if (TREE_TYPE (expr) != type
06187 && TREE_CODE (type) == INTEGER_TYPE
06188 && TYPE_IS_SIZETYPE (type))
06189 {
06190 tree tmp;
06191
06192 *expr_p = create_tmp_var (type, NULL);
06193 tmp = build1 (NOP_EXPR, type, expr);
06194 tmp = build2 (MODIFY_EXPR, type, *expr_p, tmp);
06195 if (EXPR_HAS_LOCATION (expr))
06196 SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
06197 else
06198 SET_EXPR_LOCATION (tmp, input_location);
06199
06200 gimplify_and_add (tmp, stmt_p);
06201 }
06202 }
06203
06204 #ifdef ENABLE_CHECKING
06205
06206
06207 static bool
06208 cpt_same_type (tree a, tree b)
06209 {
06210 if (lang_hooks.types_compatible_p (a, b))
06211 return true;
06212
06213
06214
06215
06216
06217 if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE)
06218 && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE))
06219 return true;
06220
06221
06222
06223
06224
06225
06226 if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE)
06227 return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
06228
06229
06230 if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b))
06231 return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
06232
06233 return false;
06234 }
06235
06236
06237
06238
06239
06240 static tree
06241 check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
06242 void *data ATTRIBUTE_UNUSED)
06243 {
06244 tree t = *tp;
06245 tree ptype, otype, dtype;
06246
06247 switch (TREE_CODE (t))
06248 {
06249 case INDIRECT_REF:
06250 case ARRAY_REF:
06251 otype = TREE_TYPE (t);
06252 ptype = TREE_TYPE (TREE_OPERAND (t, 0));
06253 dtype = TREE_TYPE (ptype);
06254 gcc_assert (cpt_same_type (otype, dtype));
06255 break;
06256
06257 case ADDR_EXPR:
06258 ptype = TREE_TYPE (t);
06259 otype = TREE_TYPE (TREE_OPERAND (t, 0));
06260 dtype = TREE_TYPE (ptype);
06261 if (!cpt_same_type (otype, dtype))
06262 {
06263
06264
06265
06266
06267 gcc_assert (TREE_CODE (otype) == ARRAY_TYPE
06268 && POINTER_TYPE_P (ptype)
06269 && cpt_same_type (TREE_TYPE (otype), dtype));
06270 break;
06271 }
06272 break;
06273
06274 default:
06275 return NULL_TREE;
06276 }
06277
06278
06279 return NULL_TREE;
06280 }
06281 #endif
06282
06283
06284
06285
06286 void
06287 gimplify_body (tree *body_p, tree fndecl, bool do_parms)
06288 {
06289 location_t saved_location = input_location;
06290 tree body, parm_stmts;
06291
06292 timevar_push (TV_TREE_GIMPLIFY);
06293
06294 gcc_assert (gimplify_ctxp == NULL);
06295 push_gimplify_context ();
06296
06297
06298
06299
06300
06301 unshare_body (body_p, fndecl);
06302 unvisit_body (body_p, fndecl);
06303
06304
06305 input_location = DECL_SOURCE_LOCATION (fndecl);
06306
06307
06308
06309 parm_stmts = do_parms ? gimplify_parameters () : NULL;
06310
06311
06312 gimplify_stmt (body_p);
06313 body = *body_p;
06314
06315 if (!body)
06316 body = alloc_stmt_list ();
06317 else if (TREE_CODE (body) == STATEMENT_LIST)
06318 {
06319 tree t = expr_only (*body_p);
06320 if (t)
06321 body = t;
06322 }
06323
06324
06325 if (TREE_CODE (body) != BIND_EXPR)
06326 {
06327 tree b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
06328 NULL_TREE, NULL_TREE);
06329 TREE_SIDE_EFFECTS (b) = 1;
06330 append_to_statement_list_force (body, &BIND_EXPR_BODY (b));
06331 body = b;
06332 }
06333
06334
06335
06336 if (parm_stmts)
06337 {
06338 append_to_statement_list_force (BIND_EXPR_BODY (body), &parm_stmts);
06339 BIND_EXPR_BODY (body) = parm_stmts;
06340 }
06341
06342
06343 unshare_all_trees (body);
06344
06345 *body_p = body;
06346
06347 pop_gimplify_context (body);
06348 gcc_assert (gimplify_ctxp == NULL);
06349
06350 #ifdef ENABLE_CHECKING
06351 walk_tree (body_p, check_pointer_types_r, NULL, NULL);
06352 #endif
06353
06354 timevar_pop (TV_TREE_GIMPLIFY);
06355 input_location = saved_location;
06356 }
06357
06358
06359
06360
06361 void
06362 gimplify_function_tree (tree fndecl)
06363 {
06364 tree oldfn, parm, ret;
06365
06366 oldfn = current_function_decl;
06367 current_function_decl = fndecl;
06368 cfun = DECL_STRUCT_FUNCTION (fndecl);
06369 if (cfun == NULL)
06370 allocate_struct_function (fndecl);
06371
06372 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = TREE_CHAIN (parm))
06373 {
06374
06375
06376
06377 if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
06378 && !TREE_THIS_VOLATILE (parm)
06379 && !needs_to_live_in_memory (parm))
06380 DECL_COMPLEX_GIMPLE_REG_P (parm) = 1;
06381 }
06382
06383 ret = DECL_RESULT (fndecl);
06384 if (TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
06385 && !needs_to_live_in_memory (ret))
06386 DECL_COMPLEX_GIMPLE_REG_P (ret) = 1;
06387
06388 gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
06389
06390
06391
06392
06393
06394 if (flag_instrument_function_entry_exit
06395 && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
06396 {
06397 tree tf, x, bind;
06398
06399 tf = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
06400 TREE_SIDE_EFFECTS (tf) = 1;
06401 x = DECL_SAVED_TREE (fndecl);
06402 append_to_statement_list (x, &TREE_OPERAND (tf, 0));
06403 x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
06404 x = build_function_call_expr (x, NULL);
06405 append_to_statement_list (x, &TREE_OPERAND (tf, 1));
06406
06407 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
06408 TREE_SIDE_EFFECTS (bind) = 1;
06409 x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
06410 x = build_function_call_expr (x, NULL);
06411 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
06412 append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
06413
06414 DECL_SAVED_TREE (fndecl) = bind;
06415 }
06416
06417 current_function_decl = oldfn;
06418 cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
06419 }
06420
06421
06422
06423
06424
06425
06426
06427 tree
06428 force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
06429 {
06430 tree t;
06431 enum gimplify_status ret;
06432 gimple_predicate gimple_test_f;
06433
06434 *stmts = NULL_TREE;
06435
06436 if (is_gimple_val (expr))
06437 return expr;
06438
06439 gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
06440
06441 push_gimplify_context ();
06442 gimplify_ctxp->into_ssa = in_ssa_p;
06443
06444 if (var)
06445 expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
06446
06447 ret = gimplify_expr (&expr, stmts, NULL,
06448 gimple_test_f, fb_rvalue);
06449 gcc_assert (ret != GS_ERROR);
06450
06451 if (referenced_vars)
06452 {
06453 for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
06454 add_referenced_var (t);
06455 }
06456
06457 pop_gimplify_context (NULL);
06458
06459 return expr;
06460 }
06461
06462
06463
06464
06465 tree
06466 force_gimple_operand_bsi (block_stmt_iterator *bsi, tree expr,
06467 bool simple_p, tree var)
06468 {
06469 tree stmts;
06470
06471 expr = force_gimple_operand (expr, &stmts, simple_p, var);
06472 if (stmts)
06473 bsi_insert_before (bsi, stmts, BSI_SAME_STMT);
06474
06475 return expr;
06476 }
06477
06478 #include "gt-gimplify.h"