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
00028 #include "config.h"
00029 #include "system.h"
00030 #include "coretypes.h"
00031 #include "tm.h"
00032 #include "tree.h"
00033 #include "rtl.h"
00034 #include "errors.h"
00035 #include "varray.h"
00036 #include "tree-gimple.h"
00037 #include "tree-inline.h"
00038 #include "diagnostic.h"
00039 #include "langhooks.h"
00040 #include "langhooks-def.h"
00041 #include "tree-flow.h"
00042 #include "cgraph.h"
00043 #include "timevar.h"
00044 #include "except.h"
00045 #include "hashtab.h"
00046 #include "flags.h"
00047 #include "real.h"
00048 #include "function.h"
00049 #include "output.h"
00050 #include "expr.h"
00051 #include "ggc.h"
00052 #include "target.h"
00053
00054 #ifdef KEY
00055 #include "gspin-gcc-interface.h"
00056 #endif
00057
00058 static struct gimplify_ctx
00059 {
00060 tree current_bind_expr;
00061 tree temps;
00062 tree conditional_cleanups;
00063 tree exit_label;
00064 tree return_temp;
00065 varray_type case_labels;
00066
00067 htab_t temp_htab;
00068 int conditions;
00069 bool save_stack;
00070 bool into_ssa;
00071 } *gimplify_ctxp;
00072
00073
00074
00075
00076
00077 typedef struct gimple_temp_hash_elt
00078 {
00079 tree val;
00080 tree temp;
00081 } elt_t;
00082
00083
00084 static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
00085 #ifdef ENABLE_CHECKING
00086 static bool cpt_same_type (tree a, tree b);
00087 #endif
00088
00089
00090
00091
00092 static hashval_t
00093 gimple_tree_hash (const void *p)
00094 {
00095 tree t = ((const elt_t *) p)->val;
00096 return iterative_hash_expr (t, 0);
00097 }
00098
00099
00100
00101 static int
00102 gimple_tree_eq (const void *p1, const void *p2)
00103 {
00104 tree t1 = ((const elt_t *) p1)->val;
00105 tree t2 = ((const elt_t *) p2)->val;
00106 enum tree_code code = TREE_CODE (t1);
00107
00108 if (TREE_CODE (t2) != code
00109 || TREE_TYPE (t1) != TREE_TYPE (t2))
00110 return 0;
00111
00112 if (!operand_equal_p (t1, t2, 0))
00113 return 0;
00114
00115
00116
00117 gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2));
00118
00119 return 1;
00120 }
00121
00122
00123
00124 void
00125 push_gimplify_context (void)
00126 {
00127 gcc_assert (!gimplify_ctxp);
00128 gimplify_ctxp
00129 = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
00130 if (optimize)
00131 gimplify_ctxp->temp_htab
00132 = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
00133 else
00134 gimplify_ctxp->temp_htab = NULL;
00135 }
00136
00137
00138
00139
00140
00141 void
00142 pop_gimplify_context (tree body)
00143 {
00144 tree t;
00145
00146 gcc_assert (gimplify_ctxp && !gimplify_ctxp->current_bind_expr);
00147
00148 for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
00149 DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
00150
00151 if (body)
00152 declare_tmp_vars (gimplify_ctxp->temps, body);
00153 else
00154 record_vars (gimplify_ctxp->temps);
00155
00156 #if 0
00157 if (!quiet_flag && optimize)
00158 fprintf (stderr, " collisions: %f ",
00159 htab_collisions (gimplify_ctxp->temp_htab));
00160 #endif
00161
00162 if (optimize)
00163 htab_delete (gimplify_ctxp->temp_htab);
00164 free (gimplify_ctxp);
00165 gimplify_ctxp = NULL;
00166 }
00167
00168 void
00169 gimple_push_bind_expr (tree bind)
00170 {
00171 TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
00172 gimplify_ctxp->current_bind_expr = bind;
00173 }
00174
00175 void
00176 gimple_pop_bind_expr (void)
00177 {
00178 gimplify_ctxp->current_bind_expr
00179 = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
00180 }
00181
00182 tree
00183 gimple_current_bind_expr (void)
00184 {
00185 return gimplify_ctxp->current_bind_expr;
00186 }
00187
00188
00189
00190
00191 static bool
00192 gimple_conditional_context (void)
00193 {
00194 return gimplify_ctxp->conditions > 0;
00195 }
00196
00197
00198
00199 static void
00200 gimple_push_condition (void)
00201 {
00202 #ifdef ENABLE_CHECKING
00203 if (gimplify_ctxp->conditions == 0)
00204 gcc_assert (!gimplify_ctxp->conditional_cleanups);
00205 #endif
00206 ++(gimplify_ctxp->conditions);
00207 }
00208
00209
00210
00211
00212 static void
00213 gimple_pop_condition (tree *pre_p)
00214 {
00215 int conds = --(gimplify_ctxp->conditions);
00216
00217 gcc_assert (conds >= 0);
00218 if (conds == 0)
00219 {
00220 append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
00221 gimplify_ctxp->conditional_cleanups = NULL_TREE;
00222 }
00223 }
00224
00225
00226
00227 static void
00228 append_to_statement_list_1 (tree t, tree *list_p)
00229 {
00230 tree list = *list_p;
00231 tree_stmt_iterator i;
00232
00233 if (!list)
00234 {
00235 if (t && TREE_CODE (t) == STATEMENT_LIST)
00236 {
00237 *list_p = t;
00238 return;
00239 }
00240 *list_p = list = alloc_stmt_list ();
00241 }
00242
00243 i = tsi_last (list);
00244 tsi_link_after (&i, t, TSI_CONTINUE_LINKING);
00245 }
00246
00247
00248
00249
00250 void
00251 append_to_statement_list (tree t, tree *list_p)
00252 {
00253 if (t && TREE_SIDE_EFFECTS (t))
00254 append_to_statement_list_1 (t, list_p);
00255 }
00256
00257
00258
00259 void
00260 append_to_statement_list_force (tree t, tree *list_p)
00261 {
00262 if (t != NULL_TREE)
00263 append_to_statement_list_1 (t, list_p);
00264 }
00265
00266
00267
00268 void
00269 gimplify_and_add (tree t, tree *list_p)
00270 {
00271 gimplify_stmt (&t);
00272 append_to_statement_list (t, list_p);
00273 }
00274
00275
00276
00277
00278
00279
00280 static inline void
00281 remove_suffix (char *name, int len)
00282 {
00283 int i;
00284
00285 for (i = 2; i < 8 && len > i; i++)
00286 {
00287 if (name[len - i] == '.')
00288 {
00289 name[len - i] = '\0';
00290 break;
00291 }
00292 }
00293 }
00294
00295
00296
00297
00298 tree
00299 create_artificial_label (void)
00300 {
00301 tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
00302
00303 DECL_ARTIFICIAL (lab) = 1;
00304 DECL_IGNORED_P (lab) = 1;
00305 DECL_CONTEXT (lab) = current_function_decl;
00306 return lab;
00307 }
00308
00309
00310
00311 static GTY(()) unsigned int tmp_var_id_num;
00312
00313 tree
00314 create_tmp_var_name (const char *prefix)
00315 {
00316 char *tmp_name;
00317
00318 if (prefix)
00319 {
00320 char *preftmp = ASTRDUP (prefix);
00321
00322 remove_suffix (preftmp, strlen (preftmp));
00323 prefix = preftmp;
00324 }
00325
00326 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
00327 return get_identifier (tmp_name);
00328 }
00329
00330
00331
00332
00333
00334 tree
00335 create_tmp_var_raw (tree type, const char *prefix)
00336 {
00337 tree tmp_var;
00338 tree new_type;
00339
00340
00341 new_type = build_type_variant (type, 0, 0);
00342 TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type);
00343
00344 tmp_var = build_decl (VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
00345 type);
00346
00347
00348 DECL_ARTIFICIAL (tmp_var) = 1;
00349
00350 DECL_IGNORED_P (tmp_var) = 1;
00351
00352
00353 TREE_READONLY (tmp_var) = 0;
00354
00355 DECL_EXTERNAL (tmp_var) = 0;
00356 TREE_STATIC (tmp_var) = 0;
00357 TREE_USED (tmp_var) = 1;
00358
00359 return tmp_var;
00360 }
00361
00362
00363
00364
00365
00366
00367 tree
00368 create_tmp_var (tree type, const char *prefix)
00369 {
00370 tree tmp_var;
00371
00372
00373
00374 gcc_assert (!TREE_ADDRESSABLE (type)
00375 && COMPLETE_TYPE_P (type)
00376 && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
00377
00378 tmp_var = create_tmp_var_raw (type, prefix);
00379 gimple_add_tmp_var (tmp_var);
00380 return tmp_var;
00381 }
00382
00383
00384
00385
00386
00387 const char *
00388 get_name (tree t)
00389 {
00390 tree stripped_decl;
00391
00392 stripped_decl = t;
00393 STRIP_NOPS (stripped_decl);
00394 if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
00395 return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
00396 else
00397 {
00398 switch (TREE_CODE (stripped_decl))
00399 {
00400 case ADDR_EXPR:
00401 return get_name (TREE_OPERAND (stripped_decl, 0));
00402 break;
00403 default:
00404 return NULL;
00405 }
00406 }
00407 }
00408
00409
00410
00411
00412 static inline tree
00413 create_tmp_from_val (tree val)
00414 {
00415 return create_tmp_var (TREE_TYPE (val), get_name (val));
00416 }
00417
00418
00419
00420
00421 static tree
00422 lookup_tmp_var (tree val, bool is_formal)
00423 {
00424 tree ret;
00425
00426
00427
00428
00429
00430
00431 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
00432 ret = create_tmp_from_val (val);
00433 else
00434 {
00435 elt_t elt, *elt_p;
00436 void **slot;
00437
00438 elt.val = val;
00439 slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
00440 if (*slot == NULL)
00441 {
00442 elt_p = xmalloc (sizeof (*elt_p));
00443 elt_p->val = val;
00444 elt_p->temp = ret = create_tmp_from_val (val);
00445 *slot = (void *) elt_p;
00446 }
00447 else
00448 {
00449 elt_p = (elt_t *) *slot;
00450 ret = elt_p->temp;
00451 }
00452 }
00453
00454 if (is_formal)
00455 DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
00456
00457 return ret;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 static tree
00473 internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
00474 {
00475 tree t, mod;
00476
00477 gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
00478
00479 t = lookup_tmp_var (val, is_formal);
00480
00481 mod = build (MODIFY_EXPR, TREE_TYPE (t), t, val);
00482
00483 if (EXPR_HAS_LOCATION (val))
00484 SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
00485 else
00486 SET_EXPR_LOCATION (mod, input_location);
00487
00488
00489 gimplify_and_add (mod, pre_p);
00490
00491
00492
00493 if (gimplify_ctxp->into_ssa)
00494 t = TREE_OPERAND (mod, 0);
00495
00496 return t;
00497 }
00498
00499 tree
00500 get_formal_tmp_var (tree val, tree *pre_p)
00501 {
00502 return internal_get_tmp_var (val, pre_p, NULL, true);
00503 }
00504
00505
00506
00507
00508 tree
00509 get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
00510 {
00511 return internal_get_tmp_var (val, pre_p, post_p, false);
00512 }
00513
00514
00515
00516 void
00517 declare_tmp_vars (tree vars, tree scope)
00518 {
00519 tree last = vars;
00520 if (last)
00521 {
00522 tree temps;
00523
00524
00525
00526 while (TREE_CODE (scope) == COMPOUND_EXPR)
00527 scope = TREE_OPERAND (scope, 0);
00528
00529 gcc_assert (TREE_CODE (scope) == BIND_EXPR);
00530
00531 temps = nreverse (last);
00532 TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
00533 BIND_EXPR_VARS (scope) = temps;
00534 }
00535 }
00536
00537 void
00538 gimple_add_tmp_var (tree tmp)
00539 {
00540 gcc_assert (!TREE_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
00541
00542 DECL_CONTEXT (tmp) = current_function_decl;
00543 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
00544
00545 if (gimplify_ctxp)
00546 {
00547 TREE_CHAIN (tmp) = gimplify_ctxp->temps;
00548 gimplify_ctxp->temps = tmp;
00549 }
00550 else if (cfun)
00551 record_vars (tmp);
00552 else
00553 declare_tmp_vars (tmp, DECL_SAVED_TREE (current_function_decl));
00554 }
00555
00556
00557
00558 static bool
00559 should_carry_locus_p (tree stmt)
00560 {
00561
00562
00563
00564 if (TREE_CODE (stmt) == LABEL_EXPR)
00565 return false;
00566
00567
00568 if (!TREE_SIDE_EFFECTS (stmt))
00569 return false;
00570
00571 return true;
00572 }
00573
00574 static void
00575 annotate_one_with_locus (tree t, location_t locus)
00576 {
00577 if (EXPR_P (t) && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
00578 SET_EXPR_LOCATION (t, locus);
00579 }
00580
00581 void
00582 annotate_all_with_locus (tree *stmt_p, location_t locus)
00583 {
00584 tree_stmt_iterator i;
00585
00586 if (!*stmt_p)
00587 return;
00588
00589 for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
00590 {
00591 tree t = tsi_stmt (i);
00592
00593
00594
00595 gcc_assert (TREE_CODE (t) != STATEMENT_LIST
00596 && TREE_CODE (t) != COMPOUND_EXPR);
00597
00598 annotate_one_with_locus (t, locus);
00599 }
00600 }
00601
00602
00603
00604
00605
00606
00607 static tree
00608 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
00609 {
00610 enum tree_code code = TREE_CODE (*tp);
00611
00612 if (TREE_CODE_CLASS (code) == tcc_type
00613 || TREE_CODE_CLASS (code) == tcc_declaration
00614 || TREE_CODE_CLASS (code) == tcc_constant
00615 || code == SAVE_EXPR || code == TARGET_EXPR
00616
00617
00618
00619 || code == BLOCK)
00620 *walk_subtrees = 0;
00621 else
00622 {
00623 gcc_assert (code != BIND_EXPR);
00624 copy_tree_r (tp, walk_subtrees, data);
00625 }
00626
00627 return NULL_TREE;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 static tree
00640 copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00641 void *data ATTRIBUTE_UNUSED)
00642 {
00643 tree t = *tp;
00644 enum tree_code code = TREE_CODE (t);
00645
00646
00647
00648
00649
00650 if (TREE_CODE_CLASS (code) == tcc_type
00651 || TREE_CODE_CLASS (code) == tcc_declaration
00652 || TREE_CODE_CLASS (code) == tcc_constant)
00653 {
00654 if (TREE_VISITED (t))
00655 *walk_subtrees = 0;
00656 else
00657 TREE_VISITED (t) = 1;
00658 }
00659
00660
00661
00662 else if (TREE_VISITED (t))
00663 {
00664 walk_tree (tp, mostly_copy_tree_r, NULL, NULL);
00665 *walk_subtrees = 0;
00666 }
00667
00668
00669 else
00670 TREE_VISITED (t) = 1;
00671
00672 return NULL_TREE;
00673 }
00674
00675 static tree
00676 unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00677 void *data ATTRIBUTE_UNUSED)
00678 {
00679 if (TREE_VISITED (*tp))
00680 TREE_VISITED (*tp) = 0;
00681 else
00682 *walk_subtrees = 0;
00683
00684 return NULL_TREE;
00685 }
00686
00687
00688
00689
00690
00691 static void
00692 unshare_body (tree *body_p, tree fndecl)
00693 {
00694 struct cgraph_node *cgn = cgraph_node (fndecl);
00695
00696 walk_tree (body_p, copy_if_shared_r, NULL, NULL);
00697 if (body_p == &DECL_SAVED_TREE (fndecl))
00698 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
00699 unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
00700 }
00701
00702
00703
00704 static void
00705 unvisit_body (tree *body_p, tree fndecl)
00706 {
00707 struct cgraph_node *cgn = cgraph_node (fndecl);
00708
00709 walk_tree (body_p, unmark_visited_r, NULL, NULL);
00710 if (body_p == &DECL_SAVED_TREE (fndecl))
00711 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
00712 unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
00713 }
00714
00715
00716
00717 void
00718 unshare_all_trees (tree t)
00719 {
00720 walk_tree (&t, copy_if_shared_r, NULL, NULL);
00721 walk_tree (&t, unmark_visited_r, NULL, NULL);
00722 }
00723
00724
00725
00726
00727
00728 tree
00729 unshare_expr (tree expr)
00730 {
00731 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
00732 return expr;
00733 }
00734
00735
00736
00737
00738 tree
00739 gimple_build_eh_filter (tree body, tree allowed, tree failure)
00740 {
00741 tree t;
00742
00743
00744 t = build (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
00745 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
00746
00747 t = build (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
00748 append_to_statement_list (body, &TREE_OPERAND (t, 0));
00749
00750 return t;
00751 }
00752
00753
00754
00755
00756
00757
00758
00759 tree
00760 voidify_wrapper_expr (tree wrapper, tree temp)
00761 {
00762 if (!VOID_TYPE_P (TREE_TYPE (wrapper)))
00763 {
00764 tree *p, sub = wrapper;
00765
00766 restart:
00767
00768 switch (TREE_CODE (sub))
00769 {
00770 case BIND_EXPR:
00771
00772 p = &BIND_EXPR_BODY (sub);
00773 break;
00774
00775 default:
00776 p = &TREE_OPERAND (sub, 0);
00777 break;
00778 }
00779
00780
00781 if (TREE_CODE (*p) == STATEMENT_LIST)
00782 {
00783 tree_stmt_iterator i = tsi_last (*p);
00784 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
00785 }
00786 else
00787 {
00788 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
00789 {
00790 TREE_SIDE_EFFECTS (*p) = 1;
00791 TREE_TYPE (*p) = void_type_node;
00792 }
00793 }
00794
00795 if (p == NULL || IS_EMPTY_STMT (*p))
00796 ;
00797
00798 else if (TREE_CODE (*p) == TRY_FINALLY_EXPR
00799 || TREE_CODE (*p) == TRY_CATCH_EXPR)
00800 {
00801 sub = *p;
00802 goto restart;
00803 }
00804
00805 else if (TREE_CODE (*p) == INIT_EXPR
00806 || TREE_CODE (*p) == TARGET_EXPR)
00807 temp = TREE_OPERAND (*p, 0);
00808
00809
00810 else if (TREE_CODE (*p) == INDIRECT_REF)
00811 {
00812 tree ptr = TREE_OPERAND (*p, 0);
00813 temp = create_tmp_var (TREE_TYPE (ptr), "retval");
00814 *p = build (MODIFY_EXPR, TREE_TYPE (ptr), temp, ptr);
00815 temp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp)), temp);
00816
00817
00818 TREE_SIDE_EFFECTS (wrapper) = 1;
00819 }
00820 else
00821 {
00822 if (!temp)
00823 temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
00824 *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
00825 TREE_SIDE_EFFECTS (wrapper) = 1;
00826 }
00827
00828 TREE_TYPE (wrapper) = void_type_node;
00829 return temp;
00830 }
00831
00832 return NULL_TREE;
00833 }
00834
00835
00836
00837
00838 static void
00839 build_stack_save_restore (tree *save, tree *restore)
00840 {
00841 tree save_call, tmp_var;
00842
00843 save_call =
00844 build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE],
00845 NULL_TREE);
00846 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
00847
00848 *save = build (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
00849 *restore =
00850 build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
00851 tree_cons (NULL_TREE, tmp_var, NULL_TREE));
00852 }
00853
00854
00855
00856 static enum gimplify_status
00857 gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
00858 {
00859 tree bind_expr = *expr_p;
00860 bool old_save_stack = gimplify_ctxp->save_stack;
00861 tree t;
00862
00863 temp = voidify_wrapper_expr (bind_expr, temp);
00864
00865
00866 for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
00867 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
00868
00869 gimple_push_bind_expr (bind_expr);
00870 gimplify_ctxp->save_stack = false;
00871
00872 gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
00873
00874 if (gimplify_ctxp->save_stack)
00875 {
00876 tree stack_save, stack_restore;
00877
00878
00879
00880
00881 build_stack_save_restore (&stack_save, &stack_restore);
00882
00883 t = build (TRY_FINALLY_EXPR, void_type_node,
00884 BIND_EXPR_BODY (bind_expr), NULL_TREE);
00885 append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
00886
00887 BIND_EXPR_BODY (bind_expr) = NULL_TREE;
00888 append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
00889 append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
00890 }
00891
00892 gimplify_ctxp->save_stack = old_save_stack;
00893 gimple_pop_bind_expr ();
00894
00895 if (temp)
00896 {
00897 *expr_p = temp;
00898 append_to_statement_list (bind_expr, pre_p);
00899 return GS_OK;
00900 }
00901 else
00902 return GS_ALL_DONE;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912 static enum gimplify_status
00913 gimplify_return_expr (tree stmt, tree *pre_p)
00914 {
00915 tree ret_expr = TREE_OPERAND (stmt, 0);
00916 tree result_decl, result;
00917
00918 if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
00919 || ret_expr == error_mark_node)
00920 return GS_ALL_DONE;
00921
00922 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
00923 result_decl = NULL_TREE;
00924 else
00925 {
00926 result_decl = TREE_OPERAND (ret_expr, 0);
00927 if (TREE_CODE (result_decl) == INDIRECT_REF)
00928
00929 result_decl = TREE_OPERAND (result_decl, 0);
00930
00931 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
00932 || TREE_CODE (ret_expr) == INIT_EXPR)
00933 && TREE_CODE (result_decl) == RESULT_DECL);
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 if (!result_decl
00945 || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
00946 result = result_decl;
00947 else if (gimplify_ctxp->return_temp)
00948 result = gimplify_ctxp->return_temp;
00949 else
00950 {
00951 result = create_tmp_var (TREE_TYPE (result_decl), NULL);
00952
00953
00954
00955
00956
00957 TREE_NO_WARNING (result) = 1;
00958
00959 gimplify_ctxp->return_temp = result;
00960 }
00961
00962
00963
00964 if (result != result_decl)
00965 TREE_OPERAND (ret_expr, 0) = result;
00966
00967 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
00968
00969
00970
00971 if (result == result_decl)
00972 ret_expr = result;
00973 else
00974 ret_expr = build (MODIFY_EXPR, TREE_TYPE (result), result_decl, result);
00975 TREE_OPERAND (stmt, 0) = ret_expr;
00976
00977 return GS_ALL_DONE;
00978 }
00979
00980
00981
00982
00983 static enum gimplify_status
00984 gimplify_decl_expr (tree *stmt_p)
00985 {
00986 tree stmt = *stmt_p;
00987 tree decl = DECL_EXPR_DECL (stmt);
00988
00989 *stmt_p = NULL_TREE;
00990
00991 if (TREE_TYPE (decl) == error_mark_node)
00992 return GS_ERROR;
00993
00994 if ((TREE_CODE (decl) == TYPE_DECL
00995 || TREE_CODE (decl) == VAR_DECL)
00996 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
00997 gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
00998
00999 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
01000 {
01001 tree init = DECL_INITIAL (decl);
01002
01003 if (!TREE_CONSTANT (DECL_SIZE (decl)))
01004 {
01005
01006
01007
01008 tree t, args, addr, ptr_type;
01009
01010 gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
01011 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
01012
01013
01014
01015
01016
01017
01018 ptr_type = build_pointer_type (TREE_TYPE (decl));
01019 addr = create_tmp_var (ptr_type, get_name (decl));
01020 DECL_IGNORED_P (addr) = 0;
01021 t = build_fold_indirect_ref (addr);
01022 DECL_VALUE_EXPR (decl) = t;
01023
01024 args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
01025 t = built_in_decls[BUILT_IN_ALLOCA];
01026 t = build_function_call_expr (t, args);
01027 t = fold_convert (ptr_type, t);
01028 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
01029
01030 gimplify_and_add (t, stmt_p);
01031
01032
01033
01034 gimplify_ctxp->save_stack = true;
01035 }
01036
01037 if (init && init != error_mark_node)
01038 {
01039 if (!TREE_STATIC (decl))
01040 {
01041 DECL_INITIAL (decl) = NULL_TREE;
01042 init = build (MODIFY_EXPR, void_type_node, decl, init);
01043 gimplify_and_add (init, stmt_p);
01044 }
01045 else
01046
01047
01048 walk_tree (&init, force_labels_r, NULL, NULL);
01049 }
01050
01051
01052
01053
01054 if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
01055 gimple_add_tmp_var (decl);
01056 }
01057
01058 return GS_ALL_DONE;
01059 }
01060
01061
01062
01063
01064
01065 static enum gimplify_status
01066 gimplify_loop_expr (tree *expr_p, tree *pre_p)
01067 {
01068 tree saved_label = gimplify_ctxp->exit_label;
01069 tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
01070 tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
01071
01072 append_to_statement_list (start_label, pre_p);
01073
01074 gimplify_ctxp->exit_label = NULL_TREE;
01075
01076 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
01077
01078 if (gimplify_ctxp->exit_label)
01079 {
01080 append_to_statement_list (jump_stmt, pre_p);
01081 *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
01082 }
01083 else
01084 *expr_p = jump_stmt;
01085
01086 gimplify_ctxp->exit_label = saved_label;
01087
01088 return GS_ALL_DONE;
01089 }
01090
01091
01092
01093
01094
01095 static int
01096 compare_case_labels (const void *p1, const void *p2)
01097 {
01098 tree case1 = *(tree *)p1;
01099 tree case2 = *(tree *)p2;
01100
01101 return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
01102 }
01103
01104
01105
01106 void
01107 sort_case_labels (tree label_vec)
01108 {
01109 size_t len = TREE_VEC_LENGTH (label_vec);
01110 tree default_case = TREE_VEC_ELT (label_vec, len - 1);
01111
01112 if (CASE_LOW (default_case))
01113 {
01114 size_t i;
01115
01116
01117
01118 for (i = 0; i < len; ++i)
01119 {
01120 tree t = TREE_VEC_ELT (label_vec, i);
01121 if (!CASE_LOW (t))
01122 {
01123 default_case = t;
01124 TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
01125 TREE_VEC_ELT (label_vec, len - 1) = default_case;
01126 break;
01127 }
01128 }
01129 }
01130
01131 qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
01132 compare_case_labels);
01133 }
01134
01135
01136
01137
01138 static enum gimplify_status
01139 gimplify_switch_expr (tree *expr_p, tree *pre_p)
01140 {
01141 tree switch_expr = *expr_p;
01142 enum gimplify_status ret;
01143
01144 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
01145 is_gimple_val, fb_rvalue);
01146
01147 if (SWITCH_BODY (switch_expr))
01148 {
01149 varray_type labels, saved_labels;
01150 tree label_vec, default_case = NULL_TREE;
01151 size_t i, len;
01152
01153
01154
01155 gcc_assert (!SWITCH_LABELS (switch_expr));
01156
01157 saved_labels = gimplify_ctxp->case_labels;
01158 VARRAY_TREE_INIT (gimplify_ctxp->case_labels, 8, "case_labels");
01159
01160 gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
01161
01162 labels = gimplify_ctxp->case_labels;
01163 gimplify_ctxp->case_labels = saved_labels;
01164
01165 len = VARRAY_ACTIVE_SIZE (labels);
01166
01167 for (i = 0; i < len; ++i)
01168 {
01169 tree t = VARRAY_TREE (labels, i);
01170 if (!CASE_LOW (t))
01171 {
01172
01173 default_case = t;
01174 VARRAY_TREE (labels, i) = VARRAY_TREE (labels, len - 1);
01175 len--;
01176 break;
01177 }
01178 }
01179
01180 label_vec = make_tree_vec (len + 1);
01181 SWITCH_LABELS (*expr_p) = label_vec;
01182 append_to_statement_list (switch_expr, pre_p);
01183
01184 if (! default_case)
01185 {
01186
01187
01188 default_case = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
01189 NULL_TREE, create_artificial_label ());
01190 append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
01191 *expr_p = build (LABEL_EXPR, void_type_node,
01192 CASE_LABEL (default_case));
01193 }
01194 else
01195 *expr_p = SWITCH_BODY (switch_expr);
01196
01197 for (i = 0; i < len; ++i)
01198 TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
01199 TREE_VEC_ELT (label_vec, len) = default_case;
01200
01201 sort_case_labels (label_vec);
01202
01203 SWITCH_BODY (switch_expr) = NULL;
01204 }
01205 else
01206 gcc_assert (SWITCH_LABELS (switch_expr));
01207
01208 return ret;
01209 }
01210
01211 static enum gimplify_status
01212 gimplify_case_label_expr (tree *expr_p)
01213 {
01214 tree expr = *expr_p;
01215
01216 gcc_assert (gimplify_ctxp->case_labels);
01217 VARRAY_PUSH_TREE (gimplify_ctxp->case_labels, expr);
01218 *expr_p = build (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
01219 return GS_ALL_DONE;
01220 }
01221
01222
01223
01224
01225 tree
01226 build_and_jump (tree *label_p)
01227 {
01228 if (label_p == NULL)
01229
01230 return NULL_TREE;
01231
01232 if (*label_p == NULL_TREE)
01233 {
01234 tree label = create_artificial_label ();
01235 *label_p = label;
01236 }
01237
01238 return build1 (GOTO_EXPR, void_type_node, *label_p);
01239 }
01240
01241
01242
01243
01244
01245 static enum gimplify_status
01246 gimplify_exit_expr (tree *expr_p)
01247 {
01248 tree cond = TREE_OPERAND (*expr_p, 0);
01249 tree expr;
01250
01251 expr = build_and_jump (&gimplify_ctxp->exit_label);
01252 expr = build (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
01253 *expr_p = expr;
01254
01255 return GS_OK;
01256 }
01257
01258
01259
01260
01261 tree
01262 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
01263 {
01264 if (TYPE_P (*tp))
01265 *walk_subtrees = 0;
01266 if (TREE_CODE (*tp) == LABEL_DECL)
01267 FORCED_LABEL (*tp) = 1;
01268
01269 return NULL_TREE;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 static void
01283 canonicalize_component_ref (tree *expr_p)
01284 {
01285 tree expr = *expr_p;
01286 tree type;
01287
01288 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
01289
01290 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
01291 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
01292 else
01293 type = TREE_TYPE (TREE_OPERAND (expr, 1));
01294
01295 if (TREE_TYPE (expr) != type)
01296 {
01297 tree old_type = TREE_TYPE (expr);
01298
01299
01300 TREE_TYPE (expr) = type;
01301
01302
01303 expr = build1 (NOP_EXPR, old_type, expr);
01304
01305 *expr_p = expr;
01306 }
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 static void
01319 canonicalize_addr_expr (tree *expr_p)
01320 {
01321 tree expr = *expr_p;
01322 tree ctype = TREE_TYPE (expr);
01323 tree addr_expr = TREE_OPERAND (expr, 0);
01324 tree atype = TREE_TYPE (addr_expr);
01325 tree dctype, datype, ddatype, otype, obj_expr;
01326
01327
01328 if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
01329 return;
01330
01331
01332 datype = TREE_TYPE (atype);
01333 if (TREE_CODE (datype) != ARRAY_TYPE)
01334 return;
01335
01336
01337 dctype = TREE_TYPE (ctype);
01338 ddatype = TREE_TYPE (datype);
01339 if (!lang_hooks.types_compatible_p (ddatype, dctype))
01340 return;
01341
01342
01343 obj_expr = TREE_OPERAND (addr_expr, 0);
01344 otype = TREE_TYPE (obj_expr);
01345 if (!lang_hooks.types_compatible_p (otype, datype))
01346 return;
01347
01348
01349 if (!TYPE_SIZE_UNIT (dctype)
01350 || TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
01351 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
01352 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
01353 return;
01354
01355
01356 *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
01357 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
01358 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
01359 size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
01360 size_int (TYPE_ALIGN_UNIT (dctype))));
01361 *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
01362 }
01363
01364
01365
01366
01367 static enum gimplify_status
01368 gimplify_conversion (tree *expr_p)
01369 {
01370 gcc_assert (TREE_CODE (*expr_p) == NOP_EXPR
01371 || TREE_CODE (*expr_p) == CONVERT_EXPR);
01372
01373
01374 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
01375
01376
01377 if (tree_ssa_useless_type_conversion (*expr_p))
01378 *expr_p = TREE_OPERAND (*expr_p, 0);
01379
01380
01381
01382 if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR)
01383 {
01384 tree sub = TREE_OPERAND (*expr_p, 0);
01385
01386
01387
01388
01389 if (TREE_CODE (sub) == COMPONENT_REF)
01390 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
01391
01392
01393
01394 else if (TREE_CODE (sub) == ADDR_EXPR)
01395 canonicalize_addr_expr (expr_p);
01396 }
01397
01398 return GS_OK;
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 static enum gimplify_status
01424 gimplify_compound_lval (tree *expr_p, tree *pre_p,
01425 tree *post_p, fallback_t fallback)
01426 {
01427 tree *p;
01428 varray_type stack;
01429 enum gimplify_status ret = GS_OK, tret;
01430 int i;
01431
01432
01433
01434
01435
01436
01437 VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack");
01438
01439
01440 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
01441 {
01442
01443 if (TREE_CODE (*p) == INDIRECT_REF)
01444 *p = fold_indirect_ref (*p);
01445 if (!handled_component_p (*p))
01446 break;
01447 VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
01448 }
01449
01450 gcc_assert (VARRAY_ACTIVE_SIZE (stack));
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 for (i = VARRAY_ACTIVE_SIZE (stack) - 1; i >= 0; i--)
01465 {
01466 tree t = VARRAY_GENERIC_PTR_NOGC (stack, i);
01467
01468 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
01469 {
01470
01471
01472
01473 if (!TREE_OPERAND (t, 2))
01474 {
01475 tree low = unshare_expr (array_ref_low_bound (t));
01476 if (!is_gimple_min_invariant (low))
01477 {
01478 TREE_OPERAND (t, 2) = low;
01479 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01480 is_gimple_formal_tmp_reg, fb_rvalue);
01481 ret = MIN (ret, tret);
01482 }
01483 }
01484
01485 if (!TREE_OPERAND (t, 3))
01486 {
01487 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
01488 tree elmt_size = unshare_expr (array_ref_element_size (t));
01489 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
01490
01491
01492
01493 elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
01494
01495 if (!is_gimple_min_invariant (elmt_size))
01496 {
01497 TREE_OPERAND (t, 3) = elmt_size;
01498 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
01499 is_gimple_formal_tmp_reg, fb_rvalue);
01500 ret = MIN (ret, tret);
01501 }
01502 }
01503 }
01504 else if (TREE_CODE (t) == COMPONENT_REF)
01505 {
01506
01507 if (!TREE_OPERAND (t, 2))
01508 {
01509 tree offset = unshare_expr (component_ref_field_offset (t));
01510 tree field = TREE_OPERAND (t, 1);
01511 tree factor
01512 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
01513
01514
01515 offset = size_binop (EXACT_DIV_EXPR, offset, factor);
01516
01517 if (!is_gimple_min_invariant (offset))
01518 {
01519 TREE_OPERAND (t, 2) = offset;
01520 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01521 is_gimple_formal_tmp_reg, fb_rvalue);
01522 ret = MIN (ret, tret);
01523 }
01524 }
01525 }
01526 }
01527
01528
01529 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
01530 ret = MIN (ret, tret);
01531
01532
01533
01534 for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
01535 {
01536 tree t = VARRAY_TOP_TREE (stack);
01537
01538 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
01539 {
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
01550 {
01551 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
01552 is_gimple_formal_tmp_reg, fb_rvalue);
01553 ret = MIN (ret, tret);
01554 }
01555 }
01556 else if (TREE_CODE (t) == BIT_FIELD_REF)
01557 {
01558 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
01559 is_gimple_val, fb_rvalue);
01560 ret = MIN (ret, tret);
01561 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
01562 is_gimple_val, fb_rvalue);
01563 ret = MIN (ret, tret);
01564 }
01565
01566 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
01567
01568
01569
01570
01571 recalculate_side_effects (t);
01572 VARRAY_POP (stack);
01573 }
01574
01575 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
01576 ret = MIN (ret, tret);
01577
01578
01579 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
01580 {
01581 canonicalize_component_ref (expr_p);
01582 ret = MIN (ret, GS_OK);
01583 }
01584
01585 VARRAY_FREE (stack);
01586
01587 return ret;
01588 }
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 static enum gimplify_status
01602 gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
01603 bool want_value)
01604 {
01605 enum tree_code code;
01606 tree lhs, lvalue, rhs, t1;
01607 bool postfix;
01608 enum tree_code arith_code;
01609 enum gimplify_status ret;
01610
01611 code = TREE_CODE (*expr_p);
01612
01613 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
01614 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
01615
01616
01617 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
01618
01619 postfix = want_value;
01620 else
01621 postfix = false;
01622
01623
01624 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
01625 arith_code = PLUS_EXPR;
01626 else
01627 arith_code = MINUS_EXPR;
01628
01629
01630 lvalue = TREE_OPERAND (*expr_p, 0);
01631 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
01632 if (ret == GS_ERROR)
01633 return ret;
01634
01635
01636 lhs = lvalue;
01637 rhs = TREE_OPERAND (*expr_p, 1);
01638
01639
01640
01641 if (postfix)
01642 {
01643 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
01644 if (ret == GS_ERROR)
01645 return ret;
01646 }
01647
01648 t1 = build (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
01649 t1 = build (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
01650
01651 if (postfix)
01652 {
01653 gimplify_and_add (t1, post_p);
01654 *expr_p = lhs;
01655 return GS_ALL_DONE;
01656 }
01657 else
01658 {
01659 *expr_p = t1;
01660 return GS_OK;
01661 }
01662 }
01663
01664
01665
01666 static void
01667 maybe_with_size_expr (tree *expr_p)
01668 {
01669 tree expr = *expr_p;
01670 tree type = TREE_TYPE (expr);
01671 tree size;
01672
01673
01674
01675 if (TREE_CODE (expr) == WITH_SIZE_EXPR
01676 || type == error_mark_node)
01677 return;
01678
01679
01680 size = TYPE_SIZE_UNIT (type);
01681 if (!size || TREE_CODE (size) == INTEGER_CST)
01682 return;
01683
01684
01685 size = unshare_expr (size);
01686 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
01687 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
01688 }
01689
01690
01691
01692 static enum gimplify_status
01693 gimplify_arg (tree *expr_p, tree *pre_p)
01694 {
01695 bool (*test) (tree);
01696 fallback_t fb;
01697
01698
01699
01700
01701
01702
01703 if (is_gimple_reg_type (TREE_TYPE (*expr_p)))
01704 test = is_gimple_val, fb = fb_rvalue;
01705 else
01706 test = is_gimple_lvalue, fb = fb_either;
01707
01708
01709 maybe_with_size_expr (expr_p);
01710
01711
01712
01713
01714
01715 return gimplify_expr (expr_p, pre_p, NULL, test, fb);
01716 }
01717
01718
01719
01720
01721
01722 static enum gimplify_status
01723 gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
01724 {
01725 tree decl;
01726 tree arglist;
01727 enum gimplify_status ret;
01728
01729 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
01730
01731
01732
01733 if (! EXPR_HAS_LOCATION (*expr_p))
01734 SET_EXPR_LOCATION (*expr_p, input_location);
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 decl = get_callee_fndecl (*expr_p);
01749 if (decl && DECL_BUILT_IN (decl))
01750 {
01751 tree new = fold_builtin (*expr_p, !want_value);
01752
01753 if (new && new != *expr_p)
01754 {
01755
01756
01757
01758 *expr_p = new;
01759 return GS_OK;
01760 }
01761
01762 if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
01763 && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
01764 {
01765 tree arglist = TREE_OPERAND (*expr_p, 1);
01766
01767 if (!arglist || !TREE_CHAIN (arglist))
01768 {
01769 error ("too few arguments to function %<va_start%>");
01770 *expr_p = build_empty_stmt ();
01771 return GS_OK;
01772 }
01773
01774 #ifdef KEY
01775
01776
01777
01778
01779
01780 if (!flag_spin_file)
01781 #endif
01782 if (fold_builtin_next_arg (TREE_CHAIN (arglist)))
01783 {
01784 *expr_p = build_empty_stmt ();
01785 return GS_OK;
01786 }
01787
01788
01789 return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p);
01790 }
01791 }
01792
01793
01794
01795
01796 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
01797 is_gimple_call_addr, fb_rvalue);
01798
01799 if (PUSH_ARGS_REVERSED)
01800 TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
01801 for (arglist = TREE_OPERAND (*expr_p, 1); arglist;
01802 arglist = TREE_CHAIN (arglist))
01803 {
01804 enum gimplify_status t;
01805
01806 t = gimplify_arg (&TREE_VALUE (arglist), pre_p);
01807
01808 if (t == GS_ERROR)
01809 ret = GS_ERROR;
01810 }
01811 if (PUSH_ARGS_REVERSED)
01812 TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
01813
01814
01815 if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl))
01816 {
01817 tree new = fold_builtin (*expr_p, !want_value);
01818
01819 if (new && new != *expr_p)
01820 {
01821
01822
01823
01824 *expr_p = new;
01825 return GS_OK;
01826 }
01827 }
01828
01829
01830
01831
01832 if (TREE_CODE (*expr_p) == CALL_EXPR
01833 && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
01834 TREE_SIDE_EFFECTS (*expr_p) = 0;
01835
01836 return ret;
01837 }
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 static tree
01851 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
01852 {
01853 tree local_label = NULL_TREE;
01854 tree t, expr = NULL;
01855
01856
01857
01858
01859 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
01860 {
01861
01862
01863
01864
01865
01866
01867 if (false_label_p == NULL)
01868 false_label_p = &local_label;
01869
01870 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p);
01871 append_to_statement_list (t, &expr);
01872
01873 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
01874 false_label_p);
01875 append_to_statement_list (t, &expr);
01876 }
01877 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
01878 {
01879
01880
01881
01882
01883
01884
01885 if (true_label_p == NULL)
01886 true_label_p = &local_label;
01887
01888 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL);
01889 append_to_statement_list (t, &expr);
01890
01891 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
01892 false_label_p);
01893 append_to_statement_list (t, &expr);
01894 }
01895 else if (TREE_CODE (pred) == COND_EXPR)
01896 {
01897
01898
01899
01900
01901
01902 expr = build (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
01903 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
01904 false_label_p),
01905 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
01906 false_label_p));
01907 }
01908 else
01909 {
01910 expr = build (COND_EXPR, void_type_node, pred,
01911 build_and_jump (true_label_p),
01912 build_and_jump (false_label_p));
01913 }
01914
01915 if (local_label)
01916 {
01917 t = build1 (LABEL_EXPR, void_type_node, local_label);
01918 append_to_statement_list (t, &expr);
01919 }
01920
01921 return expr;
01922 }
01923
01924 static tree
01925 shortcut_cond_expr (tree expr)
01926 {
01927 tree pred = TREE_OPERAND (expr, 0);
01928 tree then_ = TREE_OPERAND (expr, 1);
01929 tree else_ = TREE_OPERAND (expr, 2);
01930 tree true_label, false_label, end_label, t;
01931 tree *true_label_p;
01932 tree *false_label_p;
01933 bool emit_end, emit_false, jump_over_else;
01934 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
01935 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
01936
01937
01938 if (!else_se)
01939 {
01940
01941 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
01942 {
01943 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
01944 then_ = shortcut_cond_expr (expr);
01945 then_se = then_ && TREE_SIDE_EFFECTS (then_);
01946 pred = TREE_OPERAND (pred, 0);
01947 expr = build (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
01948 }
01949 }
01950 if (!then_se)
01951 {
01952
01953
01954
01955
01956 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
01957 {
01958 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
01959 else_ = shortcut_cond_expr (expr);
01960 else_se = else_ && TREE_SIDE_EFFECTS (else_);
01961 pred = TREE_OPERAND (pred, 0);
01962 expr = build (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
01963 }
01964 }
01965
01966
01967 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
01968 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
01969 return expr;
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979 true_label = false_label = end_label = NULL_TREE;
01980
01981
01982
01983
01984 if (then_
01985 && TREE_CODE (then_) == GOTO_EXPR
01986 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
01987 {
01988 true_label = GOTO_DESTINATION (then_);
01989 then_ = NULL;
01990 then_se = false;
01991 }
01992
01993 if (else_
01994 && TREE_CODE (else_) == GOTO_EXPR
01995 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
01996 {
01997 false_label = GOTO_DESTINATION (else_);
01998 else_ = NULL;
01999 else_se = false;
02000 }
02001
02002
02003 if (true_label)
02004 true_label_p = &true_label;
02005 else
02006 true_label_p = NULL;
02007
02008
02009 if (false_label || else_se)
02010 false_label_p = &false_label;
02011 else
02012 false_label_p = NULL;
02013
02014
02015 if (!then_se && !else_se)
02016 return shortcut_cond_r (pred, true_label_p, false_label_p);
02017
02018
02019 if (else_se)
02020 expr = expr_last (else_);
02021 else if (then_se)
02022 expr = expr_last (then_);
02023 else
02024 expr = NULL;
02025 if (expr && TREE_CODE (expr) == LABEL_EXPR)
02026 end_label = LABEL_EXPR_LABEL (expr);
02027
02028
02029
02030 if (!false_label_p)
02031 false_label_p = &end_label;
02032
02033
02034 emit_end = (end_label == NULL_TREE);
02035 emit_false = (false_label == NULL_TREE);
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045 jump_over_else = block_may_fallthru (then_);
02046
02047 pred = shortcut_cond_r (pred, true_label_p, false_label_p);
02048
02049 expr = NULL;
02050 append_to_statement_list (pred, &expr);
02051
02052 append_to_statement_list (then_, &expr);
02053 if (else_se)
02054 {
02055 if (jump_over_else)
02056 {
02057 t = build_and_jump (&end_label);
02058 append_to_statement_list (t, &expr);
02059 }
02060 if (emit_false)
02061 {
02062 t = build1 (LABEL_EXPR, void_type_node, false_label);
02063 append_to_statement_list (t, &expr);
02064 }
02065 append_to_statement_list (else_, &expr);
02066 }
02067 if (emit_end && end_label)
02068 {
02069 t = build1 (LABEL_EXPR, void_type_node, end_label);
02070 append_to_statement_list (t, &expr);
02071 }
02072
02073 return expr;
02074 }
02075
02076
02077
02078 static tree
02079 gimple_boolify (tree expr)
02080 {
02081 tree type = TREE_TYPE (expr);
02082
02083 if (TREE_CODE (type) == BOOLEAN_TYPE)
02084 return expr;
02085
02086
02087
02088 expr = lang_hooks.truthvalue_conversion (expr);
02089
02090 switch (TREE_CODE (expr))
02091 {
02092 case TRUTH_AND_EXPR:
02093 case TRUTH_OR_EXPR:
02094 case TRUTH_XOR_EXPR:
02095 case TRUTH_ANDIF_EXPR:
02096 case TRUTH_ORIF_EXPR:
02097
02098 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
02099
02100
02101 case TRUTH_NOT_EXPR:
02102 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
02103
02104
02105 case EQ_EXPR: case NE_EXPR:
02106 case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
02107
02108 TREE_TYPE (expr) = boolean_type_node;
02109 return expr;
02110
02111 default:
02112
02113
02114 return convert (boolean_type_node, expr);
02115 }
02116 }
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 static enum gimplify_status
02138 gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target,
02139 fallback_t fallback)
02140 {
02141 tree expr = *expr_p;
02142 tree tmp, tmp2, type;
02143 enum gimplify_status ret;
02144
02145 type = TREE_TYPE (expr);
02146 if (!type)
02147 TREE_TYPE (expr) = void_type_node;
02148
02149
02150
02151 else if (! VOID_TYPE_P (type))
02152 {
02153 tree result;
02154
02155 if (target)
02156 {
02157 ret = gimplify_expr (&target, pre_p, post_p,
02158 is_gimple_min_lval, fb_lvalue);
02159 if (ret != GS_ERROR)
02160 ret = GS_OK;
02161 result = tmp = target;
02162 tmp2 = unshare_expr (target);
02163 }
02164 else if ((fallback & fb_lvalue) == 0)
02165 {
02166 result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
02167 ret = GS_ALL_DONE;
02168 }
02169 else
02170 {
02171 tree type = build_pointer_type (TREE_TYPE (expr));
02172
02173 if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
02174 TREE_OPERAND (expr, 1) =
02175 build_fold_addr_expr (TREE_OPERAND (expr, 1));
02176
02177 if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
02178 TREE_OPERAND (expr, 2) =
02179 build_fold_addr_expr (TREE_OPERAND (expr, 2));
02180
02181 tmp2 = tmp = create_tmp_var (type, "iftmp");
02182
02183 expr = build (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
02184 TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
02185
02186 result = build_fold_indirect_ref (tmp);
02187 ret = GS_ALL_DONE;
02188 }
02189
02190
02191
02192 if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
02193 TREE_OPERAND (expr, 1)
02194 = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
02195
02196
02197 if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
02198 TREE_OPERAND (expr, 2)
02199 = build (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2));
02200
02201 TREE_TYPE (expr) = void_type_node;
02202 recalculate_side_effects (expr);
02203
02204
02205 gimplify_and_add (expr, pre_p);
02206
02207 *expr_p = result;
02208 return ret;
02209 }
02210
02211
02212 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
02213
02214
02215 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
02216 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
02217 {
02218 expr = shortcut_cond_expr (expr);
02219
02220 if (expr != *expr_p)
02221 {
02222 *expr_p = expr;
02223
02224
02225
02226
02227
02228 gimple_push_condition ();
02229 gimplify_stmt (expr_p);
02230 gimple_pop_condition (pre_p);
02231
02232 return GS_ALL_DONE;
02233 }
02234 }
02235
02236
02237 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
02238 is_gimple_condexpr, fb_rvalue);
02239
02240 gimple_push_condition ();
02241
02242 gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
02243 gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
02244 recalculate_side_effects (expr);
02245
02246 gimple_pop_condition (pre_p);
02247
02248 if (ret == GS_ERROR)
02249 ;
02250 else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
02251 ret = GS_ALL_DONE;
02252 else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))
02253
02254 {
02255 TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0));
02256 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
02257 is_gimple_condexpr, fb_rvalue);
02258
02259 tmp = TREE_OPERAND (expr, 1);
02260 TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2);
02261 TREE_OPERAND (expr, 2) = tmp;
02262 }
02263 else
02264
02265 expr = TREE_OPERAND (expr, 0);
02266
02267 *expr_p = expr;
02268 return ret;
02269 }
02270
02271
02272
02273
02274 static enum gimplify_status
02275 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
02276 {
02277 tree args, t, to, to_ptr, from;
02278
02279 to = TREE_OPERAND (*expr_p, 0);
02280 from = TREE_OPERAND (*expr_p, 1);
02281
02282 args = tree_cons (NULL, size, NULL);
02283
02284 t = build_fold_addr_expr (from);
02285 args = tree_cons (NULL, t, args);
02286
02287 to_ptr = build_fold_addr_expr (to);
02288 args = tree_cons (NULL, to_ptr, args);
02289 t = implicit_built_in_decls[BUILT_IN_MEMCPY];
02290 t = build_function_call_expr (t, args);
02291
02292 if (want_value)
02293 {
02294 t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
02295 t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
02296 }
02297
02298 *expr_p = t;
02299 return GS_OK;
02300 }
02301
02302
02303
02304
02305
02306 static enum gimplify_status
02307 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
02308 {
02309 tree args, t, to, to_ptr;
02310
02311 to = TREE_OPERAND (*expr_p, 0);
02312
02313 args = tree_cons (NULL, size, NULL);
02314
02315 args = tree_cons (NULL, integer_zero_node, args);
02316
02317 to_ptr = build_fold_addr_expr (to);
02318 args = tree_cons (NULL, to_ptr, args);
02319 t = implicit_built_in_decls[BUILT_IN_MEMSET];
02320 t = build_function_call_expr (t, args);
02321
02322 if (want_value)
02323 {
02324 t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
02325 t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
02326 }
02327
02328 *expr_p = t;
02329 return GS_OK;
02330 }
02331
02332
02333
02334
02335
02336 struct gimplify_init_ctor_preeval_data
02337 {
02338
02339
02340 tree lhs_base_decl;
02341
02342
02343 int lhs_alias_set;
02344 };
02345
02346 static tree
02347 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
02348 {
02349 struct gimplify_init_ctor_preeval_data *data
02350 = (struct gimplify_init_ctor_preeval_data *) xdata;
02351 tree t = *tp;
02352
02353
02354 if (data->lhs_base_decl == t)
02355 return t;
02356
02357
02358
02359
02360 if (TREE_CODE (t) == INDIRECT_REF
02361 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
02362 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
02363 return t;
02364
02365 if (IS_TYPE_OR_DECL_P (t))
02366 *walk_subtrees = 0;
02367 return NULL;
02368 }
02369
02370
02371
02372
02373
02374 static void
02375 gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
02376 struct gimplify_init_ctor_preeval_data *data)
02377 {
02378 enum gimplify_status one;
02379
02380
02381
02382
02383
02384 if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p))
02385 return;
02386
02387
02388 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
02389 return;
02390
02391
02392 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
02393 {
02394 tree list;
02395 for (list = CONSTRUCTOR_ELTS (*expr_p); list ; list = TREE_CHAIN (list))
02396 gimplify_init_ctor_preeval (&TREE_VALUE (list), pre_p, post_p, data);
02397 return;
02398 }
02399
02400
02401 if (type_contains_placeholder_p (TREE_TYPE (*expr_p)))
02402 return;
02403
02404
02405
02406
02407
02408
02409
02410 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
02411 if (one == GS_ERROR)
02412 {
02413 *expr_p = NULL;
02414 return;
02415 }
02416
02417
02418
02419
02420
02421 if (DECL_P (*expr_p))
02422 return;
02423
02424
02425
02426 if (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p))))
02427 return;
02428
02429
02430 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
02431 return;
02432
02433
02434 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
02435 }
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455 static void gimplify_init_ctor_eval (tree, tree, tree *, bool);
02456
02457 static void
02458 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
02459 tree value, tree array_elt_type,
02460 tree *pre_p, bool cleared)
02461 {
02462 tree loop_entry_label, loop_exit_label;
02463 tree var, var_type, cref;
02464
02465 loop_entry_label = create_artificial_label ();
02466 loop_exit_label = create_artificial_label ();
02467
02468
02469 var_type = TREE_TYPE (upper);
02470 var = create_tmp_var (var_type, NULL);
02471 append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
02472
02473
02474 append_to_statement_list (build1 (LABEL_EXPR,
02475 void_type_node,
02476 loop_entry_label),
02477 pre_p);
02478
02479
02480 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
02481 var, NULL_TREE, NULL_TREE);
02482
02483
02484
02485
02486 if (TREE_CODE (value) == CONSTRUCTOR)
02487
02488
02489 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
02490 pre_p, cleared);
02491 else
02492 append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
02493 cref, value),
02494 pre_p);
02495
02496
02497 gimplify_and_add (build3 (COND_EXPR, void_type_node,
02498 build2 (EQ_EXPR, boolean_type_node,
02499 var, upper),
02500 build1 (GOTO_EXPR,
02501 void_type_node,
02502 loop_exit_label),
02503 NULL_TREE),
02504 pre_p);
02505
02506
02507 append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
02508 build2 (PLUS_EXPR, var_type, var,
02509 fold_convert (var_type,
02510 integer_one_node))),
02511 pre_p);
02512
02513
02514 append_to_statement_list (build1 (GOTO_EXPR,
02515 void_type_node,
02516 loop_entry_label),
02517 pre_p);
02518
02519
02520 append_to_statement_list (build1 (LABEL_EXPR,
02521 void_type_node,
02522 loop_exit_label),
02523 pre_p);
02524 }
02525
02526
02527
02528
02529
02530
02531
02532 static void
02533 gimplify_init_ctor_eval (tree object, tree list, tree *pre_p, bool cleared)
02534 {
02535 tree array_elt_type = NULL;
02536
02537 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
02538 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
02539
02540 for (; list; list = TREE_CHAIN (list))
02541 {
02542 tree purpose, value, cref, init;
02543
02544 purpose = TREE_PURPOSE (list);
02545 value = TREE_VALUE (list);
02546
02547
02548 if (value == NULL)
02549 continue;
02550
02551 if (cleared && initializer_zerop (value))
02552 continue;
02553
02554
02555
02556 gcc_assert (purpose);
02557
02558
02559
02560 if (TREE_CODE (purpose) == RANGE_EXPR)
02561 {
02562 tree lower = TREE_OPERAND (purpose, 0);
02563 tree upper = TREE_OPERAND (purpose, 1);
02564
02565
02566
02567 if (simple_cst_equal (lower, upper))
02568 purpose = upper;
02569 else
02570 {
02571 gimplify_init_ctor_eval_range (object, lower, upper, value,
02572 array_elt_type, pre_p, cleared);
02573 continue;
02574 }
02575 }
02576
02577 if (array_elt_type)
02578 {
02579 cref = build (ARRAY_REF, array_elt_type, unshare_expr (object),
02580 purpose, NULL_TREE, NULL_TREE);
02581 }
02582 else
02583 {
02584 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
02585 cref = build (COMPONENT_REF, TREE_TYPE (purpose),
02586 unshare_expr (object), purpose, NULL_TREE);
02587 }
02588
02589 if (TREE_CODE (value) == CONSTRUCTOR
02590 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
02591 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
02592 pre_p, cleared);
02593 else
02594 {
02595 init = build (MODIFY_EXPR, TREE_TYPE (cref), cref, value);
02596 gimplify_and_add (init, pre_p);
02597 }
02598 }
02599 }
02600
02601
02602
02603
02604
02605
02606
02607
02608 static enum gimplify_status
02609 gimplify_init_constructor (tree *expr_p, tree *pre_p,
02610 tree *post_p, bool want_value)
02611 {
02612 tree object;
02613 tree ctor = TREE_OPERAND (*expr_p, 1);
02614 tree type = TREE_TYPE (ctor);
02615 enum gimplify_status ret;
02616 tree elt_list;
02617
02618 if (TREE_CODE (ctor) != CONSTRUCTOR)
02619 return GS_UNHANDLED;
02620
02621 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
02622 is_gimple_lvalue, fb_lvalue);
02623 if (ret == GS_ERROR)
02624 return ret;
02625 object = TREE_OPERAND (*expr_p, 0);
02626
02627 elt_list = CONSTRUCTOR_ELTS (ctor);
02628
02629 ret = GS_ALL_DONE;
02630 switch (TREE_CODE (type))
02631 {
02632 case RECORD_TYPE:
02633 case UNION_TYPE:
02634 case QUAL_UNION_TYPE:
02635 case ARRAY_TYPE:
02636 {
02637 struct gimplify_init_ctor_preeval_data preeval_data;
02638 HOST_WIDE_INT num_type_elements, num_ctor_elements;
02639 HOST_WIDE_INT num_nonzero_elements, num_nonconstant_elements;
02640 bool cleared;
02641
02642
02643
02644
02645 if (elt_list == NULL)
02646 break;
02647
02648 categorize_ctor_elements (ctor, &num_nonzero_elements,
02649 &num_nonconstant_elements,
02650 &num_ctor_elements, &cleared);
02651
02652
02653
02654 if (num_nonconstant_elements == 0
02655 && num_nonzero_elements > 1
02656 && TREE_READONLY (object)
02657 && TREE_CODE (object) == VAR_DECL)
02658 {
02659 DECL_INITIAL (object) = ctor;
02660 TREE_STATIC (object) = 1;
02661 if (!DECL_NAME (object))
02662 DECL_NAME (object) = create_tmp_var_name ("C");
02663 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
02664
02665
02666
02667
02668
02669
02670
02671
02672 lhd_set_decl_assembler_name (object);
02673
02674 *expr_p = NULL_TREE;
02675 break;
02676 }
02677
02678
02679
02680
02681 if (num_nonconstant_elements == 0)
02682 {
02683 HOST_WIDE_INT size = int_size_in_bytes (type);
02684 unsigned int align;
02685
02686
02687
02688
02689 if (size < 0)
02690 {
02691 size = int_size_in_bytes (TREE_TYPE (object));
02692 if (size >= 0)
02693 TREE_TYPE (ctor) = type = TREE_TYPE (object);
02694 }
02695
02696
02697
02698 if (DECL_P (object))
02699 align = DECL_ALIGN (object);
02700 else
02701 align = TYPE_ALIGN (type);
02702
02703 if (size > 0 && !can_move_by_pieces (size, align))
02704 {
02705 tree new = create_tmp_var_raw (type, "C");
02706
02707 gimple_add_tmp_var (new);
02708 TREE_STATIC (new) = 1;
02709 TREE_READONLY (new) = 1;
02710 DECL_INITIAL (new) = ctor;
02711 if (align > DECL_ALIGN (new))
02712 {
02713 DECL_ALIGN (new) = align;
02714 DECL_USER_ALIGN (new) = 1;
02715 }
02716 walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
02717
02718 TREE_OPERAND (*expr_p, 1) = new;
02719
02720
02721
02722
02723 return GS_UNHANDLED;
02724 }
02725 }
02726
02727
02728
02729
02730
02731
02732
02733
02734 num_type_elements = count_type_elements (type);
02735
02736
02737
02738
02739
02740 if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
02741 cleared = true;
02742
02743 else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
02744 && num_nonzero_elements < num_type_elements/4)
02745 cleared = true;
02746
02747
02748
02749
02750
02751 else if (num_ctor_elements < num_type_elements)
02752 cleared = true;
02753
02754 if (cleared)
02755 {
02756
02757
02758
02759 CONSTRUCTOR_ELTS (ctor) = NULL_TREE;
02760 object = unshare_expr (object);
02761 gimplify_stmt (expr_p);
02762 append_to_statement_list (*expr_p, pre_p);
02763 }
02764
02765
02766
02767
02768 if (!cleared || num_nonzero_elements > 0)
02769 {
02770 preeval_data.lhs_base_decl = get_base_address (object);
02771 if (!DECL_P (preeval_data.lhs_base_decl))
02772 preeval_data.lhs_base_decl = NULL;
02773 preeval_data.lhs_alias_set = get_alias_set (object);
02774
02775 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
02776 pre_p, post_p, &preeval_data);
02777 gimplify_init_ctor_eval (object, elt_list, pre_p, cleared);
02778 }
02779
02780 *expr_p = NULL_TREE;
02781 }
02782 break;
02783
02784 case COMPLEX_TYPE:
02785 {
02786 tree r, i;
02787
02788
02789 r = i = NULL_TREE;
02790 if (elt_list)
02791 {
02792 r = TREE_VALUE (elt_list);
02793 elt_list = TREE_CHAIN (elt_list);
02794 if (elt_list)
02795 {
02796 i = TREE_VALUE (elt_list);
02797 gcc_assert (!TREE_CHAIN (elt_list));
02798 }
02799 }
02800 if (r == NULL || i == NULL)
02801 {
02802 tree zero = convert (TREE_TYPE (type), integer_zero_node);
02803 if (r == NULL)
02804 r = zero;
02805 if (i == NULL)
02806 i = zero;
02807 }
02808
02809
02810
02811 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
02812 {
02813 ctor = build_complex (type, r, i);
02814 TREE_OPERAND (*expr_p, 1) = ctor;
02815 }
02816 else
02817 {
02818 ctor = build (COMPLEX_EXPR, type, r, i);
02819 TREE_OPERAND (*expr_p, 1) = ctor;
02820 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
02821 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
02822 fb_rvalue);
02823 }
02824 }
02825 break;
02826
02827 case VECTOR_TYPE:
02828
02829 if (TREE_CONSTANT (ctor))
02830 {
02831 tree tem;
02832
02833
02834
02835
02836 for (tem = elt_list; tem; tem = TREE_CHAIN (tem))
02837 if (! CONSTANT_CLASS_P (TREE_VALUE (tem)))
02838 break;
02839
02840 if (! tem)
02841 {
02842 TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list);
02843 break;
02844 }
02845 }
02846
02847
02848
02849 for (; elt_list; elt_list = TREE_CHAIN (elt_list))
02850 {
02851 enum gimplify_status tret;
02852 tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
02853 is_gimple_val, fb_rvalue);
02854 if (tret == GS_ERROR)
02855 ret = GS_ERROR;
02856 }
02857 break;
02858
02859 default:
02860
02861 gcc_unreachable ();
02862 }
02863
02864 if (ret == GS_ERROR)
02865 return GS_ERROR;
02866 else if (want_value)
02867 {
02868 append_to_statement_list (*expr_p, pre_p);
02869 *expr_p = object;
02870 return GS_OK;
02871 }
02872 else
02873 return GS_ALL_DONE;
02874 }
02875
02876
02877
02878
02879 static enum gimplify_status
02880 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
02881 tree *post_p, bool want_value)
02882 {
02883 enum gimplify_status ret = GS_OK;
02884
02885 while (ret != GS_UNHANDLED)
02886 switch (TREE_CODE (*from_p))
02887 {
02888 case INDIRECT_REF:
02889 {
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899 tree t = fold_indirect_ref (*from_p);
02900 if (t != *from_p)
02901 {
02902 *from_p = t;
02903 ret = GS_OK;
02904 }
02905 else
02906 ret = GS_UNHANDLED;
02907 break;
02908 }
02909
02910 case TARGET_EXPR:
02911 {
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922 tree init = TARGET_EXPR_INITIAL (*from_p);
02923
02924 if (!VOID_TYPE_P (TREE_TYPE (init)))
02925 {
02926 *from_p = init;
02927 ret = GS_OK;
02928 }
02929 else
02930 ret = GS_UNHANDLED;
02931 }
02932 break;
02933
02934 case COMPOUND_EXPR:
02935
02936
02937 gimplify_compound_expr (from_p, pre_p, true);
02938 ret = GS_OK;
02939 break;
02940
02941 case CONSTRUCTOR:
02942
02943
02944 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
02945
02946 case COND_EXPR:
02947
02948
02949
02950
02951 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
02952 {
02953 *expr_p = *from_p;
02954 return gimplify_cond_expr (expr_p, pre_p, post_p, *to_p,
02955 fb_rvalue);
02956 }
02957 else
02958 ret = GS_UNHANDLED;
02959 break;
02960
02961 default:
02962 ret = GS_UNHANDLED;
02963 break;
02964 }
02965
02966 return ret;
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984 static enum gimplify_status
02985 gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
02986 {
02987 tree *from_p = &TREE_OPERAND (*expr_p, 1);
02988 tree *to_p = &TREE_OPERAND (*expr_p, 0);
02989 enum gimplify_status ret = GS_UNHANDLED;
02990
02991 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
02992 || TREE_CODE (*expr_p) == INIT_EXPR);
02993
02994
02995 if (TREE_CODE (*expr_p) == INIT_EXPR)
02996 TREE_SET_CODE (*expr_p, MODIFY_EXPR);
02997
02998
02999 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
03000 want_value);
03001 if (ret != GS_UNHANDLED)
03002 return ret;
03003
03004
03005
03006
03007
03008
03009
03010 maybe_with_size_expr (from_p);
03011
03012 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
03013 if (ret == GS_ERROR)
03014 return ret;
03015
03016 ret = gimplify_expr (from_p, pre_p, post_p,
03017 rhs_predicate_for (*to_p), fb_rvalue);
03018 if (ret == GS_ERROR)
03019 return ret;
03020
03021
03022 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
03023 want_value);
03024 if (ret != GS_UNHANDLED)
03025 return ret;
03026
03027
03028
03029
03030 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
03031 {
03032 tree from = TREE_OPERAND (*from_p, 0);
03033 tree size = TREE_OPERAND (*from_p, 1);
03034
03035 if (TREE_CODE (from) == CONSTRUCTOR)
03036 return gimplify_modify_expr_to_memset (expr_p, size, want_value);
03037 if (is_gimple_addressable (from))
03038 {
03039 *from_p = from;
03040 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
03041 }
03042 }
03043
03044 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
03045 {
03046
03047
03048 gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
03049 *to_p = make_ssa_name (*to_p, *expr_p);
03050 }
03051
03052 if (want_value)
03053 {
03054 append_to_statement_list (*expr_p, pre_p);
03055 *expr_p = *to_p;
03056 return GS_OK;
03057 }
03058
03059 return GS_ALL_DONE;
03060 }
03061
03062
03063
03064
03065 static enum gimplify_status
03066 gimplify_variable_sized_compare (tree *expr_p)
03067 {
03068 tree op0 = TREE_OPERAND (*expr_p, 0);
03069 tree op1 = TREE_OPERAND (*expr_p, 1);
03070 tree args, t, dest;
03071
03072 t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
03073 t = unshare_expr (t);
03074 t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
03075 args = tree_cons (NULL, t, NULL);
03076 t = build_fold_addr_expr (op1);
03077 args = tree_cons (NULL, t, args);
03078 dest = build_fold_addr_expr (op0);
03079 args = tree_cons (NULL, dest, args);
03080 t = implicit_built_in_decls[BUILT_IN_MEMCMP];
03081 t = build_function_call_expr (t, args);
03082 *expr_p
03083 = build (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
03084
03085 return GS_OK;
03086 }
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100 static enum gimplify_status
03101 gimplify_boolean_expr (tree *expr_p)
03102 {
03103
03104 tree type = TREE_TYPE (*expr_p);
03105
03106 *expr_p = build (COND_EXPR, type, *expr_p,
03107 convert (type, boolean_true_node),
03108 convert (type, boolean_false_node));
03109
03110 return GS_OK;
03111 }
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125 static enum gimplify_status
03126 gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
03127 {
03128 tree t = *expr_p;
03129
03130 do
03131 {
03132 tree *sub_p = &TREE_OPERAND (t, 0);
03133
03134 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
03135 gimplify_compound_expr (sub_p, pre_p, false);
03136 else
03137 gimplify_stmt (sub_p);
03138 append_to_statement_list (*sub_p, pre_p);
03139
03140 t = TREE_OPERAND (t, 1);
03141 }
03142 while (TREE_CODE (t) == COMPOUND_EXPR);
03143
03144 *expr_p = t;
03145 if (want_value)
03146 return GS_OK;
03147 else
03148 {
03149 gimplify_stmt (expr_p);
03150 return GS_ALL_DONE;
03151 }
03152 }
03153
03154
03155
03156
03157 static enum gimplify_status
03158 gimplify_statement_list (tree *expr_p)
03159 {
03160 tree_stmt_iterator i = tsi_start (*expr_p);
03161
03162 while (!tsi_end_p (i))
03163 {
03164 tree t;
03165
03166 gimplify_stmt (tsi_stmt_ptr (i));
03167
03168 t = tsi_stmt (i);
03169 if (t == NULL)
03170 tsi_delink (&i);
03171 else if (TREE_CODE (t) == STATEMENT_LIST)
03172 {
03173 tsi_link_before (&i, t, TSI_SAME_STMT);
03174 tsi_delink (&i);
03175 }
03176 else
03177 tsi_next (&i);
03178 }
03179
03180 return GS_ALL_DONE;
03181 }
03182
03183
03184
03185
03186
03187
03188
03189
03190 static enum gimplify_status
03191 gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
03192 {
03193 enum gimplify_status ret = GS_ALL_DONE;
03194 tree val;
03195
03196 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
03197 val = TREE_OPERAND (*expr_p, 0);
03198
03199
03200 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
03201 {
03202
03203
03204
03205 if (TREE_TYPE (val) == void_type_node)
03206 {
03207 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
03208 is_gimple_stmt, fb_none);
03209 append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p);
03210 val = NULL;
03211 }
03212 else
03213 val = get_initialized_tmp_var (val, pre_p, post_p);
03214
03215 TREE_OPERAND (*expr_p, 0) = val;
03216 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
03217 }
03218
03219 *expr_p = val;
03220
03221 return ret;
03222 }
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237 static enum gimplify_status
03238 gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
03239 {
03240 tree expr = *expr_p;
03241 tree op0 = TREE_OPERAND (expr, 0);
03242 enum gimplify_status ret;
03243
03244 switch (TREE_CODE (op0))
03245 {
03246 case INDIRECT_REF:
03247 case MISALIGNED_INDIRECT_REF:
03248 do_indirect_ref:
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258 {
03259 tree op00 = TREE_OPERAND (op0, 0);
03260 tree t_expr = TREE_TYPE (expr);
03261 tree t_op00 = TREE_TYPE (op00);
03262
03263 if (!lang_hooks.types_compatible_p (t_expr, t_op00))
03264 {
03265 #ifdef ENABLE_CHECKING
03266 tree t_op0 = TREE_TYPE (op0);
03267 gcc_assert (POINTER_TYPE_P (t_expr)
03268 && cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE
03269 ? TREE_TYPE (t_op0) : t_op0,
03270 TREE_TYPE (t_expr))
03271 && POINTER_TYPE_P (t_op00)
03272 && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
03273 #endif
03274 op00 = fold_convert (TREE_TYPE (expr), op00);
03275 }
03276 *expr_p = op00;
03277 ret = GS_OK;
03278 }
03279 break;
03280
03281 case VIEW_CONVERT_EXPR:
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
03292 op0 = TREE_OPERAND (op0, 0);
03293
03294 *expr_p = fold_convert (TREE_TYPE (expr),
03295 build_fold_addr_expr (TREE_OPERAND (op0, 0)));
03296 ret = GS_OK;
03297 break;
03298
03299 default:
03300
03301
03302
03303
03304 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
03305 is_gimple_addressable, fb_either);
03306 if (ret != GS_ERROR)
03307 {
03308 op0 = TREE_OPERAND (expr, 0);
03309
03310
03311
03312 if (TREE_CODE (op0) == INDIRECT_REF)
03313 goto do_indirect_ref;
03314
03315
03316
03317 recompute_tree_invarant_for_addr_expr (expr);
03318
03319
03320 lang_hooks.mark_addressable (TREE_OPERAND (expr, 0));
03321 }
03322 break;
03323 }
03324
03325 return ret;
03326 }
03327
03328
03329
03330
03331 static enum gimplify_status
03332 gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
03333 {
03334 tree expr = *expr_p;
03335 int noutputs = list_length (ASM_OUTPUTS (expr));
03336 const char **oconstraints
03337 = (const char **) alloca ((noutputs) * sizeof (const char *));
03338 int i;
03339 tree link;
03340 const char *constraint;
03341 bool allows_mem, allows_reg, is_inout;
03342 enum gimplify_status ret, tret;
03343
03344 ret = GS_ALL_DONE;
03345 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
03346 {
03347 size_t constraint_len;
03348 oconstraints[i] = constraint
03349 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
03350 constraint_len = strlen (constraint);
03351 if (constraint_len == 0)
03352 continue;
03353
03354 parse_output_constraint (&constraint, i, 0, 0,
03355 &allows_mem, &allows_reg, &is_inout);
03356
03357 if (!allows_reg && allows_mem)
03358 lang_hooks.mark_addressable (TREE_VALUE (link));
03359
03360 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
03361 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
03362 fb_lvalue | fb_mayfail);
03363 if (tret == GS_ERROR)
03364 {
03365 error ("invalid lvalue in asm output %d", i);
03366 ret = tret;
03367 }
03368
03369 if (is_inout)
03370 {
03371
03372
03373
03374 tree input;
03375 char buf[10];
03376
03377
03378 char *p = xstrdup (constraint);
03379 p[0] = '=';
03380 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
03381
03382
03383 if (allows_reg)
03384 {
03385 sprintf (buf, "%d", i);
03386
03387
03388
03389
03390
03391 if (strchr (p, ',') != NULL)
03392 {
03393 size_t len = 0, buflen = strlen (buf);
03394 char *beg, *end, *str, *dst;
03395
03396 for (beg = p + 1;;)
03397 {
03398 end = strchr (beg, ',');
03399 if (end == NULL)
03400 end = strchr (beg, '\0');
03401 if ((size_t) (end - beg) < buflen)
03402 len += buflen + 1;
03403 else
03404 len += end - beg + 1;
03405 if (*end)
03406 beg = end + 1;
03407 else
03408 break;
03409 }
03410
03411 str = alloca (len);
03412 for (beg = p + 1, dst = str;;)
03413 {
03414 const char *tem;
03415 bool mem_p, reg_p, inout_p;
03416
03417 end = strchr (beg, ',');
03418 if (end)
03419 *end = '\0';
03420 beg[-1] = '=';
03421 tem = beg - 1;
03422 parse_output_constraint (&tem, i, 0, 0,
03423 &mem_p, ®_p, &inout_p);
03424 if (dst != str)
03425 *dst++ = ',';
03426 if (reg_p)
03427 {
03428 memcpy (dst, buf, buflen);
03429 dst += buflen;
03430 }
03431 else
03432 {
03433 if (end)
03434 len = end - beg;
03435 else
03436 len = strlen (beg);
03437 memcpy (dst, beg, len);
03438 dst += len;
03439 }
03440 if (end)
03441 beg = end + 1;
03442 else
03443 break;
03444 }
03445 *dst = '\0';
03446 input = build_string (dst - str, str);
03447 }
03448 else
03449 input = build_string (strlen (buf), buf);
03450 }
03451 else
03452 input = build_string (constraint_len - 1, constraint + 1);
03453
03454 free (p);
03455
03456 input = build_tree_list (build_tree_list (NULL_TREE, input),
03457 unshare_expr (TREE_VALUE (link)));
03458 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
03459 }
03460 }
03461
03462 for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
03463 {
03464 constraint
03465 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
03466 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
03467 oconstraints, &allows_mem, &allows_reg);
03468
03469
03470 if (!allows_reg && allows_mem)
03471 {
03472 lang_hooks.mark_addressable (TREE_VALUE (link));
03473 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
03474 is_gimple_lvalue, fb_lvalue | fb_mayfail);
03475 if (tret == GS_ERROR)
03476 {
03477 error ("memory input %d is not directly addressable", i);
03478 ret = tret;
03479 }
03480 }
03481 else
03482 {
03483 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
03484 is_gimple_asm_val, fb_rvalue);
03485 if (tret == GS_ERROR)
03486 ret = tret;
03487 }
03488 }
03489
03490 return ret;
03491 }
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507 static enum gimplify_status
03508 gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
03509 {
03510 tree_stmt_iterator iter;
03511 tree body;
03512
03513 tree temp = voidify_wrapper_expr (*expr_p, NULL);
03514
03515
03516
03517 int old_conds = gimplify_ctxp->conditions;
03518 gimplify_ctxp->conditions = 0;
03519
03520 body = TREE_OPERAND (*expr_p, 0);
03521 gimplify_to_stmt_list (&body);
03522
03523 gimplify_ctxp->conditions = old_conds;
03524
03525 for (iter = tsi_start (body); !tsi_end_p (iter); )
03526 {
03527 tree *wce_p = tsi_stmt_ptr (iter);
03528 tree wce = *wce_p;
03529
03530 if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
03531 {
03532 if (tsi_one_before_end_p (iter))
03533 {
03534 tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT);
03535 tsi_delink (&iter);
03536 break;
03537 }
03538 else
03539 {
03540 tree sl, tfe;
03541 enum tree_code code;
03542
03543 if (CLEANUP_EH_ONLY (wce))
03544 code = TRY_CATCH_EXPR;
03545 else
03546 code = TRY_FINALLY_EXPR;
03547
03548 sl = tsi_split_statement_list_after (&iter);
03549 tfe = build (code, void_type_node, sl, NULL_TREE);
03550 append_to_statement_list (TREE_OPERAND (wce, 0),
03551 &TREE_OPERAND (tfe, 1));
03552 *wce_p = tfe;
03553 iter = tsi_start (sl);
03554 }
03555 }
03556 else
03557 tsi_next (&iter);
03558 }
03559
03560 if (temp)
03561 {
03562 *expr_p = temp;
03563 append_to_statement_list (body, pre_p);
03564 return GS_OK;
03565 }
03566 else
03567 {
03568 *expr_p = body;
03569 return GS_ALL_DONE;
03570 }
03571 }
03572
03573
03574
03575
03576 static void
03577 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
03578 {
03579 tree wce;
03580
03581
03582
03583 if (errorcount || sorrycount)
03584 return;
03585
03586 if (gimple_conditional_context ())
03587 {
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609 tree flag = create_tmp_var (boolean_type_node, "cleanup");
03610 tree ffalse = build (MODIFY_EXPR, void_type_node, flag,
03611 boolean_false_node);
03612 tree ftrue = build (MODIFY_EXPR, void_type_node, flag,
03613 boolean_true_node);
03614 cleanup = build (COND_EXPR, void_type_node, flag, cleanup, NULL);
03615 wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup);
03616 append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
03617 append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
03618 append_to_statement_list (ftrue, pre_p);
03619
03620
03621
03622
03623 TREE_NO_WARNING (var) = 1;
03624 }
03625 else
03626 {
03627 wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup);
03628 CLEANUP_EH_ONLY (wce) = eh_only;
03629 append_to_statement_list (wce, pre_p);
03630 }
03631
03632 gimplify_stmt (&TREE_OPERAND (wce, 0));
03633 }
03634
03635
03636
03637 static enum gimplify_status
03638 gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
03639 {
03640 tree targ = *expr_p;
03641 tree temp = TARGET_EXPR_SLOT (targ);
03642 tree init = TARGET_EXPR_INITIAL (targ);
03643 enum gimplify_status ret;
03644
03645 if (init)
03646 {
03647
03648
03649 gimple_add_tmp_var (temp);
03650
03651
03652
03653 if (VOID_TYPE_P (TREE_TYPE (init)))
03654 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
03655 else
03656 {
03657
03658 ret = GS_OK;
03659 if (TREE_CODE (init) == BIND_EXPR)
03660 gimplify_bind_expr (&init, temp, pre_p);
03661 if (init != temp)
03662 {
03663 init = build (MODIFY_EXPR, void_type_node, temp, init);
03664 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
03665 fb_none);
03666 }
03667 }
03668 if (ret == GS_ERROR)
03669 return GS_ERROR;
03670 append_to_statement_list (init, pre_p);
03671
03672
03673 if (TARGET_EXPR_CLEANUP (targ))
03674 {
03675 gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
03676 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
03677 CLEANUP_EH_ONLY (targ), pre_p);
03678 #ifdef KEY
03679 if (flag_spin_file) {
03680 EMIT_TARGET_EXPR_CLEANUP(targ) = 1;
03681 if (gspin_invoked (targ))
03682 gs_set_flag_value (targ, GS_EMIT_TARGET_EXPR_CLEANUP, 1);
03683 }
03684 #endif
03685 }
03686
03687
03688 TREE_OPERAND (targ, 3) = init;
03689 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
03690 }
03691 else
03692
03693 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
03694
03695 *expr_p = temp;
03696 return GS_OK;
03697 }
03698
03699
03700
03701
03702
03703
03704 void
03705 gimplify_stmt (tree *stmt_p)
03706 {
03707 gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
03708 }
03709
03710
03711
03712 void
03713 gimplify_to_stmt_list (tree *stmt_p)
03714 {
03715 gimplify_stmt (stmt_p);
03716 if (!*stmt_p)
03717 *stmt_p = alloc_stmt_list ();
03718 else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
03719 {
03720 tree t = *stmt_p;
03721 *stmt_p = alloc_stmt_list ();
03722 append_to_statement_list (t, stmt_p);
03723 }
03724 }
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756 enum gimplify_status
03757 gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
03758 bool (* gimple_test_f) (tree), fallback_t fallback)
03759 {
03760 tree tmp;
03761 tree internal_pre = NULL_TREE;
03762 tree internal_post = NULL_TREE;
03763 tree save_expr;
03764 int is_statement = (pre_p == NULL);
03765 location_t saved_location;
03766 enum gimplify_status ret;
03767
03768 save_expr = *expr_p;
03769 if (save_expr == NULL_TREE)
03770 return GS_ALL_DONE;
03771
03772
03773
03774
03775
03776
03777
03778 if (pre_p == NULL)
03779 pre_p = &internal_pre;
03780 if (post_p == NULL)
03781 post_p = &internal_post;
03782
03783 saved_location = input_location;
03784 if (save_expr != error_mark_node
03785 && EXPR_HAS_LOCATION (*expr_p))
03786 input_location = EXPR_LOCATION (*expr_p);
03787
03788
03789
03790 do
03791 {
03792
03793
03794 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
03795
03796
03797 save_expr = *expr_p;
03798
03799
03800 if (save_expr == error_mark_node
03801 || (TREE_TYPE (save_expr)
03802 && TREE_TYPE (save_expr) == error_mark_node))
03803 {
03804 ret = GS_ERROR;
03805 break;
03806 }
03807
03808
03809 ret = lang_hooks.gimplify_expr (expr_p, pre_p, post_p);
03810 if (ret == GS_OK)
03811 {
03812 if (*expr_p == NULL_TREE)
03813 break;
03814 if (*expr_p != save_expr)
03815 continue;
03816 }
03817 else if (ret != GS_UNHANDLED)
03818 break;
03819
03820 ret = GS_OK;
03821 switch (TREE_CODE (*expr_p))
03822 {
03823
03824
03825 case POSTINCREMENT_EXPR:
03826 case POSTDECREMENT_EXPR:
03827 case PREINCREMENT_EXPR:
03828 case PREDECREMENT_EXPR:
03829 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
03830 fallback != fb_none);
03831 break;
03832
03833 case ARRAY_REF:
03834 case ARRAY_RANGE_REF:
03835 case REALPART_EXPR:
03836 case IMAGPART_EXPR:
03837 case COMPONENT_REF:
03838 case VIEW_CONVERT_EXPR:
03839 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
03840 fallback ? fallback : fb_rvalue);
03841 break;
03842
03843 case COND_EXPR:
03844 ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE,
03845 fallback);
03846
03847
03848
03849
03850 if (fallback == fb_lvalue)
03851 {
03852 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
03853 lang_hooks.mark_addressable (*expr_p);
03854 }
03855 break;
03856
03857 case CALL_EXPR:
03858 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
03859
03860
03861
03862
03863 if (fallback == fb_lvalue)
03864 {
03865 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
03866 lang_hooks.mark_addressable (*expr_p);
03867 }
03868 break;
03869
03870 case TREE_LIST:
03871 gcc_unreachable ();
03872
03873 case COMPOUND_EXPR:
03874 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
03875 break;
03876
03877 case MODIFY_EXPR:
03878 case INIT_EXPR:
03879 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
03880 fallback != fb_none);
03881 break;
03882
03883 case TRUTH_ANDIF_EXPR:
03884 case TRUTH_ORIF_EXPR:
03885 ret = gimplify_boolean_expr (expr_p);
03886 break;
03887
03888 case TRUTH_NOT_EXPR:
03889 TREE_OPERAND (*expr_p, 0)
03890 = gimple_boolify (TREE_OPERAND (*expr_p, 0));
03891 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
03892 is_gimple_val, fb_rvalue);
03893 recalculate_side_effects (*expr_p);
03894 break;
03895
03896 case ADDR_EXPR:
03897 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
03898 break;
03899
03900 case VA_ARG_EXPR:
03901 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
03902 break;
03903
03904 case CONVERT_EXPR:
03905 case NOP_EXPR:
03906 if (IS_EMPTY_STMT (*expr_p))
03907 {
03908 ret = GS_ALL_DONE;
03909 break;
03910 }
03911
03912 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
03913 || fallback == fb_none)
03914 {
03915
03916
03917 *expr_p = TREE_OPERAND (*expr_p, 0);
03918 break;
03919 }
03920
03921 ret = gimplify_conversion (expr_p);
03922 if (ret == GS_ERROR)
03923 break;
03924 if (*expr_p != save_expr)
03925 break;
03926
03927
03928 case FIX_TRUNC_EXPR:
03929 case FIX_CEIL_EXPR:
03930 case FIX_FLOOR_EXPR:
03931 case FIX_ROUND_EXPR:
03932
03933 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
03934 is_gimple_val, fb_rvalue);
03935 recalculate_side_effects (*expr_p);
03936 break;
03937
03938 case INDIRECT_REF:
03939 *expr_p = fold_indirect_ref (*expr_p);
03940 if (*expr_p != save_expr)
03941 break;
03942
03943 case ALIGN_INDIRECT_REF:
03944 case MISALIGNED_INDIRECT_REF:
03945 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
03946 is_gimple_reg, fb_rvalue);
03947 recalculate_side_effects (*expr_p);
03948 break;
03949
03950
03951 case INTEGER_CST:
03952 case REAL_CST:
03953 case STRING_CST:
03954 case COMPLEX_CST:
03955 case VECTOR_CST:
03956 ret = GS_ALL_DONE;
03957 break;
03958
03959 case CONST_DECL:
03960
03961
03962
03963
03964 if (fallback & fb_lvalue)
03965 ret = GS_ALL_DONE;
03966 else
03967 *expr_p = DECL_INITIAL (*expr_p);
03968 break;
03969
03970 case DECL_EXPR:
03971 ret = gimplify_decl_expr (expr_p);
03972 break;
03973
03974 case EXC_PTR_EXPR:
03975
03976 ret = GS_ALL_DONE;
03977 break;
03978
03979 case BIND_EXPR:
03980 ret = gimplify_bind_expr (expr_p, NULL, pre_p);
03981 break;
03982
03983 case LOOP_EXPR:
03984 ret = gimplify_loop_expr (expr_p, pre_p);
03985 break;
03986
03987 case SWITCH_EXPR:
03988 ret = gimplify_switch_expr (expr_p, pre_p);
03989 break;
03990
03991 case EXIT_EXPR:
03992 ret = gimplify_exit_expr (expr_p);
03993 break;
03994
03995 case GOTO_EXPR:
03996
03997
03998 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
03999 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
04000 NULL, is_gimple_val, fb_rvalue);
04001 break;
04002
04003 case LABEL_EXPR:
04004 ret = GS_ALL_DONE;
04005 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
04006 == current_function_decl);
04007 break;
04008
04009 case CASE_LABEL_EXPR:
04010 ret = gimplify_case_label_expr (expr_p);
04011 break;
04012
04013 case RETURN_EXPR:
04014 ret = gimplify_return_expr (*expr_p, pre_p);
04015 break;
04016
04017 case CONSTRUCTOR:
04018
04019
04020
04021 if (fallback == fb_none)
04022 {
04023 for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp;
04024 tmp = TREE_CHAIN (tmp))
04025 if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp)))
04026 gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p,
04027 gimple_test_f, fallback);
04028
04029 *expr_p = NULL_TREE;
04030 }
04031
04032 ret = GS_ALL_DONE;
04033 break;
04034
04035
04036
04037
04038
04039
04040 case SAVE_EXPR:
04041 ret = gimplify_save_expr (expr_p, pre_p, post_p);
04042 break;
04043
04044 case BIT_FIELD_REF:
04045 {
04046 enum gimplify_status r0, r1, r2;
04047
04048 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
04049 is_gimple_lvalue, fb_either);
04050 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
04051 is_gimple_val, fb_rvalue);
04052 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
04053 is_gimple_val, fb_rvalue);
04054 recalculate_side_effects (*expr_p);
04055
04056 ret = MIN (r0, MIN (r1, r2));
04057 }
04058 break;
04059
04060 case NON_LVALUE_EXPR:
04061
04062 gcc_unreachable ();
04063
04064 case ASM_EXPR:
04065 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
04066 break;
04067
04068 case TRY_FINALLY_EXPR:
04069 case TRY_CATCH_EXPR:
04070 gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0));
04071 gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1));
04072 ret = GS_ALL_DONE;
04073 break;
04074
04075 case CLEANUP_POINT_EXPR:
04076 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
04077 break;
04078
04079 case TARGET_EXPR:
04080 ret = gimplify_target_expr (expr_p, pre_p, post_p);
04081 break;
04082
04083 case CATCH_EXPR:
04084 gimplify_to_stmt_list (&CATCH_BODY (*expr_p));
04085 ret = GS_ALL_DONE;
04086 break;
04087
04088 case EH_FILTER_EXPR:
04089 gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p));
04090 ret = GS_ALL_DONE;
04091 break;
04092
04093 case OBJ_TYPE_REF:
04094 {
04095 enum gimplify_status r0, r1;
04096 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
04097 is_gimple_val, fb_rvalue);
04098 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
04099 is_gimple_val, fb_rvalue);
04100 ret = MIN (r0, r1);
04101 }
04102 break;
04103
04104 case LABEL_DECL:
04105
04106
04107
04108 FORCED_LABEL (*expr_p) = 1;
04109 ret = GS_ALL_DONE;
04110 break;
04111
04112 case STATEMENT_LIST:
04113 ret = gimplify_statement_list (expr_p);
04114 break;
04115
04116 case WITH_SIZE_EXPR:
04117 {
04118 enum gimplify_status r0, r1;
04119 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
04120 post_p == &internal_post ? NULL : post_p,
04121 gimple_test_f, fallback);
04122 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
04123 is_gimple_val, fb_rvalue);
04124 }
04125 break;
04126
04127 case VAR_DECL:
04128
04129
04130
04131
04132
04133
04134 tmp = *expr_p;
04135 if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
04136 && decl_function_context (tmp) == current_function_decl
04137 && !DECL_SEEN_IN_BIND_EXPR_P (tmp))
04138 {
04139 gcc_assert (errorcount || sorrycount);
04140 ret = GS_ERROR;
04141 break;
04142 }
04143
04144
04145 case PARM_DECL:
04146 tmp = *expr_p;
04147
04148
04149
04150 if (DECL_VALUE_EXPR (tmp))
04151 {
04152 *expr_p = unshare_expr (DECL_VALUE_EXPR (tmp));
04153 ret = GS_OK;
04154 break;
04155 }
04156
04157 ret = GS_ALL_DONE;
04158 break;
04159
04160 case SSA_NAME:
04161
04162 ret = GS_ALL_DONE;
04163 break;
04164
04165 default:
04166 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
04167 {
04168 case tcc_comparison:
04169
04170
04171
04172
04173
04174
04175 if (!AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 1))))
04176 goto expr_2;
04177 ret = gimplify_variable_sized_compare (expr_p);
04178 break;
04179
04180
04181
04182 case tcc_unary:
04183 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
04184 post_p, is_gimple_val, fb_rvalue);
04185 break;
04186
04187 case tcc_binary:
04188 expr_2:
04189 {
04190 enum gimplify_status r0, r1;
04191
04192 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
04193 post_p, is_gimple_val, fb_rvalue);
04194 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
04195 post_p, is_gimple_val, fb_rvalue);
04196
04197 ret = MIN (r0, r1);
04198 break;
04199 }
04200
04201 case tcc_declaration:
04202 case tcc_constant:
04203 ret = GS_ALL_DONE;
04204 goto dont_recalculate;
04205
04206 default:
04207 gcc_assert (TREE_CODE (*expr_p) == TRUTH_AND_EXPR
04208 || TREE_CODE (*expr_p) == TRUTH_OR_EXPR
04209 || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR);
04210 goto expr_2;
04211 }
04212
04213 recalculate_side_effects (*expr_p);
04214 dont_recalculate:
04215 break;
04216 }
04217
04218
04219 if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr))
04220 ret = GS_ALL_DONE;
04221 }
04222 while (ret == GS_OK);
04223
04224
04225
04226 if (ret == GS_ERROR)
04227 {
04228 if (is_statement)
04229 *expr_p = NULL;
04230 goto out;
04231 }
04232
04233
04234
04235 gcc_assert (ret != GS_UNHANDLED);
04236
04237 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
04238 {
04239
04240
04241 if (!TREE_SIDE_EFFECTS (*expr_p))
04242 *expr_p = NULL;
04243 else if (!TREE_THIS_VOLATILE (*expr_p))
04244 {
04245
04246
04247 enum tree_code code = TREE_CODE (*expr_p);
04248
04249 switch (code)
04250 {
04251 case COMPONENT_REF:
04252 case REALPART_EXPR: case IMAGPART_EXPR:
04253 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
04254 gimple_test_f, fallback);
04255 break;
04256
04257 case ARRAY_REF: case ARRAY_RANGE_REF:
04258 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
04259 gimple_test_f, fallback);
04260 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
04261 gimple_test_f, fallback);
04262 break;
04263
04264 default:
04265
04266
04267 gcc_unreachable ();
04268 }
04269
04270 *expr_p = NULL;
04271 }
04272 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
04273 {
04274
04275
04276 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
04277
04278
04279
04280
04281
04282
04283
04284 tree tmp = create_tmp_var_raw (type, "vol");
04285 gimple_add_tmp_var (tmp);
04286 *expr_p = build (MODIFY_EXPR, type, tmp, *expr_p);
04287 }
04288 else
04289
04290
04291 *expr_p = NULL;
04292 }
04293
04294
04295
04296
04297 if (fallback == fb_none || is_statement)
04298 {
04299 if (internal_pre || internal_post)
04300 {
04301 append_to_statement_list (*expr_p, &internal_pre);
04302 append_to_statement_list (internal_post, &internal_pre);
04303 annotate_all_with_locus (&internal_pre, input_location);
04304 *expr_p = internal_pre;
04305 }
04306 else if (!*expr_p)
04307 ;
04308 else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
04309 annotate_all_with_locus (expr_p, input_location);
04310 else
04311 annotate_one_with_locus (*expr_p, input_location);
04312 goto out;
04313 }
04314
04315
04316
04317
04318
04319
04320
04321 if (!internal_post && (*gimple_test_f) (*expr_p))
04322 goto out;
04323
04324
04325
04326
04327
04328
04329
04330
04331 if ((fallback & fb_lvalue) && !internal_post
04332 && is_gimple_addressable (*expr_p))
04333 {
04334
04335
04336
04337 tmp = build_fold_addr_expr (*expr_p);
04338 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
04339 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
04340 }
04341 else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
04342 {
04343 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
04344
04345
04346
04347
04348 if (internal_post || (fallback & fb_lvalue))
04349
04350
04351
04352 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
04353 else
04354 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
04355
04356 if (TREE_CODE (*expr_p) != SSA_NAME)
04357 DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
04358 }
04359 else
04360 {
04361 #ifdef ENABLE_CHECKING
04362 if (!(fallback & fb_mayfail))
04363 {
04364 fprintf (stderr, "gimplification failed:\n");
04365 print_generic_expr (stderr, *expr_p, 0);
04366 debug_tree (*expr_p);
04367 internal_error ("gimplification failed");
04368 }
04369 #endif
04370 gcc_assert (fallback & fb_mayfail);
04371
04372
04373
04374 ret = GS_ERROR;
04375 goto out;
04376 }
04377
04378
04379 gcc_assert ((*gimple_test_f) (*expr_p));
04380
04381 if (internal_post)
04382 {
04383 annotate_all_with_locus (&internal_post, input_location);
04384 append_to_statement_list (internal_post, pre_p);
04385 }
04386
04387 out:
04388 input_location = saved_location;
04389 return ret;
04390 }
04391
04392
04393
04394
04395 void
04396 gimplify_type_sizes (tree type, tree *list_p)
04397 {
04398 tree field, t;
04399
04400 if (type == NULL || type == error_mark_node)
04401 return;
04402
04403
04404 type = TYPE_MAIN_VARIANT (type);
04405
04406
04407 if (TYPE_SIZES_GIMPLIFIED (type))
04408 return;
04409
04410 TYPE_SIZES_GIMPLIFIED (type) = 1;
04411
04412 switch (TREE_CODE (type))
04413 {
04414 case INTEGER_TYPE:
04415 case ENUMERAL_TYPE:
04416 case BOOLEAN_TYPE:
04417 case CHAR_TYPE:
04418 case REAL_TYPE:
04419 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
04420 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
04421
04422 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
04423 {
04424 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
04425 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
04426 }
04427 break;
04428
04429 case ARRAY_TYPE:
04430
04431 gimplify_type_sizes (TREE_TYPE (type), list_p);
04432 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
04433 break;
04434
04435 case RECORD_TYPE:
04436 case UNION_TYPE:
04437 case QUAL_UNION_TYPE:
04438 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
04439 if (TREE_CODE (field) == FIELD_DECL)
04440 {
04441 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
04442 gimplify_type_sizes (TREE_TYPE (field), list_p);
04443 }
04444 break;
04445
04446 case POINTER_TYPE:
04447 case REFERENCE_TYPE:
04448 gimplify_type_sizes (TREE_TYPE (type), list_p);
04449 break;
04450
04451 default:
04452 break;
04453 }
04454
04455 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
04456 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
04457
04458 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
04459 {
04460 TYPE_SIZE (t) = TYPE_SIZE (type);
04461 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
04462 TYPE_SIZES_GIMPLIFIED (t) = 1;
04463 }
04464 }
04465
04466
04467
04468
04469
04470 void
04471 gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
04472 {
04473 tree type, expr = *expr_p;
04474
04475
04476
04477
04478
04479
04480 if (expr == NULL_TREE || TREE_CONSTANT (expr)
04481 || TREE_CODE (expr) == VAR_DECL
04482 || CONTAINS_PLACEHOLDER_P (expr))
04483 return;
04484
04485 type = TREE_TYPE (expr);
04486 *expr_p = unshare_expr (expr);
04487
04488 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
04489 expr = *expr_p;
04490
04491
04492
04493
04494
04495
04496
04497 if (TREE_TYPE (expr) != type
04498 && TREE_CODE (type) == INTEGER_TYPE
04499 && TYPE_IS_SIZETYPE (type))
04500 {
04501 tree tmp;
04502
04503 *expr_p = create_tmp_var (type, NULL);
04504 tmp = build1 (NOP_EXPR, type, expr);
04505 tmp = build2 (MODIFY_EXPR, type, *expr_p, expr);
04506 if (EXPR_HAS_LOCATION (expr))
04507 SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
04508 else
04509 SET_EXPR_LOCATION (tmp, input_location);
04510
04511 gimplify_and_add (tmp, stmt_p);
04512 }
04513 }
04514
04515 #ifdef ENABLE_CHECKING
04516
04517
04518 static bool
04519 cpt_same_type (tree a, tree b)
04520 {
04521 if (lang_hooks.types_compatible_p (a, b))
04522 return true;
04523
04524
04525
04526
04527
04528 if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE)
04529 && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE))
04530 return true;
04531
04532
04533
04534
04535
04536
04537 if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE)
04538 return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
04539
04540
04541 if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b))
04542 return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
04543
04544 return false;
04545 }
04546
04547
04548
04549
04550
04551 static tree
04552 check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
04553 void *data ATTRIBUTE_UNUSED)
04554 {
04555 tree t = *tp;
04556 tree ptype, otype, dtype;
04557
04558 switch (TREE_CODE (t))
04559 {
04560 case INDIRECT_REF:
04561 case ARRAY_REF:
04562 otype = TREE_TYPE (t);
04563 ptype = TREE_TYPE (TREE_OPERAND (t, 0));
04564 dtype = TREE_TYPE (ptype);
04565 gcc_assert (cpt_same_type (otype, dtype));
04566 break;
04567
04568 case ADDR_EXPR:
04569 ptype = TREE_TYPE (t);
04570 otype = TREE_TYPE (TREE_OPERAND (t, 0));
04571 dtype = TREE_TYPE (ptype);
04572 if (!cpt_same_type (otype, dtype))
04573 {
04574
04575
04576
04577
04578 gcc_assert (TREE_CODE (otype) == ARRAY_TYPE
04579 && POINTER_TYPE_P (ptype)
04580 && cpt_same_type (TREE_TYPE (otype), dtype));
04581 break;
04582 }
04583 break;
04584
04585 default:
04586 return NULL_TREE;
04587 }
04588
04589
04590 return NULL_TREE;
04591 }
04592 #endif
04593
04594
04595
04596
04597 void
04598 gimplify_body (tree *body_p, tree fndecl, bool do_parms)
04599 {
04600 location_t saved_location = input_location;
04601 tree body, parm_stmts;
04602
04603 timevar_push (TV_TREE_GIMPLIFY);
04604 push_gimplify_context ();
04605
04606
04607
04608
04609
04610 unshare_body (body_p, fndecl);
04611 unvisit_body (body_p, fndecl);
04612
04613
04614 input_location = DECL_SOURCE_LOCATION (fndecl);
04615
04616
04617
04618 parm_stmts = do_parms ? gimplify_parameters () : NULL;
04619
04620
04621 gimplify_stmt (body_p);
04622 body = *body_p;
04623
04624 if (!body)
04625 body = alloc_stmt_list ();
04626 else if (TREE_CODE (body) == STATEMENT_LIST)
04627 {
04628 tree t = expr_only (*body_p);
04629 if (t)
04630 body = t;
04631 }
04632
04633
04634 if (TREE_CODE (body) != BIND_EXPR)
04635 {
04636 tree b = build (BIND_EXPR, void_type_node, NULL_TREE,
04637 NULL_TREE, NULL_TREE);
04638 TREE_SIDE_EFFECTS (b) = 1;
04639 append_to_statement_list_force (body, &BIND_EXPR_BODY (b));
04640 body = b;
04641 }
04642
04643
04644
04645 if (parm_stmts)
04646 {
04647 append_to_statement_list_force (BIND_EXPR_BODY (body), &parm_stmts);
04648 BIND_EXPR_BODY (body) = parm_stmts;
04649 }
04650
04651
04652 unshare_all_trees (body);
04653
04654 *body_p = body;
04655
04656 pop_gimplify_context (body);
04657
04658 #ifdef ENABLE_CHECKING
04659 walk_tree (body_p, check_pointer_types_r, NULL, NULL);
04660 #endif
04661
04662 timevar_pop (TV_TREE_GIMPLIFY);
04663 input_location = saved_location;
04664 }
04665
04666
04667
04668
04669 void
04670 gimplify_function_tree (tree fndecl)
04671 {
04672 tree oldfn;
04673
04674 oldfn = current_function_decl;
04675 current_function_decl = fndecl;
04676 cfun = DECL_STRUCT_FUNCTION (fndecl);
04677 if (cfun == NULL)
04678 allocate_struct_function (fndecl);
04679
04680 gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
04681
04682
04683
04684
04685
04686 if (flag_instrument_function_entry_exit
04687 && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
04688 {
04689 tree tf, x, bind;
04690
04691 tf = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
04692 TREE_SIDE_EFFECTS (tf) = 1;
04693 x = DECL_SAVED_TREE (fndecl);
04694 append_to_statement_list (x, &TREE_OPERAND (tf, 0));
04695 x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
04696 x = build_function_call_expr (x, NULL);
04697 append_to_statement_list (x, &TREE_OPERAND (tf, 1));
04698
04699 bind = build (BIND_EXPR, void_type_node, NULL, NULL, NULL);
04700 TREE_SIDE_EFFECTS (bind) = 1;
04701 x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
04702 x = build_function_call_expr (x, NULL);
04703 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
04704 append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
04705
04706 DECL_SAVED_TREE (fndecl) = bind;
04707 }
04708
04709 current_function_decl = oldfn;
04710 cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
04711 }
04712
04713
04714
04715
04716
04717
04718
04719 tree
04720 force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
04721 {
04722 tree t;
04723 enum gimplify_status ret;
04724 gimple_predicate gimple_test_f;
04725
04726 *stmts = NULL_TREE;
04727
04728 if (is_gimple_val (expr))
04729 return expr;
04730
04731 gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
04732
04733 push_gimplify_context ();
04734 gimplify_ctxp->into_ssa = true;
04735
04736 if (var)
04737 expr = build (MODIFY_EXPR, TREE_TYPE (var), var, expr);
04738
04739 ret = gimplify_expr (&expr, stmts, NULL,
04740 gimple_test_f, fb_rvalue);
04741 gcc_assert (ret != GS_ERROR);
04742
04743 for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
04744 add_referenced_tmp_var (t);
04745
04746 pop_gimplify_context (NULL);
04747
04748 return expr;
04749 }
04750
04751 #include "gt-gimplify.h"