1169689Skan/* Tree lowering pass. This pass converts the GENERIC functions-as-trees 2169689Skan tree representation into the GIMPLE form. 3169689Skan Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 4169689Skan Major work done by Sebastian Pop <s.pop@laposte.net>, 5169689Skan Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>. 6169689Skan 7169689SkanThis file is part of GCC. 8169689Skan 9169689SkanGCC is free software; you can redistribute it and/or modify it under 10169689Skanthe terms of the GNU General Public License as published by the Free 11169689SkanSoftware Foundation; either version 2, or (at your option) any later 12169689Skanversion. 13169689Skan 14169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 15169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 16169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17169689Skanfor more details. 18169689Skan 19169689SkanYou should have received a copy of the GNU General Public License 20169689Skanalong with GCC; see the file COPYING. If not, write to the Free 21169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 22169689Skan02110-1301, USA. */ 23169689Skan 24169689Skan#include "config.h" 25169689Skan#include "system.h" 26169689Skan#include "coretypes.h" 27169689Skan#include "tm.h" 28169689Skan#include "tree.h" 29169689Skan#include "rtl.h" 30169689Skan#include "varray.h" 31169689Skan#include "tree-gimple.h" 32169689Skan#include "tree-inline.h" 33169689Skan#include "diagnostic.h" 34169689Skan#include "langhooks.h" 35169689Skan#include "langhooks-def.h" 36169689Skan#include "tree-flow.h" 37169689Skan#include "cgraph.h" 38169689Skan#include "timevar.h" 39169689Skan#include "except.h" 40169689Skan#include "hashtab.h" 41169689Skan#include "flags.h" 42169689Skan#include "real.h" 43169689Skan#include "function.h" 44169689Skan#include "output.h" 45169689Skan#include "expr.h" 46169689Skan#include "ggc.h" 47169689Skan#include "toplev.h" 48169689Skan#include "target.h" 49169689Skan#include "optabs.h" 50169689Skan#include "pointer-set.h" 51169689Skan 52169689Skan 53169689Skanenum gimplify_omp_var_data 54169689Skan{ 55169689Skan GOVD_SEEN = 1, 56169689Skan GOVD_EXPLICIT = 2, 57169689Skan GOVD_SHARED = 4, 58169689Skan GOVD_PRIVATE = 8, 59169689Skan GOVD_FIRSTPRIVATE = 16, 60169689Skan GOVD_LASTPRIVATE = 32, 61169689Skan GOVD_REDUCTION = 64, 62169689Skan GOVD_LOCAL = 128, 63169689Skan GOVD_DEBUG_PRIVATE = 256, 64169689Skan GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE 65169689Skan | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL) 66169689Skan}; 67169689Skan 68169689Skanstruct gimplify_omp_ctx 69169689Skan{ 70169689Skan struct gimplify_omp_ctx *outer_context; 71169689Skan splay_tree variables; 72169689Skan struct pointer_set_t *privatized_types; 73169689Skan location_t location; 74169689Skan enum omp_clause_default_kind default_kind; 75169689Skan bool is_parallel; 76169689Skan bool is_combined_parallel; 77169689Skan}; 78169689Skan 79169689Skanstruct gimplify_ctx 80169689Skan{ 81169689Skan struct gimplify_ctx *prev_context; 82169689Skan 83169689Skan tree current_bind_expr; 84169689Skan tree temps; 85169689Skan tree conditional_cleanups; 86169689Skan tree exit_label; 87169689Skan tree return_temp; 88169689Skan 89169689Skan VEC(tree,heap) *case_labels; 90169689Skan /* The formal temporary table. Should this be persistent? */ 91169689Skan htab_t temp_htab; 92169689Skan 93169689Skan int conditions; 94169689Skan bool save_stack; 95169689Skan bool into_ssa; 96169689Skan}; 97169689Skan 98169689Skanstatic struct gimplify_ctx *gimplify_ctxp; 99169689Skanstatic struct gimplify_omp_ctx *gimplify_omp_ctxp; 100169689Skan 101169689Skan 102169689Skan 103169689Skan/* Formal (expression) temporary table handling: Multiple occurrences of 104169689Skan the same scalar expression are evaluated into the same temporary. */ 105169689Skan 106169689Skantypedef struct gimple_temp_hash_elt 107169689Skan{ 108169689Skan tree val; /* Key */ 109169689Skan tree temp; /* Value */ 110169689Skan} elt_t; 111169689Skan 112169689Skan/* Forward declarations. */ 113169689Skanstatic enum gimplify_status gimplify_compound_expr (tree *, tree *, bool); 114169689Skan#ifdef ENABLE_CHECKING 115169689Skanstatic bool cpt_same_type (tree a, tree b); 116169689Skan#endif 117169689Skan 118169689Skan 119169689Skan/* Return a hash value for a formal temporary table entry. */ 120169689Skan 121169689Skanstatic hashval_t 122169689Skangimple_tree_hash (const void *p) 123169689Skan{ 124169689Skan tree t = ((const elt_t *) p)->val; 125169689Skan return iterative_hash_expr (t, 0); 126169689Skan} 127169689Skan 128169689Skan/* Compare two formal temporary table entries. */ 129169689Skan 130169689Skanstatic int 131169689Skangimple_tree_eq (const void *p1, const void *p2) 132169689Skan{ 133169689Skan tree t1 = ((const elt_t *) p1)->val; 134169689Skan tree t2 = ((const elt_t *) p2)->val; 135169689Skan enum tree_code code = TREE_CODE (t1); 136169689Skan 137169689Skan if (TREE_CODE (t2) != code 138169689Skan || TREE_TYPE (t1) != TREE_TYPE (t2)) 139169689Skan return 0; 140169689Skan 141169689Skan if (!operand_equal_p (t1, t2, 0)) 142169689Skan return 0; 143169689Skan 144169689Skan /* Only allow them to compare equal if they also hash equal; otherwise 145169689Skan results are nondeterminate, and we fail bootstrap comparison. */ 146169689Skan gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2)); 147169689Skan 148169689Skan return 1; 149169689Skan} 150169689Skan 151169689Skan/* Set up a context for the gimplifier. */ 152169689Skan 153169689Skanvoid 154169689Skanpush_gimplify_context (void) 155169689Skan{ 156169689Skan struct gimplify_ctx *c; 157169689Skan 158169689Skan c = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx)); 159169689Skan c->prev_context = gimplify_ctxp; 160169689Skan if (optimize) 161169689Skan c->temp_htab = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free); 162169689Skan 163169689Skan gimplify_ctxp = c; 164169689Skan} 165169689Skan 166169689Skan/* Tear down a context for the gimplifier. If BODY is non-null, then 167169689Skan put the temporaries into the outer BIND_EXPR. Otherwise, put them 168169689Skan in the unexpanded_var_list. */ 169169689Skan 170169689Skanvoid 171169689Skanpop_gimplify_context (tree body) 172169689Skan{ 173169689Skan struct gimplify_ctx *c = gimplify_ctxp; 174169689Skan tree t; 175169689Skan 176169689Skan gcc_assert (c && !c->current_bind_expr); 177169689Skan gimplify_ctxp = c->prev_context; 178169689Skan 179169689Skan for (t = c->temps; t ; t = TREE_CHAIN (t)) 180169689Skan DECL_GIMPLE_FORMAL_TEMP_P (t) = 0; 181169689Skan 182169689Skan if (body) 183169689Skan declare_vars (c->temps, body, false); 184169689Skan else 185169689Skan record_vars (c->temps); 186169689Skan 187169689Skan if (optimize) 188169689Skan htab_delete (c->temp_htab); 189169689Skan free (c); 190169689Skan} 191169689Skan 192169689Skanstatic void 193169689Skangimple_push_bind_expr (tree bind) 194169689Skan{ 195169689Skan TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr; 196169689Skan gimplify_ctxp->current_bind_expr = bind; 197169689Skan} 198169689Skan 199169689Skanstatic void 200169689Skangimple_pop_bind_expr (void) 201169689Skan{ 202169689Skan gimplify_ctxp->current_bind_expr 203169689Skan = TREE_CHAIN (gimplify_ctxp->current_bind_expr); 204169689Skan} 205169689Skan 206169689Skantree 207169689Skangimple_current_bind_expr (void) 208169689Skan{ 209169689Skan return gimplify_ctxp->current_bind_expr; 210169689Skan} 211169689Skan 212169689Skan/* Returns true iff there is a COND_EXPR between us and the innermost 213169689Skan CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */ 214169689Skan 215169689Skanstatic bool 216169689Skangimple_conditional_context (void) 217169689Skan{ 218169689Skan return gimplify_ctxp->conditions > 0; 219169689Skan} 220169689Skan 221169689Skan/* Note that we've entered a COND_EXPR. */ 222169689Skan 223169689Skanstatic void 224169689Skangimple_push_condition (void) 225169689Skan{ 226169689Skan#ifdef ENABLE_CHECKING 227169689Skan if (gimplify_ctxp->conditions == 0) 228169689Skan gcc_assert (!gimplify_ctxp->conditional_cleanups); 229169689Skan#endif 230169689Skan ++(gimplify_ctxp->conditions); 231169689Skan} 232169689Skan 233169689Skan/* Note that we've left a COND_EXPR. If we're back at unconditional scope 234169689Skan now, add any conditional cleanups we've seen to the prequeue. */ 235169689Skan 236169689Skanstatic void 237169689Skangimple_pop_condition (tree *pre_p) 238169689Skan{ 239169689Skan int conds = --(gimplify_ctxp->conditions); 240169689Skan 241169689Skan gcc_assert (conds >= 0); 242169689Skan if (conds == 0) 243169689Skan { 244169689Skan append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p); 245169689Skan gimplify_ctxp->conditional_cleanups = NULL_TREE; 246169689Skan } 247169689Skan} 248169689Skan 249169689Skan/* A stable comparison routine for use with splay trees and DECLs. */ 250169689Skan 251169689Skanstatic int 252169689Skansplay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) 253169689Skan{ 254169689Skan tree a = (tree) xa; 255169689Skan tree b = (tree) xb; 256169689Skan 257169689Skan return DECL_UID (a) - DECL_UID (b); 258169689Skan} 259169689Skan 260169689Skan/* Create a new omp construct that deals with variable remapping. */ 261169689Skan 262169689Skanstatic struct gimplify_omp_ctx * 263169689Skannew_omp_context (bool is_parallel, bool is_combined_parallel) 264169689Skan{ 265169689Skan struct gimplify_omp_ctx *c; 266169689Skan 267169689Skan c = XCNEW (struct gimplify_omp_ctx); 268169689Skan c->outer_context = gimplify_omp_ctxp; 269169689Skan c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 270169689Skan c->privatized_types = pointer_set_create (); 271169689Skan c->location = input_location; 272169689Skan c->is_parallel = is_parallel; 273169689Skan c->is_combined_parallel = is_combined_parallel; 274169689Skan c->default_kind = OMP_CLAUSE_DEFAULT_SHARED; 275169689Skan 276169689Skan return c; 277169689Skan} 278169689Skan 279169689Skan/* Destroy an omp construct that deals with variable remapping. */ 280169689Skan 281169689Skanstatic void 282169689Skandelete_omp_context (struct gimplify_omp_ctx *c) 283169689Skan{ 284169689Skan splay_tree_delete (c->variables); 285169689Skan pointer_set_destroy (c->privatized_types); 286169689Skan XDELETE (c); 287169689Skan} 288169689Skan 289169689Skanstatic void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int); 290169689Skanstatic bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool); 291169689Skan 292169689Skan/* A subroutine of append_to_statement_list{,_force}. T is not NULL. */ 293169689Skan 294169689Skanstatic void 295169689Skanappend_to_statement_list_1 (tree t, tree *list_p) 296169689Skan{ 297169689Skan tree list = *list_p; 298169689Skan tree_stmt_iterator i; 299169689Skan 300169689Skan if (!list) 301169689Skan { 302169689Skan if (t && TREE_CODE (t) == STATEMENT_LIST) 303169689Skan { 304169689Skan *list_p = t; 305169689Skan return; 306169689Skan } 307169689Skan *list_p = list = alloc_stmt_list (); 308169689Skan } 309169689Skan 310169689Skan i = tsi_last (list); 311169689Skan tsi_link_after (&i, t, TSI_CONTINUE_LINKING); 312169689Skan} 313169689Skan 314169689Skan/* Add T to the end of the list container pointed to by LIST_P. 315169689Skan If T is an expression with no effects, it is ignored. */ 316169689Skan 317169689Skanvoid 318169689Skanappend_to_statement_list (tree t, tree *list_p) 319169689Skan{ 320169689Skan if (t && TREE_SIDE_EFFECTS (t)) 321169689Skan append_to_statement_list_1 (t, list_p); 322169689Skan} 323169689Skan 324169689Skan/* Similar, but the statement is always added, regardless of side effects. */ 325169689Skan 326169689Skanvoid 327169689Skanappend_to_statement_list_force (tree t, tree *list_p) 328169689Skan{ 329169689Skan if (t != NULL_TREE) 330169689Skan append_to_statement_list_1 (t, list_p); 331169689Skan} 332169689Skan 333169689Skan/* Both gimplify the statement T and append it to LIST_P. */ 334169689Skan 335169689Skanvoid 336169689Skangimplify_and_add (tree t, tree *list_p) 337169689Skan{ 338169689Skan gimplify_stmt (&t); 339169689Skan append_to_statement_list (t, list_p); 340169689Skan} 341169689Skan 342169689Skan/* Strip off a legitimate source ending from the input string NAME of 343169689Skan length LEN. Rather than having to know the names used by all of 344169689Skan our front ends, we strip off an ending of a period followed by 345169689Skan up to five characters. (Java uses ".class".) */ 346169689Skan 347169689Skanstatic inline void 348169689Skanremove_suffix (char *name, int len) 349169689Skan{ 350169689Skan int i; 351169689Skan 352169689Skan for (i = 2; i < 8 && len > i; i++) 353169689Skan { 354169689Skan if (name[len - i] == '.') 355169689Skan { 356169689Skan name[len - i] = '\0'; 357169689Skan break; 358169689Skan } 359169689Skan } 360169689Skan} 361169689Skan 362169689Skan/* Create a nameless artificial label and put it in the current function 363169689Skan context. Returns the newly created label. */ 364169689Skan 365169689Skantree 366169689Skancreate_artificial_label (void) 367169689Skan{ 368169689Skan tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node); 369169689Skan 370169689Skan DECL_ARTIFICIAL (lab) = 1; 371169689Skan DECL_IGNORED_P (lab) = 1; 372169689Skan DECL_CONTEXT (lab) = current_function_decl; 373169689Skan return lab; 374169689Skan} 375169689Skan 376169689Skan/* Subroutine for find_single_pointer_decl. */ 377169689Skan 378169689Skanstatic tree 379169689Skanfind_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 380169689Skan void *data) 381169689Skan{ 382169689Skan tree *pdecl = (tree *) data; 383169689Skan 384169689Skan if (DECL_P (*tp) && POINTER_TYPE_P (TREE_TYPE (*tp))) 385169689Skan { 386169689Skan if (*pdecl) 387169689Skan { 388169689Skan /* We already found a pointer decl; return anything other 389169689Skan than NULL_TREE to unwind from walk_tree signalling that 390169689Skan we have a duplicate. */ 391169689Skan return *tp; 392169689Skan } 393169689Skan *pdecl = *tp; 394169689Skan } 395169689Skan 396169689Skan return NULL_TREE; 397169689Skan} 398169689Skan 399169689Skan/* Find the single DECL of pointer type in the tree T and return it. 400169689Skan If there are zero or more than one such DECLs, return NULL. */ 401169689Skan 402169689Skanstatic tree 403169689Skanfind_single_pointer_decl (tree t) 404169689Skan{ 405169689Skan tree decl = NULL_TREE; 406169689Skan 407169689Skan if (walk_tree (&t, find_single_pointer_decl_1, &decl, NULL)) 408169689Skan { 409169689Skan /* find_single_pointer_decl_1 returns a nonzero value, causing 410169689Skan walk_tree to return a nonzero value, to indicate that it 411169689Skan found more than one pointer DECL. */ 412169689Skan return NULL_TREE; 413169689Skan } 414169689Skan 415169689Skan return decl; 416169689Skan} 417169689Skan 418169689Skan/* Create a new temporary name with PREFIX. Returns an identifier. */ 419169689Skan 420169689Skanstatic GTY(()) unsigned int tmp_var_id_num; 421169689Skan 422169689Skantree 423169689Skancreate_tmp_var_name (const char *prefix) 424169689Skan{ 425169689Skan char *tmp_name; 426169689Skan 427169689Skan if (prefix) 428169689Skan { 429169689Skan char *preftmp = ASTRDUP (prefix); 430169689Skan 431169689Skan remove_suffix (preftmp, strlen (preftmp)); 432169689Skan prefix = preftmp; 433169689Skan } 434169689Skan 435169689Skan ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++); 436169689Skan return get_identifier (tmp_name); 437169689Skan} 438169689Skan 439169689Skan 440169689Skan/* Create a new temporary variable declaration of type TYPE. 441169689Skan Does NOT push it into the current binding. */ 442169689Skan 443169689Skantree 444169689Skancreate_tmp_var_raw (tree type, const char *prefix) 445169689Skan{ 446169689Skan tree tmp_var; 447169689Skan tree new_type; 448169689Skan 449169689Skan /* Make the type of the variable writable. */ 450169689Skan new_type = build_type_variant (type, 0, 0); 451169689Skan TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type); 452169689Skan 453169689Skan tmp_var = build_decl (VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL, 454169689Skan type); 455169689Skan 456169689Skan /* The variable was declared by the compiler. */ 457169689Skan DECL_ARTIFICIAL (tmp_var) = 1; 458169689Skan /* And we don't want debug info for it. */ 459169689Skan DECL_IGNORED_P (tmp_var) = 1; 460169689Skan 461169689Skan /* Make the variable writable. */ 462169689Skan TREE_READONLY (tmp_var) = 0; 463169689Skan 464169689Skan DECL_EXTERNAL (tmp_var) = 0; 465169689Skan TREE_STATIC (tmp_var) = 0; 466169689Skan TREE_USED (tmp_var) = 1; 467169689Skan 468169689Skan return tmp_var; 469169689Skan} 470169689Skan 471169689Skan/* Create a new temporary variable declaration of type TYPE. DOES push the 472169689Skan variable into the current binding. Further, assume that this is called 473169689Skan only from gimplification or optimization, at which point the creation of 474169689Skan certain types are bugs. */ 475169689Skan 476169689Skantree 477169689Skancreate_tmp_var (tree type, const char *prefix) 478169689Skan{ 479169689Skan tree tmp_var; 480169689Skan 481169689Skan /* We don't allow types that are addressable (meaning we can't make copies), 482169689Skan or incomplete. We also used to reject every variable size objects here, 483169689Skan but now support those for which a constant upper bound can be obtained. 484169689Skan The processing for variable sizes is performed in gimple_add_tmp_var, 485169689Skan point at which it really matters and possibly reached via paths not going 486169689Skan through this function, e.g. after direct calls to create_tmp_var_raw. */ 487169689Skan gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type)); 488169689Skan 489169689Skan tmp_var = create_tmp_var_raw (type, prefix); 490169689Skan gimple_add_tmp_var (tmp_var); 491169689Skan return tmp_var; 492169689Skan} 493169689Skan 494169689Skan/* Given a tree, try to return a useful variable name that we can use 495169689Skan to prefix a temporary that is being assigned the value of the tree. 496169689Skan I.E. given <temp> = &A, return A. */ 497169689Skan 498169689Skanconst char * 499169689Skanget_name (tree t) 500169689Skan{ 501169689Skan tree stripped_decl; 502169689Skan 503169689Skan stripped_decl = t; 504169689Skan STRIP_NOPS (stripped_decl); 505169689Skan if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl)) 506169689Skan return IDENTIFIER_POINTER (DECL_NAME (stripped_decl)); 507169689Skan else 508169689Skan { 509169689Skan switch (TREE_CODE (stripped_decl)) 510169689Skan { 511169689Skan case ADDR_EXPR: 512169689Skan return get_name (TREE_OPERAND (stripped_decl, 0)); 513169689Skan break; 514169689Skan default: 515169689Skan return NULL; 516169689Skan } 517169689Skan } 518169689Skan} 519169689Skan 520169689Skan/* Create a temporary with a name derived from VAL. Subroutine of 521169689Skan lookup_tmp_var; nobody else should call this function. */ 522169689Skan 523169689Skanstatic inline tree 524169689Skancreate_tmp_from_val (tree val) 525169689Skan{ 526169689Skan return create_tmp_var (TYPE_MAIN_VARIANT (TREE_TYPE (val)), get_name (val)); 527169689Skan} 528169689Skan 529169689Skan/* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse 530169689Skan an existing expression temporary. */ 531169689Skan 532169689Skanstatic tree 533169689Skanlookup_tmp_var (tree val, bool is_formal) 534169689Skan{ 535169689Skan tree ret; 536169689Skan 537169689Skan /* If not optimizing, never really reuse a temporary. local-alloc 538169689Skan won't allocate any variable that is used in more than one basic 539169689Skan block, which means it will go into memory, causing much extra 540169689Skan work in reload and final and poorer code generation, outweighing 541169689Skan the extra memory allocation here. */ 542169689Skan if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val)) 543169689Skan ret = create_tmp_from_val (val); 544169689Skan else 545169689Skan { 546169689Skan elt_t elt, *elt_p; 547169689Skan void **slot; 548169689Skan 549169689Skan elt.val = val; 550169689Skan slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT); 551169689Skan if (*slot == NULL) 552169689Skan { 553169689Skan elt_p = XNEW (elt_t); 554169689Skan elt_p->val = val; 555169689Skan elt_p->temp = ret = create_tmp_from_val (val); 556169689Skan *slot = (void *) elt_p; 557169689Skan } 558169689Skan else 559169689Skan { 560169689Skan elt_p = (elt_t *) *slot; 561169689Skan ret = elt_p->temp; 562169689Skan } 563169689Skan } 564169689Skan 565169689Skan if (is_formal) 566169689Skan DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1; 567169689Skan 568169689Skan return ret; 569169689Skan} 570169689Skan 571169689Skan/* Returns a formal temporary variable initialized with VAL. PRE_P is as 572169689Skan in gimplify_expr. Only use this function if: 573169689Skan 574169689Skan 1) The value of the unfactored expression represented by VAL will not 575169689Skan change between the initialization and use of the temporary, and 576169689Skan 2) The temporary will not be otherwise modified. 577169689Skan 578169689Skan For instance, #1 means that this is inappropriate for SAVE_EXPR temps, 579169689Skan and #2 means it is inappropriate for && temps. 580169689Skan 581169689Skan For other cases, use get_initialized_tmp_var instead. */ 582169689Skan 583169689Skanstatic tree 584169689Skaninternal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal) 585169689Skan{ 586169689Skan tree t, mod; 587169689Skan 588169689Skan gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue); 589169689Skan 590169689Skan t = lookup_tmp_var (val, is_formal); 591169689Skan 592169689Skan if (is_formal) 593169689Skan { 594169689Skan tree u = find_single_pointer_decl (val); 595169689Skan 596169689Skan if (u && TREE_CODE (u) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (u)) 597169689Skan u = DECL_GET_RESTRICT_BASE (u); 598169689Skan if (u && TYPE_RESTRICT (TREE_TYPE (u))) 599169689Skan { 600169689Skan if (DECL_BASED_ON_RESTRICT_P (t)) 601169689Skan gcc_assert (u == DECL_GET_RESTRICT_BASE (t)); 602169689Skan else 603169689Skan { 604169689Skan DECL_BASED_ON_RESTRICT_P (t) = 1; 605169689Skan SET_DECL_RESTRICT_BASE (t, u); 606169689Skan } 607169689Skan } 608169689Skan } 609169689Skan 610169689Skan if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE) 611169689Skan DECL_COMPLEX_GIMPLE_REG_P (t) = 1; 612169689Skan 613169689Skan mod = build2 (INIT_EXPR, TREE_TYPE (t), t, val); 614169689Skan 615169689Skan if (EXPR_HAS_LOCATION (val)) 616169689Skan SET_EXPR_LOCUS (mod, EXPR_LOCUS (val)); 617169689Skan else 618169689Skan SET_EXPR_LOCATION (mod, input_location); 619169689Skan 620169689Skan /* gimplify_modify_expr might want to reduce this further. */ 621169689Skan gimplify_and_add (mod, pre_p); 622169689Skan 623169689Skan /* If we're gimplifying into ssa, gimplify_modify_expr will have 624169689Skan given our temporary an ssa name. Find and return it. */ 625169689Skan if (gimplify_ctxp->into_ssa) 626169689Skan t = TREE_OPERAND (mod, 0); 627169689Skan 628169689Skan return t; 629169689Skan} 630169689Skan 631169689Skan/* Returns a formal temporary variable initialized with VAL. PRE_P 632169689Skan points to a statement list where side-effects needed to compute VAL 633169689Skan should be stored. */ 634169689Skan 635169689Skantree 636169689Skanget_formal_tmp_var (tree val, tree *pre_p) 637169689Skan{ 638169689Skan return internal_get_tmp_var (val, pre_p, NULL, true); 639169689Skan} 640169689Skan 641169689Skan/* Returns a temporary variable initialized with VAL. PRE_P and POST_P 642169689Skan are as in gimplify_expr. */ 643169689Skan 644169689Skantree 645169689Skanget_initialized_tmp_var (tree val, tree *pre_p, tree *post_p) 646169689Skan{ 647169689Skan return internal_get_tmp_var (val, pre_p, post_p, false); 648169689Skan} 649169689Skan 650169689Skan/* Declares all the variables in VARS in SCOPE. If DEBUG_INFO is 651169689Skan true, generate debug info for them; otherwise don't. */ 652169689Skan 653169689Skanvoid 654169689Skandeclare_vars (tree vars, tree scope, bool debug_info) 655169689Skan{ 656169689Skan tree last = vars; 657169689Skan if (last) 658169689Skan { 659169689Skan tree temps, block; 660169689Skan 661169689Skan /* C99 mode puts the default 'return 0;' for main outside the outer 662169689Skan braces. So drill down until we find an actual scope. */ 663169689Skan while (TREE_CODE (scope) == COMPOUND_EXPR) 664169689Skan scope = TREE_OPERAND (scope, 0); 665169689Skan 666169689Skan gcc_assert (TREE_CODE (scope) == BIND_EXPR); 667169689Skan 668169689Skan temps = nreverse (last); 669169689Skan 670169689Skan block = BIND_EXPR_BLOCK (scope); 671169689Skan if (!block || !debug_info) 672169689Skan { 673169689Skan TREE_CHAIN (last) = BIND_EXPR_VARS (scope); 674169689Skan BIND_EXPR_VARS (scope) = temps; 675169689Skan } 676169689Skan else 677169689Skan { 678169689Skan /* We need to attach the nodes both to the BIND_EXPR and to its 679169689Skan associated BLOCK for debugging purposes. The key point here 680169689Skan is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR 681169689Skan is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */ 682169689Skan if (BLOCK_VARS (block)) 683169689Skan BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps); 684169689Skan else 685169689Skan { 686169689Skan BIND_EXPR_VARS (scope) = chainon (BIND_EXPR_VARS (scope), temps); 687169689Skan BLOCK_VARS (block) = temps; 688169689Skan } 689169689Skan } 690169689Skan } 691169689Skan} 692169689Skan 693169689Skan/* For VAR a VAR_DECL of variable size, try to find a constant upper bound 694169689Skan for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if 695169689Skan no such upper bound can be obtained. */ 696169689Skan 697169689Skanstatic void 698169689Skanforce_constant_size (tree var) 699169689Skan{ 700169689Skan /* The only attempt we make is by querying the maximum size of objects 701169689Skan of the variable's type. */ 702169689Skan 703169689Skan HOST_WIDE_INT max_size; 704169689Skan 705169689Skan gcc_assert (TREE_CODE (var) == VAR_DECL); 706169689Skan 707169689Skan max_size = max_int_size_in_bytes (TREE_TYPE (var)); 708169689Skan 709169689Skan gcc_assert (max_size >= 0); 710169689Skan 711169689Skan DECL_SIZE_UNIT (var) 712169689Skan = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size); 713169689Skan DECL_SIZE (var) 714169689Skan = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT); 715169689Skan} 716169689Skan 717169689Skanvoid 718169689Skangimple_add_tmp_var (tree tmp) 719169689Skan{ 720169689Skan gcc_assert (!TREE_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); 721169689Skan 722169689Skan /* Later processing assumes that the object size is constant, which might 723169689Skan not be true at this point. Force the use of a constant upper bound in 724169689Skan this case. */ 725169689Skan if (!host_integerp (DECL_SIZE_UNIT (tmp), 1)) 726169689Skan force_constant_size (tmp); 727169689Skan 728169689Skan DECL_CONTEXT (tmp) = current_function_decl; 729169689Skan DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; 730169689Skan 731169689Skan if (gimplify_ctxp) 732169689Skan { 733169689Skan TREE_CHAIN (tmp) = gimplify_ctxp->temps; 734169689Skan gimplify_ctxp->temps = tmp; 735169689Skan 736169689Skan /* Mark temporaries local within the nearest enclosing parallel. */ 737169689Skan if (gimplify_omp_ctxp) 738169689Skan { 739169689Skan struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 740169689Skan while (ctx && !ctx->is_parallel) 741169689Skan ctx = ctx->outer_context; 742169689Skan if (ctx) 743169689Skan omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN); 744169689Skan } 745169689Skan } 746169689Skan else if (cfun) 747169689Skan record_vars (tmp); 748169689Skan else 749169689Skan declare_vars (tmp, DECL_SAVED_TREE (current_function_decl), false); 750169689Skan} 751169689Skan 752169689Skan/* Determines whether to assign a locus to the statement STMT. */ 753169689Skan 754169689Skanstatic bool 755169689Skanshould_carry_locus_p (tree stmt) 756169689Skan{ 757169689Skan /* Don't emit a line note for a label. We particularly don't want to 758169689Skan emit one for the break label, since it doesn't actually correspond 759169689Skan to the beginning of the loop/switch. */ 760169689Skan if (TREE_CODE (stmt) == LABEL_EXPR) 761169689Skan return false; 762169689Skan 763169689Skan /* Do not annotate empty statements, since it confuses gcov. */ 764169689Skan if (!TREE_SIDE_EFFECTS (stmt)) 765169689Skan return false; 766169689Skan 767169689Skan return true; 768169689Skan} 769169689Skan 770169689Skanstatic void 771169689Skanannotate_one_with_locus (tree t, location_t locus) 772169689Skan{ 773169689Skan if (EXPR_P (t) && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t)) 774169689Skan SET_EXPR_LOCATION (t, locus); 775169689Skan} 776169689Skan 777169689Skanvoid 778169689Skanannotate_all_with_locus (tree *stmt_p, location_t locus) 779169689Skan{ 780169689Skan tree_stmt_iterator i; 781169689Skan 782169689Skan if (!*stmt_p) 783169689Skan return; 784169689Skan 785169689Skan for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i)) 786169689Skan { 787169689Skan tree t = tsi_stmt (i); 788169689Skan 789169689Skan /* Assuming we've already been gimplified, we shouldn't 790169689Skan see nested chaining constructs anymore. */ 791169689Skan gcc_assert (TREE_CODE (t) != STATEMENT_LIST 792169689Skan && TREE_CODE (t) != COMPOUND_EXPR); 793169689Skan 794169689Skan annotate_one_with_locus (t, locus); 795169689Skan } 796169689Skan} 797169689Skan 798169689Skan/* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes. 799169689Skan These nodes model computations that should only be done once. If we 800169689Skan were to unshare something like SAVE_EXPR(i++), the gimplification 801169689Skan process would create wrong code. */ 802169689Skan 803169689Skanstatic tree 804169689Skanmostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) 805169689Skan{ 806169689Skan enum tree_code code = TREE_CODE (*tp); 807169689Skan /* Don't unshare types, decls, constants and SAVE_EXPR nodes. */ 808169689Skan if (TREE_CODE_CLASS (code) == tcc_type 809169689Skan || TREE_CODE_CLASS (code) == tcc_declaration 810169689Skan || TREE_CODE_CLASS (code) == tcc_constant 811169689Skan || code == SAVE_EXPR || code == TARGET_EXPR 812169689Skan /* We can't do anything sensible with a BLOCK used as an expression, 813169689Skan but we also can't just die when we see it because of non-expression 814169689Skan uses. So just avert our eyes and cross our fingers. Silly Java. */ 815169689Skan || code == BLOCK) 816169689Skan *walk_subtrees = 0; 817169689Skan else 818169689Skan { 819169689Skan gcc_assert (code != BIND_EXPR); 820169689Skan copy_tree_r (tp, walk_subtrees, data); 821169689Skan } 822169689Skan 823169689Skan return NULL_TREE; 824169689Skan} 825169689Skan 826169689Skan/* Callback for walk_tree to unshare most of the shared trees rooted at 827169689Skan *TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1), 828169689Skan then *TP is deep copied by calling copy_tree_r. 829169689Skan 830169689Skan This unshares the same trees as copy_tree_r with the exception of 831169689Skan SAVE_EXPR nodes. These nodes model computations that should only be 832169689Skan done once. If we were to unshare something like SAVE_EXPR(i++), the 833169689Skan gimplification process would create wrong code. */ 834169689Skan 835169689Skanstatic tree 836169689Skancopy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 837169689Skan void *data ATTRIBUTE_UNUSED) 838169689Skan{ 839169689Skan tree t = *tp; 840169689Skan enum tree_code code = TREE_CODE (t); 841169689Skan 842169689Skan /* Skip types, decls, and constants. But we do want to look at their 843169689Skan types and the bounds of types. Mark them as visited so we properly 844169689Skan unmark their subtrees on the unmark pass. If we've already seen them, 845169689Skan don't look down further. */ 846169689Skan if (TREE_CODE_CLASS (code) == tcc_type 847169689Skan || TREE_CODE_CLASS (code) == tcc_declaration 848169689Skan || TREE_CODE_CLASS (code) == tcc_constant) 849169689Skan { 850169689Skan if (TREE_VISITED (t)) 851169689Skan *walk_subtrees = 0; 852169689Skan else 853169689Skan TREE_VISITED (t) = 1; 854169689Skan } 855169689Skan 856169689Skan /* If this node has been visited already, unshare it and don't look 857169689Skan any deeper. */ 858169689Skan else if (TREE_VISITED (t)) 859169689Skan { 860169689Skan walk_tree (tp, mostly_copy_tree_r, NULL, NULL); 861169689Skan *walk_subtrees = 0; 862169689Skan } 863169689Skan 864169689Skan /* Otherwise, mark the tree as visited and keep looking. */ 865169689Skan else 866169689Skan TREE_VISITED (t) = 1; 867169689Skan 868169689Skan return NULL_TREE; 869169689Skan} 870169689Skan 871169689Skanstatic tree 872169689Skanunmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 873169689Skan void *data ATTRIBUTE_UNUSED) 874169689Skan{ 875169689Skan if (TREE_VISITED (*tp)) 876169689Skan TREE_VISITED (*tp) = 0; 877169689Skan else 878169689Skan *walk_subtrees = 0; 879169689Skan 880169689Skan return NULL_TREE; 881169689Skan} 882169689Skan 883169689Skan/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the 884169689Skan bodies of any nested functions if we are unsharing the entire body of 885169689Skan FNDECL. */ 886169689Skan 887169689Skanstatic void 888169689Skanunshare_body (tree *body_p, tree fndecl) 889169689Skan{ 890169689Skan struct cgraph_node *cgn = cgraph_node (fndecl); 891169689Skan 892169689Skan walk_tree (body_p, copy_if_shared_r, NULL, NULL); 893169689Skan if (body_p == &DECL_SAVED_TREE (fndecl)) 894169689Skan for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) 895169689Skan unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl); 896169689Skan} 897169689Skan 898169689Skan/* Likewise, but mark all trees as not visited. */ 899169689Skan 900169689Skanstatic void 901169689Skanunvisit_body (tree *body_p, tree fndecl) 902169689Skan{ 903169689Skan struct cgraph_node *cgn = cgraph_node (fndecl); 904169689Skan 905169689Skan walk_tree (body_p, unmark_visited_r, NULL, NULL); 906169689Skan if (body_p == &DECL_SAVED_TREE (fndecl)) 907169689Skan for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) 908169689Skan unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl); 909169689Skan} 910169689Skan 911169689Skan/* Unshare T and all the trees reached from T via TREE_CHAIN. */ 912169689Skan 913169689Skanstatic void 914169689Skanunshare_all_trees (tree t) 915169689Skan{ 916169689Skan walk_tree (&t, copy_if_shared_r, NULL, NULL); 917169689Skan walk_tree (&t, unmark_visited_r, NULL, NULL); 918169689Skan} 919169689Skan 920169689Skan/* Unconditionally make an unshared copy of EXPR. This is used when using 921169689Skan stored expressions which span multiple functions, such as BINFO_VTABLE, 922169689Skan as the normal unsharing process can't tell that they're shared. */ 923169689Skan 924169689Skantree 925169689Skanunshare_expr (tree expr) 926169689Skan{ 927169689Skan walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); 928169689Skan return expr; 929169689Skan} 930169689Skan 931169689Skan/* A terser interface for building a representation of an exception 932169689Skan specification. */ 933169689Skan 934169689Skantree 935169689Skangimple_build_eh_filter (tree body, tree allowed, tree failure) 936169689Skan{ 937169689Skan tree t; 938169689Skan 939169689Skan /* FIXME should the allowed types go in TREE_TYPE? */ 940169689Skan t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE); 941169689Skan append_to_statement_list (failure, &EH_FILTER_FAILURE (t)); 942169689Skan 943169689Skan t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t); 944169689Skan append_to_statement_list (body, &TREE_OPERAND (t, 0)); 945169689Skan 946169689Skan return t; 947169689Skan} 948169689Skan 949169689Skan 950169689Skan/* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both 951169689Skan contain statements and have a value. Assign its value to a temporary 952169689Skan and give it void_type_node. Returns the temporary, or NULL_TREE if 953169689Skan WRAPPER was already void. */ 954169689Skan 955169689Skantree 956169689Skanvoidify_wrapper_expr (tree wrapper, tree temp) 957169689Skan{ 958169689Skan tree type = TREE_TYPE (wrapper); 959169689Skan if (type && !VOID_TYPE_P (type)) 960169689Skan { 961169689Skan tree *p; 962169689Skan 963169689Skan /* Set p to point to the body of the wrapper. Loop until we find 964169689Skan something that isn't a wrapper. */ 965169689Skan for (p = &wrapper; p && *p; ) 966169689Skan { 967169689Skan switch (TREE_CODE (*p)) 968169689Skan { 969169689Skan case BIND_EXPR: 970169689Skan TREE_SIDE_EFFECTS (*p) = 1; 971169689Skan TREE_TYPE (*p) = void_type_node; 972169689Skan /* For a BIND_EXPR, the body is operand 1. */ 973169689Skan p = &BIND_EXPR_BODY (*p); 974169689Skan break; 975169689Skan 976169689Skan case CLEANUP_POINT_EXPR: 977169689Skan case TRY_FINALLY_EXPR: 978169689Skan case TRY_CATCH_EXPR: 979169689Skan TREE_SIDE_EFFECTS (*p) = 1; 980169689Skan TREE_TYPE (*p) = void_type_node; 981169689Skan p = &TREE_OPERAND (*p, 0); 982169689Skan break; 983169689Skan 984169689Skan case STATEMENT_LIST: 985169689Skan { 986169689Skan tree_stmt_iterator i = tsi_last (*p); 987169689Skan TREE_SIDE_EFFECTS (*p) = 1; 988169689Skan TREE_TYPE (*p) = void_type_node; 989169689Skan p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i); 990169689Skan } 991169689Skan break; 992169689Skan 993169689Skan case COMPOUND_EXPR: 994169689Skan /* Advance to the last statement. Set all container types to void. */ 995169689Skan for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)) 996169689Skan { 997169689Skan TREE_SIDE_EFFECTS (*p) = 1; 998169689Skan TREE_TYPE (*p) = void_type_node; 999169689Skan } 1000169689Skan break; 1001169689Skan 1002169689Skan default: 1003169689Skan goto out; 1004169689Skan } 1005169689Skan } 1006169689Skan 1007169689Skan out: 1008169689Skan if (p == NULL || IS_EMPTY_STMT (*p)) 1009169689Skan temp = NULL_TREE; 1010169689Skan else if (temp) 1011169689Skan { 1012169689Skan /* The wrapper is on the RHS of an assignment that we're pushing 1013169689Skan down. */ 1014169689Skan gcc_assert (TREE_CODE (temp) == INIT_EXPR 1015169689Skan || TREE_CODE (temp) == MODIFY_EXPR); 1016169689Skan TREE_OPERAND (temp, 1) = *p; 1017169689Skan *p = temp; 1018169689Skan } 1019169689Skan else 1020169689Skan { 1021169689Skan temp = create_tmp_var (type, "retval"); 1022169689Skan *p = build2 (INIT_EXPR, type, temp, *p); 1023169689Skan } 1024169689Skan 1025169689Skan return temp; 1026169689Skan } 1027169689Skan 1028169689Skan return NULL_TREE; 1029169689Skan} 1030169689Skan 1031169689Skan/* Prepare calls to builtins to SAVE and RESTORE the stack as well as 1032169689Skan a temporary through which they communicate. */ 1033169689Skan 1034169689Skanstatic void 1035169689Skanbuild_stack_save_restore (tree *save, tree *restore) 1036169689Skan{ 1037169689Skan tree save_call, tmp_var; 1038169689Skan 1039169689Skan save_call = 1040169689Skan build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 1041169689Skan NULL_TREE); 1042169689Skan tmp_var = create_tmp_var (ptr_type_node, "saved_stack"); 1043169689Skan 1044169689Skan *save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call); 1045169689Skan *restore = 1046169689Skan build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE], 1047169689Skan tree_cons (NULL_TREE, tmp_var, NULL_TREE)); 1048169689Skan} 1049169689Skan 1050169689Skan/* Gimplify a BIND_EXPR. Just voidify and recurse. */ 1051169689Skan 1052169689Skanstatic enum gimplify_status 1053169689Skangimplify_bind_expr (tree *expr_p, tree *pre_p) 1054169689Skan{ 1055169689Skan tree bind_expr = *expr_p; 1056169689Skan bool old_save_stack = gimplify_ctxp->save_stack; 1057169689Skan tree t; 1058169689Skan 1059169689Skan tree temp = voidify_wrapper_expr (bind_expr, NULL); 1060169689Skan 1061169689Skan /* Mark variables seen in this bind expr. */ 1062169689Skan for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t)) 1063169689Skan { 1064169689Skan if (TREE_CODE (t) == VAR_DECL) 1065169689Skan { 1066169689Skan struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 1067169689Skan 1068169689Skan /* Mark variable as local. */ 1069169689Skan if (ctx && !is_global_var (t) 1070169689Skan && (! DECL_SEEN_IN_BIND_EXPR_P (t) 1071169689Skan || splay_tree_lookup (ctx->variables, 1072169689Skan (splay_tree_key) t) == NULL)) 1073169689Skan omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN); 1074169689Skan 1075169689Skan DECL_SEEN_IN_BIND_EXPR_P (t) = 1; 1076169689Skan } 1077169689Skan 1078169689Skan /* Preliminarily mark non-addressed complex variables as eligible 1079169689Skan for promotion to gimple registers. We'll transform their uses 1080169689Skan as we find them. */ 1081169689Skan if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE 1082169689Skan && !TREE_THIS_VOLATILE (t) 1083169689Skan && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t)) 1084169689Skan && !needs_to_live_in_memory (t)) 1085169689Skan DECL_COMPLEX_GIMPLE_REG_P (t) = 1; 1086169689Skan } 1087169689Skan 1088169689Skan gimple_push_bind_expr (bind_expr); 1089169689Skan gimplify_ctxp->save_stack = false; 1090169689Skan 1091169689Skan gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr)); 1092169689Skan 1093169689Skan if (gimplify_ctxp->save_stack) 1094169689Skan { 1095169689Skan tree stack_save, stack_restore; 1096169689Skan 1097169689Skan /* Save stack on entry and restore it on exit. Add a try_finally 1098169689Skan block to achieve this. Note that mudflap depends on the 1099169689Skan format of the emitted code: see mx_register_decls(). */ 1100169689Skan build_stack_save_restore (&stack_save, &stack_restore); 1101169689Skan 1102169689Skan t = build2 (TRY_FINALLY_EXPR, void_type_node, 1103169689Skan BIND_EXPR_BODY (bind_expr), NULL_TREE); 1104169689Skan append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1)); 1105169689Skan 1106169689Skan BIND_EXPR_BODY (bind_expr) = NULL_TREE; 1107169689Skan append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr)); 1108169689Skan append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr)); 1109169689Skan } 1110169689Skan 1111169689Skan gimplify_ctxp->save_stack = old_save_stack; 1112169689Skan gimple_pop_bind_expr (); 1113169689Skan 1114169689Skan if (temp) 1115169689Skan { 1116169689Skan *expr_p = temp; 1117169689Skan append_to_statement_list (bind_expr, pre_p); 1118169689Skan return GS_OK; 1119169689Skan } 1120169689Skan else 1121169689Skan return GS_ALL_DONE; 1122169689Skan} 1123169689Skan 1124169689Skan/* Gimplify a RETURN_EXPR. If the expression to be returned is not a 1125169689Skan GIMPLE value, it is assigned to a new temporary and the statement is 1126169689Skan re-written to return the temporary. 1127169689Skan 1128169689Skan PRE_P points to the list where side effects that must happen before 1129169689Skan STMT should be stored. */ 1130169689Skan 1131169689Skanstatic enum gimplify_status 1132169689Skangimplify_return_expr (tree stmt, tree *pre_p) 1133169689Skan{ 1134169689Skan tree ret_expr = TREE_OPERAND (stmt, 0); 1135169689Skan tree result_decl, result; 1136169689Skan 1137169689Skan if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL 1138169689Skan || ret_expr == error_mark_node) 1139169689Skan return GS_ALL_DONE; 1140169689Skan 1141169689Skan if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) 1142169689Skan result_decl = NULL_TREE; 1143169689Skan else 1144169689Skan { 1145169689Skan result_decl = TREE_OPERAND (ret_expr, 0); 1146169689Skan if (TREE_CODE (result_decl) == INDIRECT_REF) 1147169689Skan /* See through a return by reference. */ 1148169689Skan result_decl = TREE_OPERAND (result_decl, 0); 1149169689Skan 1150169689Skan gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR 1151169689Skan || TREE_CODE (ret_expr) == INIT_EXPR) 1152169689Skan && TREE_CODE (result_decl) == RESULT_DECL); 1153169689Skan } 1154169689Skan 1155169689Skan /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. 1156169689Skan Recall that aggregate_value_p is FALSE for any aggregate type that is 1157169689Skan returned in registers. If we're returning values in registers, then 1158169689Skan we don't want to extend the lifetime of the RESULT_DECL, particularly 1159169689Skan across another call. In addition, for those aggregates for which 1160169689Skan hard_function_value generates a PARALLEL, we'll die during normal 1161169689Skan expansion of structure assignments; there's special code in expand_return 1162169689Skan to handle this case that does not exist in expand_expr. */ 1163169689Skan if (!result_decl 1164169689Skan || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl))) 1165169689Skan result = result_decl; 1166169689Skan else if (gimplify_ctxp->return_temp) 1167169689Skan result = gimplify_ctxp->return_temp; 1168169689Skan else 1169169689Skan { 1170169689Skan result = create_tmp_var (TREE_TYPE (result_decl), NULL); 1171169689Skan 1172169689Skan /* ??? With complex control flow (usually involving abnormal edges), 1173169689Skan we can wind up warning about an uninitialized value for this. Due 1174169689Skan to how this variable is constructed and initialized, this is never 1175169689Skan true. Give up and never warn. */ 1176169689Skan TREE_NO_WARNING (result) = 1; 1177169689Skan 1178169689Skan gimplify_ctxp->return_temp = result; 1179169689Skan } 1180169689Skan 1181169689Skan /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use. 1182169689Skan Then gimplify the whole thing. */ 1183169689Skan if (result != result_decl) 1184169689Skan TREE_OPERAND (ret_expr, 0) = result; 1185169689Skan 1186169689Skan gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p); 1187169689Skan 1188169689Skan /* If we didn't use a temporary, then the result is just the result_decl. 1189169689Skan Otherwise we need a simple copy. This should already be gimple. */ 1190169689Skan if (result == result_decl) 1191169689Skan ret_expr = result; 1192169689Skan else 1193169689Skan ret_expr = build2 (MODIFY_EXPR, TREE_TYPE (result), result_decl, result); 1194169689Skan TREE_OPERAND (stmt, 0) = ret_expr; 1195169689Skan 1196169689Skan return GS_ALL_DONE; 1197169689Skan} 1198169689Skan 1199169689Skan/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation 1200169689Skan and initialization explicit. */ 1201169689Skan 1202169689Skanstatic enum gimplify_status 1203169689Skangimplify_decl_expr (tree *stmt_p) 1204169689Skan{ 1205169689Skan tree stmt = *stmt_p; 1206169689Skan tree decl = DECL_EXPR_DECL (stmt); 1207169689Skan 1208169689Skan *stmt_p = NULL_TREE; 1209169689Skan 1210169689Skan if (TREE_TYPE (decl) == error_mark_node) 1211169689Skan return GS_ERROR; 1212169689Skan 1213169689Skan if ((TREE_CODE (decl) == TYPE_DECL 1214169689Skan || TREE_CODE (decl) == VAR_DECL) 1215169689Skan && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl))) 1216169689Skan gimplify_type_sizes (TREE_TYPE (decl), stmt_p); 1217169689Skan 1218169689Skan if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) 1219169689Skan { 1220169689Skan tree init = DECL_INITIAL (decl); 1221169689Skan 1222169689Skan if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 1223169689Skan { 1224169689Skan /* This is a variable-sized decl. Simplify its size and mark it 1225169689Skan for deferred expansion. Note that mudflap depends on the format 1226169689Skan of the emitted code: see mx_register_decls(). */ 1227169689Skan tree t, args, addr, ptr_type; 1228169689Skan 1229169689Skan gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p); 1230169689Skan gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p); 1231169689Skan 1232169689Skan /* All occurrences of this decl in final gimplified code will be 1233169689Skan replaced by indirection. Setting DECL_VALUE_EXPR does two 1234169689Skan things: First, it lets the rest of the gimplifier know what 1235169689Skan replacement to use. Second, it lets the debug info know 1236169689Skan where to find the value. */ 1237169689Skan ptr_type = build_pointer_type (TREE_TYPE (decl)); 1238169689Skan addr = create_tmp_var (ptr_type, get_name (decl)); 1239169689Skan DECL_IGNORED_P (addr) = 0; 1240169689Skan t = build_fold_indirect_ref (addr); 1241169689Skan SET_DECL_VALUE_EXPR (decl, t); 1242169689Skan DECL_HAS_VALUE_EXPR_P (decl) = 1; 1243169689Skan 1244169689Skan args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL); 1245169689Skan t = built_in_decls[BUILT_IN_ALLOCA]; 1246169689Skan t = build_function_call_expr (t, args); 1247169689Skan t = fold_convert (ptr_type, t); 1248169689Skan t = build2 (MODIFY_EXPR, void_type_node, addr, t); 1249169689Skan 1250169689Skan gimplify_and_add (t, stmt_p); 1251169689Skan 1252169689Skan /* Indicate that we need to restore the stack level when the 1253169689Skan enclosing BIND_EXPR is exited. */ 1254169689Skan gimplify_ctxp->save_stack = true; 1255169689Skan } 1256169689Skan 1257169689Skan if (init && init != error_mark_node) 1258169689Skan { 1259169689Skan if (!TREE_STATIC (decl)) 1260169689Skan { 1261169689Skan DECL_INITIAL (decl) = NULL_TREE; 1262169689Skan init = build2 (INIT_EXPR, void_type_node, decl, init); 1263169689Skan gimplify_and_add (init, stmt_p); 1264169689Skan } 1265169689Skan else 1266169689Skan /* We must still examine initializers for static variables 1267169689Skan as they may contain a label address. */ 1268169689Skan walk_tree (&init, force_labels_r, NULL, NULL); 1269169689Skan } 1270169689Skan 1271169689Skan /* Some front ends do not explicitly declare all anonymous 1272169689Skan artificial variables. We compensate here by declaring the 1273169689Skan variables, though it would be better if the front ends would 1274169689Skan explicitly declare them. */ 1275169689Skan if (!DECL_SEEN_IN_BIND_EXPR_P (decl) 1276169689Skan && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE) 1277169689Skan gimple_add_tmp_var (decl); 1278169689Skan } 1279169689Skan 1280169689Skan return GS_ALL_DONE; 1281169689Skan} 1282169689Skan 1283169689Skan/* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body 1284169689Skan and replacing the LOOP_EXPR with goto, but if the loop contains an 1285169689Skan EXIT_EXPR, we need to append a label for it to jump to. */ 1286169689Skan 1287169689Skanstatic enum gimplify_status 1288169689Skangimplify_loop_expr (tree *expr_p, tree *pre_p) 1289169689Skan{ 1290169689Skan tree saved_label = gimplify_ctxp->exit_label; 1291169689Skan tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE); 1292169689Skan tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label)); 1293169689Skan 1294169689Skan append_to_statement_list (start_label, pre_p); 1295169689Skan 1296169689Skan gimplify_ctxp->exit_label = NULL_TREE; 1297169689Skan 1298169689Skan gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p); 1299169689Skan 1300169689Skan if (gimplify_ctxp->exit_label) 1301169689Skan { 1302169689Skan append_to_statement_list (jump_stmt, pre_p); 1303169689Skan *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label); 1304169689Skan } 1305169689Skan else 1306169689Skan *expr_p = jump_stmt; 1307169689Skan 1308169689Skan gimplify_ctxp->exit_label = saved_label; 1309169689Skan 1310169689Skan return GS_ALL_DONE; 1311169689Skan} 1312169689Skan 1313169689Skan/* Compare two case labels. Because the front end should already have 1314169689Skan made sure that case ranges do not overlap, it is enough to only compare 1315169689Skan the CASE_LOW values of each case label. */ 1316169689Skan 1317169689Skanstatic int 1318169689Skancompare_case_labels (const void *p1, const void *p2) 1319169689Skan{ 1320169689Skan tree case1 = *(tree *)p1; 1321169689Skan tree case2 = *(tree *)p2; 1322169689Skan 1323169689Skan return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2)); 1324169689Skan} 1325169689Skan 1326169689Skan/* Sort the case labels in LABEL_VEC in place in ascending order. */ 1327169689Skan 1328169689Skanvoid 1329169689Skansort_case_labels (tree label_vec) 1330169689Skan{ 1331169689Skan size_t len = TREE_VEC_LENGTH (label_vec); 1332169689Skan tree default_case = TREE_VEC_ELT (label_vec, len - 1); 1333169689Skan 1334169689Skan if (CASE_LOW (default_case)) 1335169689Skan { 1336169689Skan size_t i; 1337169689Skan 1338169689Skan /* The last label in the vector should be the default case 1339169689Skan but it is not. */ 1340169689Skan for (i = 0; i < len; ++i) 1341169689Skan { 1342169689Skan tree t = TREE_VEC_ELT (label_vec, i); 1343169689Skan if (!CASE_LOW (t)) 1344169689Skan { 1345169689Skan default_case = t; 1346169689Skan TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1); 1347169689Skan TREE_VEC_ELT (label_vec, len - 1) = default_case; 1348169689Skan break; 1349169689Skan } 1350169689Skan } 1351169689Skan } 1352169689Skan 1353169689Skan qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree), 1354169689Skan compare_case_labels); 1355169689Skan} 1356169689Skan 1357169689Skan/* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can 1358169689Skan branch to. */ 1359169689Skan 1360169689Skanstatic enum gimplify_status 1361169689Skangimplify_switch_expr (tree *expr_p, tree *pre_p) 1362169689Skan{ 1363169689Skan tree switch_expr = *expr_p; 1364169689Skan enum gimplify_status ret; 1365169689Skan 1366169689Skan ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, 1367169689Skan is_gimple_val, fb_rvalue); 1368169689Skan 1369169689Skan if (SWITCH_BODY (switch_expr)) 1370169689Skan { 1371169689Skan VEC(tree,heap) *labels, *saved_labels; 1372169689Skan tree label_vec, default_case = NULL_TREE; 1373169689Skan size_t i, len; 1374169689Skan 1375169689Skan /* If someone can be bothered to fill in the labels, they can 1376169689Skan be bothered to null out the body too. */ 1377169689Skan gcc_assert (!SWITCH_LABELS (switch_expr)); 1378169689Skan 1379169689Skan saved_labels = gimplify_ctxp->case_labels; 1380169689Skan gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8); 1381169689Skan 1382169689Skan gimplify_to_stmt_list (&SWITCH_BODY (switch_expr)); 1383169689Skan 1384169689Skan labels = gimplify_ctxp->case_labels; 1385169689Skan gimplify_ctxp->case_labels = saved_labels; 1386169689Skan 1387169689Skan i = 0; 1388169689Skan while (i < VEC_length (tree, labels)) 1389169689Skan { 1390169689Skan tree elt = VEC_index (tree, labels, i); 1391169689Skan tree low = CASE_LOW (elt); 1392169689Skan bool remove_element = FALSE; 1393169689Skan 1394169689Skan if (low) 1395169689Skan { 1396169689Skan /* Discard empty ranges. */ 1397169689Skan tree high = CASE_HIGH (elt); 1398169689Skan if (high && INT_CST_LT (high, low)) 1399169689Skan remove_element = TRUE; 1400169689Skan } 1401169689Skan else 1402169689Skan { 1403169689Skan /* The default case must be the last label in the list. */ 1404169689Skan gcc_assert (!default_case); 1405169689Skan default_case = elt; 1406169689Skan remove_element = TRUE; 1407169689Skan } 1408169689Skan 1409169689Skan if (remove_element) 1410169689Skan VEC_ordered_remove (tree, labels, i); 1411169689Skan else 1412169689Skan i++; 1413169689Skan } 1414169689Skan len = i; 1415169689Skan 1416169689Skan label_vec = make_tree_vec (len + 1); 1417169689Skan SWITCH_LABELS (*expr_p) = label_vec; 1418169689Skan append_to_statement_list (switch_expr, pre_p); 1419169689Skan 1420169689Skan if (! default_case) 1421169689Skan { 1422169689Skan /* If the switch has no default label, add one, so that we jump 1423169689Skan around the switch body. */ 1424169689Skan default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, 1425169689Skan NULL_TREE, create_artificial_label ()); 1426169689Skan append_to_statement_list (SWITCH_BODY (switch_expr), pre_p); 1427169689Skan *expr_p = build1 (LABEL_EXPR, void_type_node, 1428169689Skan CASE_LABEL (default_case)); 1429169689Skan } 1430169689Skan else 1431169689Skan *expr_p = SWITCH_BODY (switch_expr); 1432169689Skan 1433169689Skan for (i = 0; i < len; ++i) 1434169689Skan TREE_VEC_ELT (label_vec, i) = VEC_index (tree, labels, i); 1435169689Skan TREE_VEC_ELT (label_vec, len) = default_case; 1436169689Skan 1437169689Skan VEC_free (tree, heap, labels); 1438169689Skan 1439169689Skan sort_case_labels (label_vec); 1440169689Skan 1441169689Skan SWITCH_BODY (switch_expr) = NULL; 1442169689Skan } 1443169689Skan else 1444169689Skan gcc_assert (SWITCH_LABELS (switch_expr)); 1445169689Skan 1446169689Skan return ret; 1447169689Skan} 1448169689Skan 1449169689Skanstatic enum gimplify_status 1450169689Skangimplify_case_label_expr (tree *expr_p) 1451169689Skan{ 1452169689Skan tree expr = *expr_p; 1453169689Skan struct gimplify_ctx *ctxp; 1454169689Skan 1455169689Skan /* Invalid OpenMP programs can play Duff's Device type games with 1456169689Skan #pragma omp parallel. At least in the C front end, we don't 1457169689Skan detect such invalid branches until after gimplification. */ 1458169689Skan for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context) 1459169689Skan if (ctxp->case_labels) 1460169689Skan break; 1461169689Skan 1462169689Skan VEC_safe_push (tree, heap, ctxp->case_labels, expr); 1463169689Skan *expr_p = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (expr)); 1464169689Skan return GS_ALL_DONE; 1465169689Skan} 1466169689Skan 1467169689Skan/* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first 1468169689Skan if necessary. */ 1469169689Skan 1470169689Skantree 1471169689Skanbuild_and_jump (tree *label_p) 1472169689Skan{ 1473169689Skan if (label_p == NULL) 1474169689Skan /* If there's nowhere to jump, just fall through. */ 1475169689Skan return NULL_TREE; 1476169689Skan 1477169689Skan if (*label_p == NULL_TREE) 1478169689Skan { 1479169689Skan tree label = create_artificial_label (); 1480169689Skan *label_p = label; 1481169689Skan } 1482169689Skan 1483169689Skan return build1 (GOTO_EXPR, void_type_node, *label_p); 1484169689Skan} 1485169689Skan 1486169689Skan/* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR. 1487169689Skan This also involves building a label to jump to and communicating it to 1488169689Skan gimplify_loop_expr through gimplify_ctxp->exit_label. */ 1489169689Skan 1490169689Skanstatic enum gimplify_status 1491169689Skangimplify_exit_expr (tree *expr_p) 1492169689Skan{ 1493169689Skan tree cond = TREE_OPERAND (*expr_p, 0); 1494169689Skan tree expr; 1495169689Skan 1496169689Skan expr = build_and_jump (&gimplify_ctxp->exit_label); 1497169689Skan expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE); 1498169689Skan *expr_p = expr; 1499169689Skan 1500169689Skan return GS_OK; 1501169689Skan} 1502169689Skan 1503169689Skan/* A helper function to be called via walk_tree. Mark all labels under *TP 1504169689Skan as being forced. To be called for DECL_INITIAL of static variables. */ 1505169689Skan 1506169689Skantree 1507169689Skanforce_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 1508169689Skan{ 1509169689Skan if (TYPE_P (*tp)) 1510169689Skan *walk_subtrees = 0; 1511169689Skan if (TREE_CODE (*tp) == LABEL_DECL) 1512169689Skan FORCED_LABEL (*tp) = 1; 1513169689Skan 1514169689Skan return NULL_TREE; 1515169689Skan} 1516169689Skan 1517169689Skan/* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is 1518169689Skan different from its canonical type, wrap the whole thing inside a 1519169689Skan NOP_EXPR and force the type of the COMPONENT_REF to be the canonical 1520169689Skan type. 1521169689Skan 1522169689Skan The canonical type of a COMPONENT_REF is the type of the field being 1523169689Skan referenced--unless the field is a bit-field which can be read directly 1524169689Skan in a smaller mode, in which case the canonical type is the 1525169689Skan sign-appropriate type corresponding to that mode. */ 1526169689Skan 1527169689Skanstatic void 1528169689Skancanonicalize_component_ref (tree *expr_p) 1529169689Skan{ 1530169689Skan tree expr = *expr_p; 1531169689Skan tree type; 1532169689Skan 1533169689Skan gcc_assert (TREE_CODE (expr) == COMPONENT_REF); 1534169689Skan 1535169689Skan if (INTEGRAL_TYPE_P (TREE_TYPE (expr))) 1536169689Skan type = TREE_TYPE (get_unwidened (expr, NULL_TREE)); 1537169689Skan else 1538169689Skan type = TREE_TYPE (TREE_OPERAND (expr, 1)); 1539169689Skan 1540169689Skan if (TREE_TYPE (expr) != type) 1541169689Skan { 1542169689Skan tree old_type = TREE_TYPE (expr); 1543169689Skan 1544169689Skan /* Set the type of the COMPONENT_REF to the underlying type. */ 1545169689Skan TREE_TYPE (expr) = type; 1546169689Skan 1547169689Skan /* And wrap the whole thing inside a NOP_EXPR. */ 1548169689Skan expr = build1 (NOP_EXPR, old_type, expr); 1549169689Skan 1550169689Skan *expr_p = expr; 1551169689Skan } 1552169689Skan} 1553169689Skan 1554169689Skan/* If a NOP conversion is changing a pointer to array of foo to a pointer 1555169689Skan to foo, embed that change in the ADDR_EXPR by converting 1556169689Skan T array[U]; 1557169689Skan (T *)&array 1558169689Skan ==> 1559169689Skan &array[L] 1560169689Skan where L is the lower bound. For simplicity, only do this for constant 1561169689Skan lower bound. */ 1562169689Skan 1563169689Skanstatic void 1564169689Skancanonicalize_addr_expr (tree *expr_p) 1565169689Skan{ 1566169689Skan tree expr = *expr_p; 1567169689Skan tree ctype = TREE_TYPE (expr); 1568169689Skan tree addr_expr = TREE_OPERAND (expr, 0); 1569169689Skan tree atype = TREE_TYPE (addr_expr); 1570169689Skan tree dctype, datype, ddatype, otype, obj_expr; 1571169689Skan 1572169689Skan /* Both cast and addr_expr types should be pointers. */ 1573169689Skan if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype)) 1574169689Skan return; 1575169689Skan 1576169689Skan /* The addr_expr type should be a pointer to an array. */ 1577169689Skan datype = TREE_TYPE (atype); 1578169689Skan if (TREE_CODE (datype) != ARRAY_TYPE) 1579169689Skan return; 1580169689Skan 1581169689Skan /* Both cast and addr_expr types should address the same object type. */ 1582169689Skan dctype = TREE_TYPE (ctype); 1583169689Skan ddatype = TREE_TYPE (datype); 1584169689Skan if (!lang_hooks.types_compatible_p (ddatype, dctype)) 1585169689Skan return; 1586169689Skan 1587169689Skan /* The addr_expr and the object type should match. */ 1588169689Skan obj_expr = TREE_OPERAND (addr_expr, 0); 1589169689Skan otype = TREE_TYPE (obj_expr); 1590169689Skan if (!lang_hooks.types_compatible_p (otype, datype)) 1591169689Skan return; 1592169689Skan 1593169689Skan /* The lower bound and element sizes must be constant. */ 1594169689Skan if (!TYPE_SIZE_UNIT (dctype) 1595169689Skan || TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST 1596169689Skan || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype)) 1597169689Skan || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST) 1598169689Skan return; 1599169689Skan 1600169689Skan /* All checks succeeded. Build a new node to merge the cast. */ 1601169689Skan *expr_p = build4 (ARRAY_REF, dctype, obj_expr, 1602169689Skan TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), 1603237406Spfg NULL_TREE, NULL_TREE); 1604169689Skan *expr_p = build1 (ADDR_EXPR, ctype, *expr_p); 1605169689Skan} 1606169689Skan 1607169689Skan/* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions 1608169689Skan underneath as appropriate. */ 1609169689Skan 1610169689Skanstatic enum gimplify_status 1611169689Skangimplify_conversion (tree *expr_p) 1612169689Skan{ 1613169689Skan gcc_assert (TREE_CODE (*expr_p) == NOP_EXPR 1614169689Skan || TREE_CODE (*expr_p) == CONVERT_EXPR); 1615169689Skan 1616169689Skan /* Then strip away all but the outermost conversion. */ 1617169689Skan STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0)); 1618169689Skan 1619169689Skan /* And remove the outermost conversion if it's useless. */ 1620169689Skan if (tree_ssa_useless_type_conversion (*expr_p)) 1621169689Skan *expr_p = TREE_OPERAND (*expr_p, 0); 1622169689Skan 1623169689Skan /* If we still have a conversion at the toplevel, 1624169689Skan then canonicalize some constructs. */ 1625169689Skan if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR) 1626169689Skan { 1627169689Skan tree sub = TREE_OPERAND (*expr_p, 0); 1628169689Skan 1629169689Skan /* If a NOP conversion is changing the type of a COMPONENT_REF 1630169689Skan expression, then canonicalize its type now in order to expose more 1631169689Skan redundant conversions. */ 1632169689Skan if (TREE_CODE (sub) == COMPONENT_REF) 1633169689Skan canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)); 1634169689Skan 1635169689Skan /* If a NOP conversion is changing a pointer to array of foo 1636169689Skan to a pointer to foo, embed that change in the ADDR_EXPR. */ 1637169689Skan else if (TREE_CODE (sub) == ADDR_EXPR) 1638169689Skan canonicalize_addr_expr (expr_p); 1639169689Skan } 1640169689Skan 1641169689Skan return GS_OK; 1642169689Skan} 1643169689Skan 1644169689Skan/* Gimplify a VAR_DECL or PARM_DECL. Returns GS_OK if we expanded a 1645169689Skan DECL_VALUE_EXPR, and it's worth re-examining things. */ 1646169689Skan 1647169689Skanstatic enum gimplify_status 1648169689Skangimplify_var_or_parm_decl (tree *expr_p) 1649169689Skan{ 1650169689Skan tree decl = *expr_p; 1651169689Skan 1652169689Skan /* ??? If this is a local variable, and it has not been seen in any 1653169689Skan outer BIND_EXPR, then it's probably the result of a duplicate 1654169689Skan declaration, for which we've already issued an error. It would 1655169689Skan be really nice if the front end wouldn't leak these at all. 1656169689Skan Currently the only known culprit is C++ destructors, as seen 1657169689Skan in g++.old-deja/g++.jason/binding.C. */ 1658169689Skan if (TREE_CODE (decl) == VAR_DECL 1659169689Skan && !DECL_SEEN_IN_BIND_EXPR_P (decl) 1660169689Skan && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl) 1661169689Skan && decl_function_context (decl) == current_function_decl) 1662169689Skan { 1663169689Skan gcc_assert (errorcount || sorrycount); 1664169689Skan return GS_ERROR; 1665169689Skan } 1666169689Skan 1667169689Skan /* When within an OpenMP context, notice uses of variables. */ 1668169689Skan if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true)) 1669169689Skan return GS_ALL_DONE; 1670169689Skan 1671169689Skan /* If the decl is an alias for another expression, substitute it now. */ 1672169689Skan if (DECL_HAS_VALUE_EXPR_P (decl)) 1673169689Skan { 1674169689Skan *expr_p = unshare_expr (DECL_VALUE_EXPR (decl)); 1675169689Skan return GS_OK; 1676169689Skan } 1677169689Skan 1678169689Skan return GS_ALL_DONE; 1679169689Skan} 1680169689Skan 1681169689Skan 1682169689Skan/* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR 1683169689Skan node pointed to by EXPR_P. 1684169689Skan 1685169689Skan compound_lval 1686169689Skan : min_lval '[' val ']' 1687169689Skan | min_lval '.' ID 1688169689Skan | compound_lval '[' val ']' 1689169689Skan | compound_lval '.' ID 1690169689Skan 1691169689Skan This is not part of the original SIMPLE definition, which separates 1692169689Skan array and member references, but it seems reasonable to handle them 1693169689Skan together. Also, this way we don't run into problems with union 1694169689Skan aliasing; gcc requires that for accesses through a union to alias, the 1695169689Skan union reference must be explicit, which was not always the case when we 1696169689Skan were splitting up array and member refs. 1697169689Skan 1698169689Skan PRE_P points to the list where side effects that must happen before 1699169689Skan *EXPR_P should be stored. 1700169689Skan 1701169689Skan POST_P points to the list where side effects that must happen after 1702169689Skan *EXPR_P should be stored. */ 1703169689Skan 1704169689Skanstatic enum gimplify_status 1705169689Skangimplify_compound_lval (tree *expr_p, tree *pre_p, 1706169689Skan tree *post_p, fallback_t fallback) 1707169689Skan{ 1708169689Skan tree *p; 1709169689Skan VEC(tree,heap) *stack; 1710169689Skan enum gimplify_status ret = GS_OK, tret; 1711169689Skan int i; 1712169689Skan 1713169689Skan /* Create a stack of the subexpressions so later we can walk them in 1714169689Skan order from inner to outer. */ 1715169689Skan stack = VEC_alloc (tree, heap, 10); 1716169689Skan 1717169689Skan /* We can handle anything that get_inner_reference can deal with. */ 1718169689Skan for (p = expr_p; ; p = &TREE_OPERAND (*p, 0)) 1719169689Skan { 1720169689Skan restart: 1721169689Skan /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */ 1722169689Skan if (TREE_CODE (*p) == INDIRECT_REF) 1723169689Skan *p = fold_indirect_ref (*p); 1724169689Skan 1725169689Skan if (handled_component_p (*p)) 1726169689Skan ; 1727169689Skan /* Expand DECL_VALUE_EXPR now. In some cases that may expose 1728169689Skan additional COMPONENT_REFs. */ 1729169689Skan else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL) 1730169689Skan && gimplify_var_or_parm_decl (p) == GS_OK) 1731169689Skan goto restart; 1732169689Skan else 1733169689Skan break; 1734169689Skan 1735169689Skan VEC_safe_push (tree, heap, stack, *p); 1736169689Skan } 1737169689Skan 1738169689Skan gcc_assert (VEC_length (tree, stack)); 1739169689Skan 1740169689Skan /* Now STACK is a stack of pointers to all the refs we've walked through 1741169689Skan and P points to the innermost expression. 1742169689Skan 1743169689Skan Java requires that we elaborated nodes in source order. That 1744169689Skan means we must gimplify the inner expression followed by each of 1745169689Skan the indices, in order. But we can't gimplify the inner 1746169689Skan expression until we deal with any variable bounds, sizes, or 1747169689Skan positions in order to deal with PLACEHOLDER_EXPRs. 1748169689Skan 1749169689Skan So we do this in three steps. First we deal with the annotations 1750169689Skan for any variables in the components, then we gimplify the base, 1751169689Skan then we gimplify any indices, from left to right. */ 1752169689Skan for (i = VEC_length (tree, stack) - 1; i >= 0; i--) 1753169689Skan { 1754169689Skan tree t = VEC_index (tree, stack, i); 1755169689Skan 1756169689Skan if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) 1757169689Skan { 1758169689Skan /* Gimplify the low bound and element type size and put them into 1759169689Skan the ARRAY_REF. If these values are set, they have already been 1760169689Skan gimplified. */ 1761169689Skan if (!TREE_OPERAND (t, 2)) 1762169689Skan { 1763169689Skan tree low = unshare_expr (array_ref_low_bound (t)); 1764169689Skan if (!is_gimple_min_invariant (low)) 1765169689Skan { 1766169689Skan TREE_OPERAND (t, 2) = low; 1767169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, 1768169689Skan is_gimple_formal_tmp_reg, fb_rvalue); 1769169689Skan ret = MIN (ret, tret); 1770169689Skan } 1771169689Skan } 1772169689Skan 1773169689Skan if (!TREE_OPERAND (t, 3)) 1774169689Skan { 1775169689Skan tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); 1776169689Skan tree elmt_size = unshare_expr (array_ref_element_size (t)); 1777169689Skan tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); 1778169689Skan 1779169689Skan /* Divide the element size by the alignment of the element 1780169689Skan type (above). */ 1781169689Skan elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor); 1782169689Skan 1783169689Skan if (!is_gimple_min_invariant (elmt_size)) 1784169689Skan { 1785169689Skan TREE_OPERAND (t, 3) = elmt_size; 1786169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p, 1787169689Skan is_gimple_formal_tmp_reg, fb_rvalue); 1788169689Skan ret = MIN (ret, tret); 1789169689Skan } 1790169689Skan } 1791169689Skan } 1792169689Skan else if (TREE_CODE (t) == COMPONENT_REF) 1793169689Skan { 1794169689Skan /* Set the field offset into T and gimplify it. */ 1795169689Skan if (!TREE_OPERAND (t, 2)) 1796169689Skan { 1797169689Skan tree offset = unshare_expr (component_ref_field_offset (t)); 1798169689Skan tree field = TREE_OPERAND (t, 1); 1799169689Skan tree factor 1800169689Skan = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); 1801169689Skan 1802169689Skan /* Divide the offset by its alignment. */ 1803169689Skan offset = size_binop (EXACT_DIV_EXPR, offset, factor); 1804169689Skan 1805169689Skan if (!is_gimple_min_invariant (offset)) 1806169689Skan { 1807169689Skan TREE_OPERAND (t, 2) = offset; 1808169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, 1809169689Skan is_gimple_formal_tmp_reg, fb_rvalue); 1810169689Skan ret = MIN (ret, tret); 1811169689Skan } 1812169689Skan } 1813169689Skan } 1814169689Skan } 1815169689Skan 1816169689Skan /* Step 2 is to gimplify the base expression. Make sure lvalue is set 1817169689Skan so as to match the min_lval predicate. Failure to do so may result 1818169689Skan in the creation of large aggregate temporaries. */ 1819169689Skan tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, 1820169689Skan fallback | fb_lvalue); 1821169689Skan ret = MIN (ret, tret); 1822169689Skan 1823169689Skan /* And finally, the indices and operands to BIT_FIELD_REF. During this 1824169689Skan loop we also remove any useless conversions. */ 1825169689Skan for (; VEC_length (tree, stack) > 0; ) 1826169689Skan { 1827169689Skan tree t = VEC_pop (tree, stack); 1828169689Skan 1829169689Skan if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) 1830169689Skan { 1831169689Skan /* Gimplify the dimension. 1832169689Skan Temporary fix for gcc.c-torture/execute/20040313-1.c. 1833169689Skan Gimplify non-constant array indices into a temporary 1834169689Skan variable. 1835169689Skan FIXME - The real fix is to gimplify post-modify 1836169689Skan expressions into a minimal gimple lvalue. However, that 1837169689Skan exposes bugs in alias analysis. The alias analyzer does 1838169689Skan not handle &PTR->FIELD very well. Will fix after the 1839169689Skan branch is merged into mainline (dnovillo 2004-05-03). */ 1840169689Skan if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))) 1841169689Skan { 1842169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, 1843169689Skan is_gimple_formal_tmp_reg, fb_rvalue); 1844169689Skan ret = MIN (ret, tret); 1845169689Skan } 1846169689Skan } 1847169689Skan else if (TREE_CODE (t) == BIT_FIELD_REF) 1848169689Skan { 1849169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, 1850169689Skan is_gimple_val, fb_rvalue); 1851169689Skan ret = MIN (ret, tret); 1852169689Skan tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, 1853169689Skan is_gimple_val, fb_rvalue); 1854169689Skan ret = MIN (ret, tret); 1855169689Skan } 1856169689Skan 1857169689Skan STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0)); 1858169689Skan 1859169689Skan /* The innermost expression P may have originally had TREE_SIDE_EFFECTS 1860169689Skan set which would have caused all the outer expressions in EXPR_P 1861169689Skan leading to P to also have had TREE_SIDE_EFFECTS set. */ 1862169689Skan recalculate_side_effects (t); 1863169689Skan } 1864169689Skan 1865169689Skan tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback); 1866169689Skan ret = MIN (ret, tret); 1867169689Skan 1868169689Skan /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */ 1869169689Skan if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF) 1870169689Skan { 1871169689Skan canonicalize_component_ref (expr_p); 1872169689Skan ret = MIN (ret, GS_OK); 1873169689Skan } 1874169689Skan 1875169689Skan VEC_free (tree, heap, stack); 1876169689Skan 1877169689Skan return ret; 1878169689Skan} 1879169689Skan 1880169689Skan/* Gimplify the self modifying expression pointed to by EXPR_P 1881169689Skan (++, --, +=, -=). 1882169689Skan 1883169689Skan PRE_P points to the list where side effects that must happen before 1884169689Skan *EXPR_P should be stored. 1885169689Skan 1886169689Skan POST_P points to the list where side effects that must happen after 1887169689Skan *EXPR_P should be stored. 1888169689Skan 1889169689Skan WANT_VALUE is nonzero iff we want to use the value of this expression 1890169689Skan in another expression. */ 1891169689Skan 1892169689Skanstatic enum gimplify_status 1893169689Skangimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p, 1894169689Skan bool want_value) 1895169689Skan{ 1896169689Skan enum tree_code code; 1897169689Skan tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p; 1898169689Skan bool postfix; 1899169689Skan enum tree_code arith_code; 1900169689Skan enum gimplify_status ret; 1901169689Skan 1902169689Skan code = TREE_CODE (*expr_p); 1903169689Skan 1904169689Skan gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR 1905169689Skan || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); 1906169689Skan 1907169689Skan /* Prefix or postfix? */ 1908169689Skan if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) 1909169689Skan /* Faster to treat as prefix if result is not used. */ 1910169689Skan postfix = want_value; 1911169689Skan else 1912169689Skan postfix = false; 1913169689Skan 1914169689Skan /* For postfix, make sure the inner expression's post side effects 1915169689Skan are executed after side effects from this expression. */ 1916169689Skan if (postfix) 1917169689Skan post_p = &post; 1918169689Skan 1919169689Skan /* Add or subtract? */ 1920169689Skan if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) 1921169689Skan arith_code = PLUS_EXPR; 1922169689Skan else 1923169689Skan arith_code = MINUS_EXPR; 1924169689Skan 1925169689Skan /* Gimplify the LHS into a GIMPLE lvalue. */ 1926169689Skan lvalue = TREE_OPERAND (*expr_p, 0); 1927169689Skan ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 1928169689Skan if (ret == GS_ERROR) 1929169689Skan return ret; 1930169689Skan 1931169689Skan /* Extract the operands to the arithmetic operation. */ 1932169689Skan lhs = lvalue; 1933169689Skan rhs = TREE_OPERAND (*expr_p, 1); 1934169689Skan 1935169689Skan /* For postfix operator, we evaluate the LHS to an rvalue and then use 1936169689Skan that as the result value and in the postqueue operation. */ 1937169689Skan if (postfix) 1938169689Skan { 1939169689Skan ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); 1940169689Skan if (ret == GS_ERROR) 1941169689Skan return ret; 1942169689Skan } 1943169689Skan 1944169689Skan t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs); 1945169689Skan t1 = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1); 1946169689Skan 1947169689Skan if (postfix) 1948169689Skan { 1949169689Skan gimplify_and_add (t1, orig_post_p); 1950169689Skan append_to_statement_list (post, orig_post_p); 1951169689Skan *expr_p = lhs; 1952169689Skan return GS_ALL_DONE; 1953169689Skan } 1954169689Skan else 1955169689Skan { 1956169689Skan *expr_p = t1; 1957169689Skan return GS_OK; 1958169689Skan } 1959169689Skan} 1960169689Skan 1961169689Skan/* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */ 1962169689Skan 1963169689Skanstatic void 1964169689Skanmaybe_with_size_expr (tree *expr_p) 1965169689Skan{ 1966169689Skan tree expr = *expr_p; 1967169689Skan tree type = TREE_TYPE (expr); 1968169689Skan tree size; 1969169689Skan 1970169689Skan /* If we've already wrapped this or the type is error_mark_node, we can't do 1971169689Skan anything. */ 1972169689Skan if (TREE_CODE (expr) == WITH_SIZE_EXPR 1973169689Skan || type == error_mark_node) 1974169689Skan return; 1975169689Skan 1976169689Skan /* If the size isn't known or is a constant, we have nothing to do. */ 1977169689Skan size = TYPE_SIZE_UNIT (type); 1978169689Skan if (!size || TREE_CODE (size) == INTEGER_CST) 1979169689Skan return; 1980169689Skan 1981169689Skan /* Otherwise, make a WITH_SIZE_EXPR. */ 1982169689Skan size = unshare_expr (size); 1983169689Skan size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr); 1984169689Skan *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size); 1985169689Skan} 1986169689Skan 1987169689Skan/* Subroutine of gimplify_call_expr: Gimplify a single argument. */ 1988169689Skan 1989169689Skanstatic enum gimplify_status 1990169689Skangimplify_arg (tree *expr_p, tree *pre_p) 1991169689Skan{ 1992169689Skan bool (*test) (tree); 1993169689Skan fallback_t fb; 1994169689Skan 1995169689Skan /* In general, we allow lvalues for function arguments to avoid 1996169689Skan extra overhead of copying large aggregates out of even larger 1997169689Skan aggregates into temporaries only to copy the temporaries to 1998169689Skan the argument list. Make optimizers happy by pulling out to 1999169689Skan temporaries those types that fit in registers. */ 2000169689Skan if (is_gimple_reg_type (TREE_TYPE (*expr_p))) 2001169689Skan test = is_gimple_val, fb = fb_rvalue; 2002169689Skan else 2003169689Skan test = is_gimple_lvalue, fb = fb_either; 2004169689Skan 2005169689Skan /* If this is a variable sized type, we must remember the size. */ 2006169689Skan maybe_with_size_expr (expr_p); 2007169689Skan 2008169689Skan /* There is a sequence point before a function call. Side effects in 2009169689Skan the argument list must occur before the actual call. So, when 2010169689Skan gimplifying arguments, force gimplify_expr to use an internal 2011169689Skan post queue which is then appended to the end of PRE_P. */ 2012169689Skan return gimplify_expr (expr_p, pre_p, NULL, test, fb); 2013169689Skan} 2014169689Skan 2015169689Skan/* Gimplify the CALL_EXPR node pointed to by EXPR_P. PRE_P points to the 2016169689Skan list where side effects that must happen before *EXPR_P should be stored. 2017169689Skan WANT_VALUE is true if the result of the call is desired. */ 2018169689Skan 2019169689Skanstatic enum gimplify_status 2020169689Skangimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value) 2021169689Skan{ 2022169689Skan tree decl; 2023169689Skan tree arglist; 2024169689Skan enum gimplify_status ret; 2025169689Skan 2026169689Skan gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR); 2027169689Skan 2028169689Skan /* For reliable diagnostics during inlining, it is necessary that 2029169689Skan every call_expr be annotated with file and line. */ 2030169689Skan if (! EXPR_HAS_LOCATION (*expr_p)) 2031169689Skan SET_EXPR_LOCATION (*expr_p, input_location); 2032169689Skan 2033169689Skan /* This may be a call to a builtin function. 2034169689Skan 2035169689Skan Builtin function calls may be transformed into different 2036169689Skan (and more efficient) builtin function calls under certain 2037169689Skan circumstances. Unfortunately, gimplification can muck things 2038169689Skan up enough that the builtin expanders are not aware that certain 2039169689Skan transformations are still valid. 2040169689Skan 2041169689Skan So we attempt transformation/gimplification of the call before 2042169689Skan we gimplify the CALL_EXPR. At this time we do not manage to 2043169689Skan transform all calls in the same manner as the expanders do, but 2044169689Skan we do transform most of them. */ 2045169689Skan decl = get_callee_fndecl (*expr_p); 2046169689Skan if (decl && DECL_BUILT_IN (decl)) 2047169689Skan { 2048169689Skan tree arglist = TREE_OPERAND (*expr_p, 1); 2049169689Skan tree new = fold_builtin (decl, arglist, !want_value); 2050169689Skan 2051169689Skan if (new && new != *expr_p) 2052169689Skan { 2053169689Skan /* There was a transformation of this call which computes the 2054169689Skan same value, but in a more efficient way. Return and try 2055169689Skan again. */ 2056169689Skan *expr_p = new; 2057169689Skan return GS_OK; 2058169689Skan } 2059169689Skan 2060169689Skan if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 2061169689Skan && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START) 2062169689Skan { 2063169689Skan if (!arglist || !TREE_CHAIN (arglist)) 2064169689Skan { 2065169689Skan error ("too few arguments to function %<va_start%>"); 2066169689Skan *expr_p = build_empty_stmt (); 2067169689Skan return GS_OK; 2068169689Skan } 2069169689Skan 2070169689Skan if (fold_builtin_next_arg (TREE_CHAIN (arglist))) 2071169689Skan { 2072169689Skan *expr_p = build_empty_stmt (); 2073169689Skan return GS_OK; 2074169689Skan } 2075169689Skan /* Avoid gimplifying the second argument to va_start, which needs 2076169689Skan to be the plain PARM_DECL. */ 2077169689Skan return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p); 2078169689Skan } 2079169689Skan } 2080169689Skan 2081169689Skan /* There is a sequence point before the call, so any side effects in 2082169689Skan the calling expression must occur before the actual call. Force 2083169689Skan gimplify_expr to use an internal post queue. */ 2084169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL, 2085169689Skan is_gimple_call_addr, fb_rvalue); 2086169689Skan 2087169689Skan if (PUSH_ARGS_REVERSED) 2088169689Skan TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1)); 2089169689Skan for (arglist = TREE_OPERAND (*expr_p, 1); arglist; 2090169689Skan arglist = TREE_CHAIN (arglist)) 2091169689Skan { 2092169689Skan enum gimplify_status t; 2093169689Skan 2094169689Skan t = gimplify_arg (&TREE_VALUE (arglist), pre_p); 2095169689Skan 2096169689Skan if (t == GS_ERROR) 2097169689Skan ret = GS_ERROR; 2098169689Skan } 2099169689Skan if (PUSH_ARGS_REVERSED) 2100169689Skan TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1)); 2101169689Skan 2102169689Skan /* Try this again in case gimplification exposed something. */ 2103169689Skan if (ret != GS_ERROR) 2104169689Skan { 2105169689Skan decl = get_callee_fndecl (*expr_p); 2106169689Skan if (decl && DECL_BUILT_IN (decl)) 2107169689Skan { 2108169689Skan tree arglist = TREE_OPERAND (*expr_p, 1); 2109169689Skan tree new = fold_builtin (decl, arglist, !want_value); 2110169689Skan 2111169689Skan if (new && new != *expr_p) 2112169689Skan { 2113169689Skan /* There was a transformation of this call which computes the 2114169689Skan same value, but in a more efficient way. Return and try 2115169689Skan again. */ 2116169689Skan *expr_p = new; 2117169689Skan return GS_OK; 2118169689Skan } 2119169689Skan } 2120169689Skan } 2121169689Skan 2122169689Skan /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its 2123169689Skan decl. This allows us to eliminate redundant or useless 2124169689Skan calls to "const" functions. */ 2125169689Skan if (TREE_CODE (*expr_p) == CALL_EXPR 2126169689Skan && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE))) 2127169689Skan TREE_SIDE_EFFECTS (*expr_p) = 0; 2128169689Skan 2129169689Skan return ret; 2130169689Skan} 2131169689Skan 2132169689Skan/* Handle shortcut semantics in the predicate operand of a COND_EXPR by 2133169689Skan rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs. 2134169689Skan 2135169689Skan TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the 2136169689Skan condition is true or false, respectively. If null, we should generate 2137169689Skan our own to skip over the evaluation of this specific expression. 2138169689Skan 2139169689Skan This function is the tree equivalent of do_jump. 2140169689Skan 2141169689Skan shortcut_cond_r should only be called by shortcut_cond_expr. */ 2142169689Skan 2143169689Skanstatic tree 2144169689Skanshortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p) 2145169689Skan{ 2146169689Skan tree local_label = NULL_TREE; 2147169689Skan tree t, expr = NULL; 2148169689Skan 2149169689Skan /* OK, it's not a simple case; we need to pull apart the COND_EXPR to 2150169689Skan retain the shortcut semantics. Just insert the gotos here; 2151169689Skan shortcut_cond_expr will append the real blocks later. */ 2152169689Skan if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 2153169689Skan { 2154169689Skan /* Turn if (a && b) into 2155169689Skan 2156169689Skan if (a); else goto no; 2157169689Skan if (b) goto yes; else goto no; 2158169689Skan (no:) */ 2159169689Skan 2160169689Skan if (false_label_p == NULL) 2161169689Skan false_label_p = &local_label; 2162169689Skan 2163169689Skan t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p); 2164169689Skan append_to_statement_list (t, &expr); 2165169689Skan 2166169689Skan t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, 2167169689Skan false_label_p); 2168169689Skan append_to_statement_list (t, &expr); 2169169689Skan } 2170169689Skan else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 2171169689Skan { 2172169689Skan /* Turn if (a || b) into 2173169689Skan 2174169689Skan if (a) goto yes; 2175169689Skan if (b) goto yes; else goto no; 2176169689Skan (yes:) */ 2177169689Skan 2178169689Skan if (true_label_p == NULL) 2179169689Skan true_label_p = &local_label; 2180169689Skan 2181169689Skan t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL); 2182169689Skan append_to_statement_list (t, &expr); 2183169689Skan 2184169689Skan t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, 2185169689Skan false_label_p); 2186169689Skan append_to_statement_list (t, &expr); 2187169689Skan } 2188169689Skan else if (TREE_CODE (pred) == COND_EXPR) 2189169689Skan { 2190169689Skan /* As long as we're messing with gotos, turn if (a ? b : c) into 2191169689Skan if (a) 2192169689Skan if (b) goto yes; else goto no; 2193169689Skan else 2194169689Skan if (c) goto yes; else goto no; */ 2195169689Skan expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0), 2196169689Skan shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, 2197169689Skan false_label_p), 2198169689Skan shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, 2199169689Skan false_label_p)); 2200169689Skan } 2201169689Skan else 2202169689Skan { 2203169689Skan expr = build3 (COND_EXPR, void_type_node, pred, 2204169689Skan build_and_jump (true_label_p), 2205169689Skan build_and_jump (false_label_p)); 2206169689Skan } 2207169689Skan 2208169689Skan if (local_label) 2209169689Skan { 2210169689Skan t = build1 (LABEL_EXPR, void_type_node, local_label); 2211169689Skan append_to_statement_list (t, &expr); 2212169689Skan } 2213169689Skan 2214169689Skan return expr; 2215169689Skan} 2216169689Skan 2217169689Skanstatic tree 2218169689Skanshortcut_cond_expr (tree expr) 2219169689Skan{ 2220169689Skan tree pred = TREE_OPERAND (expr, 0); 2221169689Skan tree then_ = TREE_OPERAND (expr, 1); 2222169689Skan tree else_ = TREE_OPERAND (expr, 2); 2223169689Skan tree true_label, false_label, end_label, t; 2224169689Skan tree *true_label_p; 2225169689Skan tree *false_label_p; 2226169689Skan bool emit_end, emit_false, jump_over_else; 2227169689Skan bool then_se = then_ && TREE_SIDE_EFFECTS (then_); 2228169689Skan bool else_se = else_ && TREE_SIDE_EFFECTS (else_); 2229169689Skan 2230169689Skan /* First do simple transformations. */ 2231169689Skan if (!else_se) 2232169689Skan { 2233169689Skan /* If there is no 'else', turn (a && b) into if (a) if (b). */ 2234169689Skan while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 2235169689Skan { 2236169689Skan TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 2237169689Skan then_ = shortcut_cond_expr (expr); 2238169689Skan then_se = then_ && TREE_SIDE_EFFECTS (then_); 2239169689Skan pred = TREE_OPERAND (pred, 0); 2240169689Skan expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE); 2241169689Skan } 2242169689Skan } 2243169689Skan if (!then_se) 2244169689Skan { 2245169689Skan /* If there is no 'then', turn 2246169689Skan if (a || b); else d 2247169689Skan into 2248169689Skan if (a); else if (b); else d. */ 2249169689Skan while (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 2250169689Skan { 2251169689Skan TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 2252169689Skan else_ = shortcut_cond_expr (expr); 2253169689Skan else_se = else_ && TREE_SIDE_EFFECTS (else_); 2254169689Skan pred = TREE_OPERAND (pred, 0); 2255169689Skan expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_); 2256169689Skan } 2257169689Skan } 2258169689Skan 2259169689Skan /* If we're done, great. */ 2260169689Skan if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR 2261169689Skan && TREE_CODE (pred) != TRUTH_ORIF_EXPR) 2262169689Skan return expr; 2263169689Skan 2264169689Skan /* Otherwise we need to mess with gotos. Change 2265169689Skan if (a) c; else d; 2266169689Skan to 2267169689Skan if (a); else goto no; 2268169689Skan c; goto end; 2269169689Skan no: d; end: 2270169689Skan and recursively gimplify the condition. */ 2271169689Skan 2272169689Skan true_label = false_label = end_label = NULL_TREE; 2273169689Skan 2274169689Skan /* If our arms just jump somewhere, hijack those labels so we don't 2275169689Skan generate jumps to jumps. */ 2276169689Skan 2277169689Skan if (then_ 2278169689Skan && TREE_CODE (then_) == GOTO_EXPR 2279169689Skan && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL) 2280169689Skan { 2281169689Skan true_label = GOTO_DESTINATION (then_); 2282169689Skan then_ = NULL; 2283169689Skan then_se = false; 2284169689Skan } 2285169689Skan 2286169689Skan if (else_ 2287169689Skan && TREE_CODE (else_) == GOTO_EXPR 2288169689Skan && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL) 2289169689Skan { 2290169689Skan false_label = GOTO_DESTINATION (else_); 2291169689Skan else_ = NULL; 2292169689Skan else_se = false; 2293169689Skan } 2294169689Skan 2295169689Skan /* If we aren't hijacking a label for the 'then' branch, it falls through. */ 2296169689Skan if (true_label) 2297169689Skan true_label_p = &true_label; 2298169689Skan else 2299169689Skan true_label_p = NULL; 2300169689Skan 2301169689Skan /* The 'else' branch also needs a label if it contains interesting code. */ 2302169689Skan if (false_label || else_se) 2303169689Skan false_label_p = &false_label; 2304169689Skan else 2305169689Skan false_label_p = NULL; 2306169689Skan 2307169689Skan /* If there was nothing else in our arms, just forward the label(s). */ 2308169689Skan if (!then_se && !else_se) 2309169689Skan return shortcut_cond_r (pred, true_label_p, false_label_p); 2310169689Skan 2311169689Skan /* If our last subexpression already has a terminal label, reuse it. */ 2312169689Skan if (else_se) 2313169689Skan expr = expr_last (else_); 2314169689Skan else if (then_se) 2315169689Skan expr = expr_last (then_); 2316169689Skan else 2317169689Skan expr = NULL; 2318169689Skan if (expr && TREE_CODE (expr) == LABEL_EXPR) 2319169689Skan end_label = LABEL_EXPR_LABEL (expr); 2320169689Skan 2321169689Skan /* If we don't care about jumping to the 'else' branch, jump to the end 2322169689Skan if the condition is false. */ 2323169689Skan if (!false_label_p) 2324169689Skan false_label_p = &end_label; 2325169689Skan 2326169689Skan /* We only want to emit these labels if we aren't hijacking them. */ 2327169689Skan emit_end = (end_label == NULL_TREE); 2328169689Skan emit_false = (false_label == NULL_TREE); 2329169689Skan 2330169689Skan /* We only emit the jump over the else clause if we have to--if the 2331169689Skan then clause may fall through. Otherwise we can wind up with a 2332169689Skan useless jump and a useless label at the end of gimplified code, 2333169689Skan which will cause us to think that this conditional as a whole 2334169689Skan falls through even if it doesn't. If we then inline a function 2335169689Skan which ends with such a condition, that can cause us to issue an 2336169689Skan inappropriate warning about control reaching the end of a 2337169689Skan non-void function. */ 2338169689Skan jump_over_else = block_may_fallthru (then_); 2339169689Skan 2340169689Skan pred = shortcut_cond_r (pred, true_label_p, false_label_p); 2341169689Skan 2342169689Skan expr = NULL; 2343169689Skan append_to_statement_list (pred, &expr); 2344169689Skan 2345169689Skan append_to_statement_list (then_, &expr); 2346169689Skan if (else_se) 2347169689Skan { 2348169689Skan if (jump_over_else) 2349169689Skan { 2350169689Skan t = build_and_jump (&end_label); 2351169689Skan append_to_statement_list (t, &expr); 2352169689Skan } 2353169689Skan if (emit_false) 2354169689Skan { 2355169689Skan t = build1 (LABEL_EXPR, void_type_node, false_label); 2356169689Skan append_to_statement_list (t, &expr); 2357169689Skan } 2358169689Skan append_to_statement_list (else_, &expr); 2359169689Skan } 2360169689Skan if (emit_end && end_label) 2361169689Skan { 2362169689Skan t = build1 (LABEL_EXPR, void_type_node, end_label); 2363169689Skan append_to_statement_list (t, &expr); 2364169689Skan } 2365169689Skan 2366169689Skan return expr; 2367169689Skan} 2368169689Skan 2369169689Skan/* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */ 2370169689Skan 2371169689Skantree 2372169689Skangimple_boolify (tree expr) 2373169689Skan{ 2374169689Skan tree type = TREE_TYPE (expr); 2375169689Skan 2376169689Skan if (TREE_CODE (type) == BOOLEAN_TYPE) 2377169689Skan return expr; 2378169689Skan 2379169689Skan switch (TREE_CODE (expr)) 2380169689Skan { 2381169689Skan case TRUTH_AND_EXPR: 2382169689Skan case TRUTH_OR_EXPR: 2383169689Skan case TRUTH_XOR_EXPR: 2384169689Skan case TRUTH_ANDIF_EXPR: 2385169689Skan case TRUTH_ORIF_EXPR: 2386169689Skan /* Also boolify the arguments of truth exprs. */ 2387169689Skan TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); 2388169689Skan /* FALLTHRU */ 2389169689Skan 2390169689Skan case TRUTH_NOT_EXPR: 2391169689Skan TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 2392169689Skan /* FALLTHRU */ 2393169689Skan 2394169689Skan case EQ_EXPR: case NE_EXPR: 2395169689Skan case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: 2396169689Skan /* These expressions always produce boolean results. */ 2397169689Skan TREE_TYPE (expr) = boolean_type_node; 2398169689Skan return expr; 2399169689Skan 2400169689Skan default: 2401169689Skan /* Other expressions that get here must have boolean values, but 2402169689Skan might need to be converted to the appropriate mode. */ 2403169689Skan return fold_convert (boolean_type_node, expr); 2404169689Skan } 2405169689Skan} 2406169689Skan 2407169689Skan/* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' 2408169689Skan into 2409169689Skan 2410169689Skan if (p) if (p) 2411169689Skan t1 = a; a; 2412169689Skan else or else 2413169689Skan t1 = b; b; 2414169689Skan t1; 2415169689Skan 2416169689Skan The second form is used when *EXPR_P is of type void. 2417169689Skan 2418169689Skan TARGET is the tree for T1 above. 2419169689Skan 2420169689Skan PRE_P points to the list where side effects that must happen before 2421169689Skan *EXPR_P should be stored. */ 2422169689Skan 2423169689Skanstatic enum gimplify_status 2424169689Skangimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback) 2425169689Skan{ 2426169689Skan tree expr = *expr_p; 2427169689Skan tree tmp, tmp2, type; 2428169689Skan enum gimplify_status ret; 2429169689Skan 2430169689Skan type = TREE_TYPE (expr); 2431169689Skan 2432169689Skan /* If this COND_EXPR has a value, copy the values into a temporary within 2433169689Skan the arms. */ 2434169689Skan if (! VOID_TYPE_P (type)) 2435169689Skan { 2436169689Skan tree result; 2437169689Skan 2438169689Skan if ((fallback & fb_lvalue) == 0) 2439169689Skan { 2440169689Skan result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp"); 2441169689Skan ret = GS_ALL_DONE; 2442169689Skan } 2443169689Skan else 2444169689Skan { 2445169689Skan tree type = build_pointer_type (TREE_TYPE (expr)); 2446169689Skan 2447169689Skan if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node) 2448169689Skan TREE_OPERAND (expr, 1) = 2449169689Skan build_fold_addr_expr (TREE_OPERAND (expr, 1)); 2450169689Skan 2451169689Skan if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) 2452169689Skan TREE_OPERAND (expr, 2) = 2453169689Skan build_fold_addr_expr (TREE_OPERAND (expr, 2)); 2454169689Skan 2455169689Skan tmp2 = tmp = create_tmp_var (type, "iftmp"); 2456169689Skan 2457169689Skan expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0), 2458169689Skan TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2)); 2459169689Skan 2460169689Skan result = build_fold_indirect_ref (tmp); 2461169689Skan ret = GS_ALL_DONE; 2462169689Skan } 2463169689Skan 2464169689Skan /* Build the then clause, 't1 = a;'. But don't build an assignment 2465169689Skan if this branch is void; in C++ it can be, if it's a throw. */ 2466169689Skan if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node) 2467169689Skan TREE_OPERAND (expr, 1) 2468169689Skan = build2 (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1)); 2469169689Skan 2470169689Skan /* Build the else clause, 't1 = b;'. */ 2471169689Skan if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) 2472169689Skan TREE_OPERAND (expr, 2) 2473169689Skan = build2 (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2)); 2474169689Skan 2475169689Skan TREE_TYPE (expr) = void_type_node; 2476169689Skan recalculate_side_effects (expr); 2477169689Skan 2478169689Skan /* Move the COND_EXPR to the prequeue. */ 2479169689Skan gimplify_and_add (expr, pre_p); 2480169689Skan 2481169689Skan *expr_p = result; 2482169689Skan return ret; 2483169689Skan } 2484169689Skan 2485169689Skan /* Make sure the condition has BOOLEAN_TYPE. */ 2486169689Skan TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 2487169689Skan 2488169689Skan /* Break apart && and || conditions. */ 2489169689Skan if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR 2490169689Skan || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR) 2491169689Skan { 2492169689Skan expr = shortcut_cond_expr (expr); 2493169689Skan 2494169689Skan if (expr != *expr_p) 2495169689Skan { 2496169689Skan *expr_p = expr; 2497169689Skan 2498169689Skan /* We can't rely on gimplify_expr to re-gimplify the expanded 2499169689Skan form properly, as cleanups might cause the target labels to be 2500169689Skan wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to 2501169689Skan set up a conditional context. */ 2502169689Skan gimple_push_condition (); 2503169689Skan gimplify_stmt (expr_p); 2504169689Skan gimple_pop_condition (pre_p); 2505169689Skan 2506169689Skan return GS_ALL_DONE; 2507169689Skan } 2508169689Skan } 2509169689Skan 2510169689Skan /* Now do the normal gimplification. */ 2511169689Skan ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, 2512169689Skan is_gimple_condexpr, fb_rvalue); 2513169689Skan 2514169689Skan gimple_push_condition (); 2515169689Skan 2516169689Skan gimplify_to_stmt_list (&TREE_OPERAND (expr, 1)); 2517169689Skan gimplify_to_stmt_list (&TREE_OPERAND (expr, 2)); 2518169689Skan recalculate_side_effects (expr); 2519169689Skan 2520169689Skan gimple_pop_condition (pre_p); 2521169689Skan 2522169689Skan if (ret == GS_ERROR) 2523169689Skan ; 2524169689Skan else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) 2525169689Skan ret = GS_ALL_DONE; 2526169689Skan else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))) 2527169689Skan /* Rewrite "if (a); else b" to "if (!a) b" */ 2528169689Skan { 2529169689Skan TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0)); 2530169689Skan ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, 2531169689Skan is_gimple_condexpr, fb_rvalue); 2532169689Skan 2533169689Skan tmp = TREE_OPERAND (expr, 1); 2534169689Skan TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2); 2535169689Skan TREE_OPERAND (expr, 2) = tmp; 2536169689Skan } 2537169689Skan else 2538169689Skan /* Both arms are empty; replace the COND_EXPR with its predicate. */ 2539169689Skan expr = TREE_OPERAND (expr, 0); 2540169689Skan 2541169689Skan *expr_p = expr; 2542169689Skan return ret; 2543169689Skan} 2544169689Skan 2545169689Skan/* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 2546169689Skan a call to __builtin_memcpy. */ 2547169689Skan 2548169689Skanstatic enum gimplify_status 2549169689Skangimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value) 2550169689Skan{ 2551169689Skan tree args, t, to, to_ptr, from; 2552169689Skan 2553169689Skan to = TREE_OPERAND (*expr_p, 0); 2554169689Skan from = TREE_OPERAND (*expr_p, 1); 2555169689Skan 2556169689Skan args = tree_cons (NULL, size, NULL); 2557169689Skan 2558169689Skan t = build_fold_addr_expr (from); 2559169689Skan args = tree_cons (NULL, t, args); 2560169689Skan 2561169689Skan to_ptr = build_fold_addr_expr (to); 2562169689Skan args = tree_cons (NULL, to_ptr, args); 2563169689Skan t = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2564169689Skan t = build_function_call_expr (t, args); 2565169689Skan 2566169689Skan if (want_value) 2567169689Skan { 2568169689Skan t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t); 2569169689Skan t = build1 (INDIRECT_REF, TREE_TYPE (to), t); 2570169689Skan } 2571169689Skan 2572169689Skan *expr_p = t; 2573169689Skan return GS_OK; 2574169689Skan} 2575169689Skan 2576169689Skan/* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 2577169689Skan a call to __builtin_memset. In this case we know that the RHS is 2578169689Skan a CONSTRUCTOR with an empty element list. */ 2579169689Skan 2580169689Skanstatic enum gimplify_status 2581169689Skangimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value) 2582169689Skan{ 2583169689Skan tree args, t, to, to_ptr; 2584169689Skan 2585169689Skan to = TREE_OPERAND (*expr_p, 0); 2586169689Skan 2587169689Skan args = tree_cons (NULL, size, NULL); 2588169689Skan 2589169689Skan args = tree_cons (NULL, integer_zero_node, args); 2590169689Skan 2591169689Skan to_ptr = build_fold_addr_expr (to); 2592169689Skan args = tree_cons (NULL, to_ptr, args); 2593169689Skan t = implicit_built_in_decls[BUILT_IN_MEMSET]; 2594169689Skan t = build_function_call_expr (t, args); 2595169689Skan 2596169689Skan if (want_value) 2597169689Skan { 2598169689Skan t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t); 2599169689Skan t = build1 (INDIRECT_REF, TREE_TYPE (to), t); 2600169689Skan } 2601169689Skan 2602169689Skan *expr_p = t; 2603169689Skan return GS_OK; 2604169689Skan} 2605169689Skan 2606169689Skan/* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree, 2607169689Skan determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an 2608169689Skan assignment. Returns non-null if we detect a potential overlap. */ 2609169689Skan 2610169689Skanstruct gimplify_init_ctor_preeval_data 2611169689Skan{ 2612169689Skan /* The base decl of the lhs object. May be NULL, in which case we 2613169689Skan have to assume the lhs is indirect. */ 2614169689Skan tree lhs_base_decl; 2615169689Skan 2616169689Skan /* The alias set of the lhs object. */ 2617169689Skan int lhs_alias_set; 2618169689Skan}; 2619169689Skan 2620169689Skanstatic tree 2621169689Skangimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata) 2622169689Skan{ 2623169689Skan struct gimplify_init_ctor_preeval_data *data 2624169689Skan = (struct gimplify_init_ctor_preeval_data *) xdata; 2625169689Skan tree t = *tp; 2626169689Skan 2627169689Skan /* If we find the base object, obviously we have overlap. */ 2628169689Skan if (data->lhs_base_decl == t) 2629169689Skan return t; 2630169689Skan 2631169689Skan /* If the constructor component is indirect, determine if we have a 2632169689Skan potential overlap with the lhs. The only bits of information we 2633169689Skan have to go on at this point are addressability and alias sets. */ 2634169689Skan if (TREE_CODE (t) == INDIRECT_REF 2635169689Skan && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 2636169689Skan && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t))) 2637169689Skan return t; 2638169689Skan 2639169689Skan /* If the constructor component is a call, determine if it can hide a 2640169689Skan potential overlap with the lhs through an INDIRECT_REF like above. */ 2641169689Skan if (TREE_CODE (t) == CALL_EXPR) 2642169689Skan { 2643169689Skan tree type, fntype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); 2644169689Skan 2645169689Skan for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type)) 2646169689Skan if (POINTER_TYPE_P (TREE_VALUE (type)) 2647169689Skan && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 2648169689Skan && alias_sets_conflict_p (data->lhs_alias_set, 2649169689Skan get_alias_set 2650169689Skan (TREE_TYPE (TREE_VALUE (type))))) 2651169689Skan return t; 2652169689Skan } 2653169689Skan 2654169689Skan if (IS_TYPE_OR_DECL_P (t)) 2655169689Skan *walk_subtrees = 0; 2656169689Skan return NULL; 2657169689Skan} 2658169689Skan 2659169689Skan/* A subroutine of gimplify_init_constructor. Pre-evaluate *EXPR_P, 2660169689Skan force values that overlap with the lhs (as described by *DATA) 2661169689Skan into temporaries. */ 2662169689Skan 2663169689Skanstatic void 2664169689Skangimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p, 2665169689Skan struct gimplify_init_ctor_preeval_data *data) 2666169689Skan{ 2667169689Skan enum gimplify_status one; 2668169689Skan 2669169689Skan /* If the value is invariant, then there's nothing to pre-evaluate. 2670169689Skan But ensure it doesn't have any side-effects since a SAVE_EXPR is 2671169689Skan invariant but has side effects and might contain a reference to 2672169689Skan the object we're initializing. */ 2673169689Skan if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p)) 2674169689Skan return; 2675169689Skan 2676169689Skan /* If the type has non-trivial constructors, we can't pre-evaluate. */ 2677169689Skan if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p))) 2678169689Skan return; 2679169689Skan 2680169689Skan /* Recurse for nested constructors. */ 2681169689Skan if (TREE_CODE (*expr_p) == CONSTRUCTOR) 2682169689Skan { 2683169689Skan unsigned HOST_WIDE_INT ix; 2684169689Skan constructor_elt *ce; 2685169689Skan VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (*expr_p); 2686169689Skan 2687169689Skan for (ix = 0; VEC_iterate (constructor_elt, v, ix, ce); ix++) 2688169689Skan gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data); 2689169689Skan return; 2690169689Skan } 2691169689Skan 2692169689Skan /* If this is a variable sized type, we must remember the size. */ 2693169689Skan maybe_with_size_expr (expr_p); 2694169689Skan 2695169689Skan /* Gimplify the constructor element to something appropriate for the rhs 2696169689Skan of a MODIFY_EXPR. Given that we know the lhs is an aggregate, we know 2697169689Skan the gimplifier will consider this a store to memory. Doing this 2698169689Skan gimplification now means that we won't have to deal with complicated 2699169689Skan language-specific trees, nor trees like SAVE_EXPR that can induce 2700169689Skan exponential search behavior. */ 2701169689Skan one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue); 2702169689Skan if (one == GS_ERROR) 2703169689Skan { 2704169689Skan *expr_p = NULL; 2705169689Skan return; 2706169689Skan } 2707169689Skan 2708169689Skan /* If we gimplified to a bare decl, we can be sure that it doesn't overlap 2709169689Skan with the lhs, since "a = { .x=a }" doesn't make sense. This will 2710169689Skan always be true for all scalars, since is_gimple_mem_rhs insists on a 2711169689Skan temporary variable for them. */ 2712169689Skan if (DECL_P (*expr_p)) 2713169689Skan return; 2714169689Skan 2715169689Skan /* If this is of variable size, we have no choice but to assume it doesn't 2716169689Skan overlap since we can't make a temporary for it. */ 2717169689Skan if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST) 2718169689Skan return; 2719169689Skan 2720169689Skan /* Otherwise, we must search for overlap ... */ 2721169689Skan if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL)) 2722169689Skan return; 2723169689Skan 2724169689Skan /* ... and if found, force the value into a temporary. */ 2725169689Skan *expr_p = get_formal_tmp_var (*expr_p, pre_p); 2726169689Skan} 2727169689Skan 2728169689Skan/* A subroutine of gimplify_init_ctor_eval. Create a loop for 2729169689Skan a RANGE_EXPR in a CONSTRUCTOR for an array. 2730169689Skan 2731169689Skan var = lower; 2732169689Skan loop_entry: 2733169689Skan object[var] = value; 2734169689Skan if (var == upper) 2735169689Skan goto loop_exit; 2736169689Skan var = var + 1; 2737169689Skan goto loop_entry; 2738169689Skan loop_exit: 2739169689Skan 2740169689Skan We increment var _after_ the loop exit check because we might otherwise 2741169689Skan fail if upper == TYPE_MAX_VALUE (type for upper). 2742169689Skan 2743169689Skan Note that we never have to deal with SAVE_EXPRs here, because this has 2744169689Skan already been taken care of for us, in gimplify_init_ctor_preeval(). */ 2745169689Skan 2746169689Skanstatic void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *, 2747169689Skan tree *, bool); 2748169689Skan 2749169689Skanstatic void 2750169689Skangimplify_init_ctor_eval_range (tree object, tree lower, tree upper, 2751169689Skan tree value, tree array_elt_type, 2752169689Skan tree *pre_p, bool cleared) 2753169689Skan{ 2754169689Skan tree loop_entry_label, loop_exit_label; 2755169689Skan tree var, var_type, cref; 2756169689Skan 2757169689Skan loop_entry_label = create_artificial_label (); 2758169689Skan loop_exit_label = create_artificial_label (); 2759169689Skan 2760169689Skan /* Create and initialize the index variable. */ 2761169689Skan var_type = TREE_TYPE (upper); 2762169689Skan var = create_tmp_var (var_type, NULL); 2763169689Skan append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p); 2764169689Skan 2765169689Skan /* Add the loop entry label. */ 2766169689Skan append_to_statement_list (build1 (LABEL_EXPR, 2767169689Skan void_type_node, 2768169689Skan loop_entry_label), 2769169689Skan pre_p); 2770169689Skan 2771169689Skan /* Build the reference. */ 2772169689Skan cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 2773169689Skan var, NULL_TREE, NULL_TREE); 2774169689Skan 2775169689Skan /* If we are a constructor, just call gimplify_init_ctor_eval to do 2776169689Skan the store. Otherwise just assign value to the reference. */ 2777169689Skan 2778169689Skan if (TREE_CODE (value) == CONSTRUCTOR) 2779169689Skan /* NB we might have to call ourself recursively through 2780169689Skan gimplify_init_ctor_eval if the value is a constructor. */ 2781169689Skan gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 2782169689Skan pre_p, cleared); 2783169689Skan else 2784169689Skan append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref), 2785169689Skan cref, value), 2786169689Skan pre_p); 2787169689Skan 2788169689Skan /* We exit the loop when the index var is equal to the upper bound. */ 2789169689Skan gimplify_and_add (build3 (COND_EXPR, void_type_node, 2790169689Skan build2 (EQ_EXPR, boolean_type_node, 2791169689Skan var, upper), 2792169689Skan build1 (GOTO_EXPR, 2793169689Skan void_type_node, 2794169689Skan loop_exit_label), 2795169689Skan NULL_TREE), 2796169689Skan pre_p); 2797169689Skan 2798169689Skan /* Otherwise, increment the index var... */ 2799169689Skan append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, 2800169689Skan build2 (PLUS_EXPR, var_type, var, 2801169689Skan fold_convert (var_type, 2802169689Skan integer_one_node))), 2803169689Skan pre_p); 2804169689Skan 2805169689Skan /* ...and jump back to the loop entry. */ 2806169689Skan append_to_statement_list (build1 (GOTO_EXPR, 2807169689Skan void_type_node, 2808169689Skan loop_entry_label), 2809169689Skan pre_p); 2810169689Skan 2811169689Skan /* Add the loop exit label. */ 2812169689Skan append_to_statement_list (build1 (LABEL_EXPR, 2813169689Skan void_type_node, 2814169689Skan loop_exit_label), 2815169689Skan pre_p); 2816169689Skan} 2817169689Skan 2818169689Skan/* Return true if FDECL is accessing a field that is zero sized. */ 2819169689Skan 2820169689Skanstatic bool 2821169689Skanzero_sized_field_decl (tree fdecl) 2822169689Skan{ 2823169689Skan if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl) 2824169689Skan && integer_zerop (DECL_SIZE (fdecl))) 2825169689Skan return true; 2826169689Skan return false; 2827169689Skan} 2828169689Skan 2829169689Skan/* Return true if TYPE is zero sized. */ 2830169689Skan 2831169689Skanstatic bool 2832169689Skanzero_sized_type (tree type) 2833169689Skan{ 2834169689Skan if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type) 2835169689Skan && integer_zerop (TYPE_SIZE (type))) 2836169689Skan return true; 2837169689Skan return false; 2838169689Skan} 2839169689Skan 2840169689Skan/* A subroutine of gimplify_init_constructor. Generate individual 2841169689Skan MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the 2842169689Skan assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the 2843169689Skan CONSTRUCTOR. CLEARED is true if the entire LHS object has been 2844169689Skan zeroed first. */ 2845169689Skan 2846169689Skanstatic void 2847169689Skangimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts, 2848169689Skan tree *pre_p, bool cleared) 2849169689Skan{ 2850169689Skan tree array_elt_type = NULL; 2851169689Skan unsigned HOST_WIDE_INT ix; 2852169689Skan tree purpose, value; 2853169689Skan 2854169689Skan if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE) 2855169689Skan array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object))); 2856169689Skan 2857169689Skan FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value) 2858169689Skan { 2859169689Skan tree cref, init; 2860169689Skan 2861169689Skan /* NULL values are created above for gimplification errors. */ 2862169689Skan if (value == NULL) 2863169689Skan continue; 2864169689Skan 2865169689Skan if (cleared && initializer_zerop (value)) 2866169689Skan continue; 2867169689Skan 2868169689Skan /* ??? Here's to hoping the front end fills in all of the indices, 2869169689Skan so we don't have to figure out what's missing ourselves. */ 2870169689Skan gcc_assert (purpose); 2871169689Skan 2872169689Skan /* Skip zero-sized fields, unless value has side-effects. This can 2873169689Skan happen with calls to functions returning a zero-sized type, which 2874169689Skan we shouldn't discard. As a number of downstream passes don't 2875169689Skan expect sets of zero-sized fields, we rely on the gimplification of 2876169689Skan the MODIFY_EXPR we make below to drop the assignment statement. */ 2877169689Skan if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose)) 2878169689Skan continue; 2879169689Skan 2880169689Skan /* If we have a RANGE_EXPR, we have to build a loop to assign the 2881169689Skan whole range. */ 2882169689Skan if (TREE_CODE (purpose) == RANGE_EXPR) 2883169689Skan { 2884169689Skan tree lower = TREE_OPERAND (purpose, 0); 2885169689Skan tree upper = TREE_OPERAND (purpose, 1); 2886169689Skan 2887169689Skan /* If the lower bound is equal to upper, just treat it as if 2888169689Skan upper was the index. */ 2889169689Skan if (simple_cst_equal (lower, upper)) 2890169689Skan purpose = upper; 2891169689Skan else 2892169689Skan { 2893169689Skan gimplify_init_ctor_eval_range (object, lower, upper, value, 2894169689Skan array_elt_type, pre_p, cleared); 2895169689Skan continue; 2896169689Skan } 2897169689Skan } 2898169689Skan 2899169689Skan if (array_elt_type) 2900169689Skan { 2901169689Skan cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 2902169689Skan purpose, NULL_TREE, NULL_TREE); 2903169689Skan } 2904169689Skan else 2905169689Skan { 2906169689Skan gcc_assert (TREE_CODE (purpose) == FIELD_DECL); 2907169689Skan cref = build3 (COMPONENT_REF, TREE_TYPE (purpose), 2908169689Skan unshare_expr (object), purpose, NULL_TREE); 2909169689Skan } 2910169689Skan 2911169689Skan if (TREE_CODE (value) == CONSTRUCTOR 2912169689Skan && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE) 2913169689Skan gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 2914169689Skan pre_p, cleared); 2915169689Skan else 2916169689Skan { 2917169689Skan init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); 2918169689Skan gimplify_and_add (init, pre_p); 2919169689Skan } 2920169689Skan } 2921169689Skan} 2922169689Skan 2923169689Skan/* A subroutine of gimplify_modify_expr. Break out elements of a 2924169689Skan CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs. 2925169689Skan 2926169689Skan Note that we still need to clear any elements that don't have explicit 2927169689Skan initializers, so if not all elements are initialized we keep the 2928169689Skan original MODIFY_EXPR, we just remove all of the constructor elements. */ 2929169689Skan 2930169689Skanstatic enum gimplify_status 2931169689Skangimplify_init_constructor (tree *expr_p, tree *pre_p, 2932169689Skan tree *post_p, bool want_value) 2933169689Skan{ 2934169689Skan tree object; 2935169689Skan tree ctor = TREE_OPERAND (*expr_p, 1); 2936169689Skan tree type = TREE_TYPE (ctor); 2937169689Skan enum gimplify_status ret; 2938169689Skan VEC(constructor_elt,gc) *elts; 2939169689Skan 2940169689Skan if (TREE_CODE (ctor) != CONSTRUCTOR) 2941169689Skan return GS_UNHANDLED; 2942169689Skan 2943169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 2944169689Skan is_gimple_lvalue, fb_lvalue); 2945169689Skan if (ret == GS_ERROR) 2946169689Skan return ret; 2947169689Skan object = TREE_OPERAND (*expr_p, 0); 2948169689Skan 2949169689Skan elts = CONSTRUCTOR_ELTS (ctor); 2950169689Skan 2951169689Skan ret = GS_ALL_DONE; 2952169689Skan switch (TREE_CODE (type)) 2953169689Skan { 2954169689Skan case RECORD_TYPE: 2955169689Skan case UNION_TYPE: 2956169689Skan case QUAL_UNION_TYPE: 2957169689Skan case ARRAY_TYPE: 2958169689Skan { 2959169689Skan struct gimplify_init_ctor_preeval_data preeval_data; 2960169689Skan HOST_WIDE_INT num_type_elements, num_ctor_elements; 2961169689Skan HOST_WIDE_INT num_nonzero_elements; 2962169689Skan bool cleared, valid_const_initializer; 2963169689Skan 2964169689Skan /* Aggregate types must lower constructors to initialization of 2965169689Skan individual elements. The exception is that a CONSTRUCTOR node 2966169689Skan with no elements indicates zero-initialization of the whole. */ 2967169689Skan if (VEC_empty (constructor_elt, elts)) 2968169689Skan break; 2969169689Skan 2970169689Skan /* Fetch information about the constructor to direct later processing. 2971169689Skan We might want to make static versions of it in various cases, and 2972169689Skan can only do so if it known to be a valid constant initializer. */ 2973169689Skan valid_const_initializer 2974169689Skan = categorize_ctor_elements (ctor, &num_nonzero_elements, 2975169689Skan &num_ctor_elements, &cleared); 2976169689Skan 2977169689Skan /* If a const aggregate variable is being initialized, then it 2978169689Skan should never be a lose to promote the variable to be static. */ 2979169689Skan if (valid_const_initializer 2980169689Skan && num_nonzero_elements > 1 2981169689Skan && TREE_READONLY (object) 2982169689Skan && TREE_CODE (object) == VAR_DECL) 2983169689Skan { 2984169689Skan DECL_INITIAL (object) = ctor; 2985169689Skan TREE_STATIC (object) = 1; 2986169689Skan if (!DECL_NAME (object)) 2987169689Skan DECL_NAME (object) = create_tmp_var_name ("C"); 2988169689Skan walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL); 2989169689Skan 2990169689Skan /* ??? C++ doesn't automatically append a .<number> to the 2991169689Skan assembler name, and even when it does, it looks a FE private 2992169689Skan data structures to figure out what that number should be, 2993169689Skan which are not set for this variable. I suppose this is 2994169689Skan important for local statics for inline functions, which aren't 2995169689Skan "local" in the object file sense. So in order to get a unique 2996169689Skan TU-local symbol, we must invoke the lhd version now. */ 2997169689Skan lhd_set_decl_assembler_name (object); 2998169689Skan 2999169689Skan *expr_p = NULL_TREE; 3000169689Skan break; 3001169689Skan } 3002169689Skan 3003169689Skan /* If there are "lots" of initialized elements, even discounting 3004169689Skan those that are not address constants (and thus *must* be 3005169689Skan computed at runtime), then partition the constructor into 3006169689Skan constant and non-constant parts. Block copy the constant 3007169689Skan parts in, then generate code for the non-constant parts. */ 3008169689Skan /* TODO. There's code in cp/typeck.c to do this. */ 3009169689Skan 3010169689Skan num_type_elements = count_type_elements (type, true); 3011169689Skan 3012169689Skan /* If count_type_elements could not determine number of type elements 3013169689Skan for a constant-sized object, assume clearing is needed. 3014169689Skan Don't do this for variable-sized objects, as store_constructor 3015169689Skan will ignore the clearing of variable-sized objects. */ 3016169689Skan if (num_type_elements < 0 && int_size_in_bytes (type) >= 0) 3017169689Skan cleared = true; 3018169689Skan /* If there are "lots" of zeros, then block clear the object first. */ 3019169689Skan else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO 3020169689Skan && num_nonzero_elements < num_type_elements/4) 3021169689Skan cleared = true; 3022169689Skan /* ??? This bit ought not be needed. For any element not present 3023169689Skan in the initializer, we should simply set them to zero. Except 3024169689Skan we'd need to *find* the elements that are not present, and that 3025169689Skan requires trickery to avoid quadratic compile-time behavior in 3026169689Skan large cases or excessive memory use in small cases. */ 3027169689Skan else if (num_ctor_elements < num_type_elements) 3028169689Skan cleared = true; 3029169689Skan 3030169689Skan /* If there are "lots" of initialized elements, and all of them 3031169689Skan are valid address constants, then the entire initializer can 3032169689Skan be dropped to memory, and then memcpy'd out. Don't do this 3033169689Skan for sparse arrays, though, as it's more efficient to follow 3034169689Skan the standard CONSTRUCTOR behavior of memset followed by 3035169689Skan individual element initialization. */ 3036169689Skan if (valid_const_initializer && !cleared) 3037169689Skan { 3038169689Skan HOST_WIDE_INT size = int_size_in_bytes (type); 3039169689Skan unsigned int align; 3040169689Skan 3041169689Skan /* ??? We can still get unbounded array types, at least 3042169689Skan from the C++ front end. This seems wrong, but attempt 3043169689Skan to work around it for now. */ 3044169689Skan if (size < 0) 3045169689Skan { 3046169689Skan size = int_size_in_bytes (TREE_TYPE (object)); 3047169689Skan if (size >= 0) 3048169689Skan TREE_TYPE (ctor) = type = TREE_TYPE (object); 3049169689Skan } 3050169689Skan 3051169689Skan /* Find the maximum alignment we can assume for the object. */ 3052169689Skan /* ??? Make use of DECL_OFFSET_ALIGN. */ 3053169689Skan if (DECL_P (object)) 3054169689Skan align = DECL_ALIGN (object); 3055169689Skan else 3056169689Skan align = TYPE_ALIGN (type); 3057169689Skan 3058169689Skan if (size > 0 && !can_move_by_pieces (size, align)) 3059169689Skan { 3060169689Skan tree new = create_tmp_var_raw (type, "C"); 3061169689Skan 3062169689Skan gimple_add_tmp_var (new); 3063169689Skan TREE_STATIC (new) = 1; 3064169689Skan TREE_READONLY (new) = 1; 3065169689Skan DECL_INITIAL (new) = ctor; 3066169689Skan if (align > DECL_ALIGN (new)) 3067169689Skan { 3068169689Skan DECL_ALIGN (new) = align; 3069169689Skan DECL_USER_ALIGN (new) = 1; 3070169689Skan } 3071169689Skan walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL); 3072169689Skan 3073169689Skan TREE_OPERAND (*expr_p, 1) = new; 3074169689Skan 3075169689Skan /* This is no longer an assignment of a CONSTRUCTOR, but 3076169689Skan we still may have processing to do on the LHS. So 3077169689Skan pretend we didn't do anything here to let that happen. */ 3078169689Skan return GS_UNHANDLED; 3079169689Skan } 3080169689Skan } 3081169689Skan 3082169689Skan /* If there are nonzero elements, pre-evaluate to capture elements 3083169689Skan overlapping with the lhs into temporaries. We must do this before 3084169689Skan clearing to fetch the values before they are zeroed-out. */ 3085169689Skan if (num_nonzero_elements > 0) 3086169689Skan { 3087169689Skan preeval_data.lhs_base_decl = get_base_address (object); 3088169689Skan if (!DECL_P (preeval_data.lhs_base_decl)) 3089169689Skan preeval_data.lhs_base_decl = NULL; 3090169689Skan preeval_data.lhs_alias_set = get_alias_set (object); 3091169689Skan 3092169689Skan gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1), 3093169689Skan pre_p, post_p, &preeval_data); 3094169689Skan } 3095169689Skan 3096169689Skan if (cleared) 3097169689Skan { 3098169689Skan /* Zap the CONSTRUCTOR element list, which simplifies this case. 3099169689Skan Note that we still have to gimplify, in order to handle the 3100169689Skan case of variable sized types. Avoid shared tree structures. */ 3101169689Skan CONSTRUCTOR_ELTS (ctor) = NULL; 3102169689Skan object = unshare_expr (object); 3103169689Skan gimplify_stmt (expr_p); 3104169689Skan append_to_statement_list (*expr_p, pre_p); 3105169689Skan } 3106169689Skan 3107169689Skan /* If we have not block cleared the object, or if there are nonzero 3108169689Skan elements in the constructor, add assignments to the individual 3109169689Skan scalar fields of the object. */ 3110169689Skan if (!cleared || num_nonzero_elements > 0) 3111169689Skan gimplify_init_ctor_eval (object, elts, pre_p, cleared); 3112169689Skan 3113169689Skan *expr_p = NULL_TREE; 3114169689Skan } 3115169689Skan break; 3116169689Skan 3117169689Skan case COMPLEX_TYPE: 3118169689Skan { 3119169689Skan tree r, i; 3120169689Skan 3121169689Skan /* Extract the real and imaginary parts out of the ctor. */ 3122169689Skan gcc_assert (VEC_length (constructor_elt, elts) == 2); 3123169689Skan r = VEC_index (constructor_elt, elts, 0)->value; 3124169689Skan i = VEC_index (constructor_elt, elts, 1)->value; 3125169689Skan if (r == NULL || i == NULL) 3126169689Skan { 3127169689Skan tree zero = fold_convert (TREE_TYPE (type), integer_zero_node); 3128169689Skan if (r == NULL) 3129169689Skan r = zero; 3130169689Skan if (i == NULL) 3131169689Skan i = zero; 3132169689Skan } 3133169689Skan 3134169689Skan /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to 3135169689Skan represent creation of a complex value. */ 3136169689Skan if (TREE_CONSTANT (r) && TREE_CONSTANT (i)) 3137169689Skan { 3138169689Skan ctor = build_complex (type, r, i); 3139169689Skan TREE_OPERAND (*expr_p, 1) = ctor; 3140169689Skan } 3141169689Skan else 3142169689Skan { 3143169689Skan ctor = build2 (COMPLEX_EXPR, type, r, i); 3144169689Skan TREE_OPERAND (*expr_p, 1) = ctor; 3145169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 3146169689Skan rhs_predicate_for (TREE_OPERAND (*expr_p, 0)), 3147169689Skan fb_rvalue); 3148169689Skan } 3149169689Skan } 3150169689Skan break; 3151169689Skan 3152169689Skan case VECTOR_TYPE: 3153169689Skan { 3154169689Skan unsigned HOST_WIDE_INT ix; 3155169689Skan constructor_elt *ce; 3156169689Skan 3157169689Skan /* Go ahead and simplify constant constructors to VECTOR_CST. */ 3158169689Skan if (TREE_CONSTANT (ctor)) 3159169689Skan { 3160169689Skan bool constant_p = true; 3161169689Skan tree value; 3162169689Skan 3163169689Skan /* Even when ctor is constant, it might contain non-*_CST 3164169689Skan elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't 3165169689Skan belong into VECTOR_CST nodes. */ 3166169689Skan FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value) 3167169689Skan if (!CONSTANT_CLASS_P (value)) 3168169689Skan { 3169169689Skan constant_p = false; 3170169689Skan break; 3171169689Skan } 3172169689Skan 3173169689Skan if (constant_p) 3174169689Skan { 3175169689Skan TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts); 3176169689Skan break; 3177169689Skan } 3178169689Skan 3179169689Skan /* Don't reduce a TREE_CONSTANT vector ctor even if we can't 3180169689Skan make a VECTOR_CST. It won't do anything for us, and it'll 3181169689Skan prevent us from representing it as a single constant. */ 3182169689Skan break; 3183169689Skan } 3184169689Skan 3185169689Skan /* Vector types use CONSTRUCTOR all the way through gimple 3186169689Skan compilation as a general initializer. */ 3187169689Skan for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++) 3188169689Skan { 3189169689Skan enum gimplify_status tret; 3190169689Skan tret = gimplify_expr (&ce->value, pre_p, post_p, 3191169689Skan is_gimple_val, fb_rvalue); 3192169689Skan if (tret == GS_ERROR) 3193169689Skan ret = GS_ERROR; 3194169689Skan } 3195169689Skan } 3196169689Skan break; 3197169689Skan 3198169689Skan default: 3199169689Skan /* So how did we get a CONSTRUCTOR for a scalar type? */ 3200169689Skan gcc_unreachable (); 3201169689Skan } 3202169689Skan 3203169689Skan if (ret == GS_ERROR) 3204169689Skan return GS_ERROR; 3205169689Skan else if (want_value) 3206169689Skan { 3207169689Skan append_to_statement_list (*expr_p, pre_p); 3208169689Skan *expr_p = object; 3209169689Skan return GS_OK; 3210169689Skan } 3211169689Skan else 3212169689Skan return GS_ALL_DONE; 3213169689Skan} 3214169689Skan 3215169689Skan/* Given a pointer value OP0, return a simplified version of an 3216169689Skan indirection through OP0, or NULL_TREE if no simplification is 3217169689Skan possible. This may only be applied to a rhs of an expression. 3218169689Skan Note that the resulting type may be different from the type pointed 3219169689Skan to in the sense that it is still compatible from the langhooks 3220169689Skan point of view. */ 3221169689Skan 3222169689Skanstatic tree 3223169689Skanfold_indirect_ref_rhs (tree t) 3224169689Skan{ 3225169689Skan tree type = TREE_TYPE (TREE_TYPE (t)); 3226169689Skan tree sub = t; 3227169689Skan tree subtype; 3228169689Skan 3229169689Skan STRIP_USELESS_TYPE_CONVERSION (sub); 3230169689Skan subtype = TREE_TYPE (sub); 3231169689Skan if (!POINTER_TYPE_P (subtype)) 3232169689Skan return NULL_TREE; 3233169689Skan 3234169689Skan if (TREE_CODE (sub) == ADDR_EXPR) 3235169689Skan { 3236169689Skan tree op = TREE_OPERAND (sub, 0); 3237169689Skan tree optype = TREE_TYPE (op); 3238169689Skan /* *&p => p */ 3239169689Skan if (lang_hooks.types_compatible_p (type, optype)) 3240169689Skan return op; 3241169689Skan /* *(foo *)&fooarray => fooarray[0] */ 3242169689Skan else if (TREE_CODE (optype) == ARRAY_TYPE 3243169689Skan && lang_hooks.types_compatible_p (type, TREE_TYPE (optype))) 3244169689Skan { 3245169689Skan tree type_domain = TYPE_DOMAIN (optype); 3246169689Skan tree min_val = size_zero_node; 3247169689Skan if (type_domain && TYPE_MIN_VALUE (type_domain)) 3248169689Skan min_val = TYPE_MIN_VALUE (type_domain); 3249169689Skan return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE); 3250169689Skan } 3251169689Skan } 3252169689Skan 3253169689Skan /* *(foo *)fooarrptr => (*fooarrptr)[0] */ 3254169689Skan if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE 3255169689Skan && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype)))) 3256169689Skan { 3257169689Skan tree type_domain; 3258169689Skan tree min_val = size_zero_node; 3259169689Skan tree osub = sub; 3260169689Skan sub = fold_indirect_ref_rhs (sub); 3261169689Skan if (! sub) 3262169689Skan sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub); 3263169689Skan type_domain = TYPE_DOMAIN (TREE_TYPE (sub)); 3264169689Skan if (type_domain && TYPE_MIN_VALUE (type_domain)) 3265169689Skan min_val = TYPE_MIN_VALUE (type_domain); 3266169689Skan return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE); 3267169689Skan } 3268169689Skan 3269169689Skan return NULL_TREE; 3270169689Skan} 3271169689Skan 3272169689Skan/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs 3273169689Skan based on the code of the RHS. We loop for as long as something changes. */ 3274169689Skan 3275169689Skanstatic enum gimplify_status 3276169689Skangimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, 3277169689Skan tree *post_p, bool want_value) 3278169689Skan{ 3279169689Skan enum gimplify_status ret = GS_OK; 3280169689Skan 3281169689Skan while (ret != GS_UNHANDLED) 3282169689Skan switch (TREE_CODE (*from_p)) 3283169689Skan { 3284169689Skan case INDIRECT_REF: 3285169689Skan { 3286169689Skan /* If we have code like 3287169689Skan 3288169689Skan *(const A*)(A*)&x 3289169689Skan 3290169689Skan where the type of "x" is a (possibly cv-qualified variant 3291169689Skan of "A"), treat the entire expression as identical to "x". 3292169689Skan This kind of code arises in C++ when an object is bound 3293169689Skan to a const reference, and if "x" is a TARGET_EXPR we want 3294169689Skan to take advantage of the optimization below. */ 3295169689Skan tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)); 3296169689Skan if (t) 3297169689Skan { 3298169689Skan *from_p = t; 3299169689Skan ret = GS_OK; 3300169689Skan } 3301169689Skan else 3302169689Skan ret = GS_UNHANDLED; 3303169689Skan break; 3304169689Skan } 3305169689Skan 3306169689Skan case TARGET_EXPR: 3307169689Skan { 3308169689Skan /* If we are initializing something from a TARGET_EXPR, strip the 3309169689Skan TARGET_EXPR and initialize it directly, if possible. This can't 3310169689Skan be done if the initializer is void, since that implies that the 3311169689Skan temporary is set in some non-trivial way. 3312169689Skan 3313169689Skan ??? What about code that pulls out the temp and uses it 3314169689Skan elsewhere? I think that such code never uses the TARGET_EXPR as 3315169689Skan an initializer. If I'm wrong, we'll die because the temp won't 3316169689Skan have any RTL. In that case, I guess we'll need to replace 3317169689Skan references somehow. */ 3318169689Skan tree init = TARGET_EXPR_INITIAL (*from_p); 3319169689Skan 3320169689Skan if (!VOID_TYPE_P (TREE_TYPE (init))) 3321169689Skan { 3322169689Skan *from_p = init; 3323169689Skan ret = GS_OK; 3324169689Skan } 3325169689Skan else 3326169689Skan ret = GS_UNHANDLED; 3327169689Skan } 3328169689Skan break; 3329169689Skan 3330169689Skan case COMPOUND_EXPR: 3331169689Skan /* Remove any COMPOUND_EXPR in the RHS so the following cases will be 3332169689Skan caught. */ 3333169689Skan gimplify_compound_expr (from_p, pre_p, true); 3334169689Skan ret = GS_OK; 3335169689Skan break; 3336169689Skan 3337169689Skan case CONSTRUCTOR: 3338169689Skan /* If we're initializing from a CONSTRUCTOR, break this into 3339169689Skan individual MODIFY_EXPRs. */ 3340169689Skan return gimplify_init_constructor (expr_p, pre_p, post_p, want_value); 3341169689Skan 3342169689Skan case COND_EXPR: 3343169689Skan /* If we're assigning to a non-register type, push the assignment 3344169689Skan down into the branches. This is mandatory for ADDRESSABLE types, 3345169689Skan since we cannot generate temporaries for such, but it saves a 3346169689Skan copy in other cases as well. */ 3347169689Skan if (!is_gimple_reg_type (TREE_TYPE (*from_p))) 3348169689Skan { 3349169689Skan /* This code should mirror the code in gimplify_cond_expr. */ 3350169689Skan enum tree_code code = TREE_CODE (*expr_p); 3351169689Skan tree cond = *from_p; 3352169689Skan tree result = *to_p; 3353169689Skan 3354169689Skan ret = gimplify_expr (&result, pre_p, post_p, 3355169689Skan is_gimple_min_lval, fb_lvalue); 3356169689Skan if (ret != GS_ERROR) 3357169689Skan ret = GS_OK; 3358169689Skan 3359169689Skan if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node) 3360169689Skan TREE_OPERAND (cond, 1) 3361169689Skan = build2 (code, void_type_node, result, 3362169689Skan TREE_OPERAND (cond, 1)); 3363169689Skan if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) 3364169689Skan TREE_OPERAND (cond, 2) 3365169689Skan = build2 (code, void_type_node, unshare_expr (result), 3366169689Skan TREE_OPERAND (cond, 2)); 3367169689Skan 3368169689Skan TREE_TYPE (cond) = void_type_node; 3369169689Skan recalculate_side_effects (cond); 3370169689Skan 3371169689Skan if (want_value) 3372169689Skan { 3373169689Skan gimplify_and_add (cond, pre_p); 3374169689Skan *expr_p = unshare_expr (result); 3375169689Skan } 3376169689Skan else 3377169689Skan *expr_p = cond; 3378169689Skan return ret; 3379169689Skan } 3380169689Skan else 3381169689Skan ret = GS_UNHANDLED; 3382169689Skan break; 3383169689Skan 3384169689Skan case CALL_EXPR: 3385169689Skan /* For calls that return in memory, give *to_p as the CALL_EXPR's 3386169689Skan return slot so that we don't generate a temporary. */ 3387169689Skan if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p) 3388169689Skan && aggregate_value_p (*from_p, *from_p)) 3389169689Skan { 3390169689Skan bool use_target; 3391169689Skan 3392169689Skan if (!(rhs_predicate_for (*to_p))(*from_p)) 3393169689Skan /* If we need a temporary, *to_p isn't accurate. */ 3394169689Skan use_target = false; 3395169689Skan else if (TREE_CODE (*to_p) == RESULT_DECL 3396169689Skan && DECL_NAME (*to_p) == NULL_TREE 3397169689Skan && needs_to_live_in_memory (*to_p)) 3398169689Skan /* It's OK to use the return slot directly unless it's an NRV. */ 3399169689Skan use_target = true; 3400169689Skan else if (is_gimple_reg_type (TREE_TYPE (*to_p)) 3401169689Skan || (DECL_P (*to_p) && DECL_REGISTER (*to_p))) 3402169689Skan /* Don't force regs into memory. */ 3403169689Skan use_target = false; 3404169689Skan else if (TREE_CODE (*to_p) == VAR_DECL 3405169689Skan && DECL_GIMPLE_FORMAL_TEMP_P (*to_p)) 3406169689Skan /* Don't use the original target if it's a formal temp; we 3407169689Skan don't want to take their addresses. */ 3408169689Skan use_target = false; 3409169689Skan else if (TREE_CODE (*expr_p) == INIT_EXPR) 3410169689Skan /* It's OK to use the target directly if it's being 3411169689Skan initialized. */ 3412169689Skan use_target = true; 3413169689Skan else if (!is_gimple_non_addressable (*to_p)) 3414169689Skan /* Don't use the original target if it's already addressable; 3415169689Skan if its address escapes, and the called function uses the 3416169689Skan NRV optimization, a conforming program could see *to_p 3417169689Skan change before the called function returns; see c++/19317. 3418169689Skan When optimizing, the return_slot pass marks more functions 3419169689Skan as safe after we have escape info. */ 3420169689Skan use_target = false; 3421169689Skan else 3422169689Skan use_target = true; 3423169689Skan 3424169689Skan if (use_target) 3425169689Skan { 3426169689Skan CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1; 3427169689Skan lang_hooks.mark_addressable (*to_p); 3428169689Skan } 3429169689Skan } 3430169689Skan 3431169689Skan ret = GS_UNHANDLED; 3432169689Skan break; 3433169689Skan 3434169689Skan /* If we're initializing from a container, push the initialization 3435169689Skan inside it. */ 3436169689Skan case CLEANUP_POINT_EXPR: 3437169689Skan case BIND_EXPR: 3438169689Skan case STATEMENT_LIST: 3439169689Skan { 3440169689Skan tree wrap = *from_p; 3441169689Skan tree t; 3442169689Skan 3443169689Skan ret = gimplify_expr (to_p, pre_p, post_p, 3444169689Skan is_gimple_min_lval, fb_lvalue); 3445169689Skan if (ret != GS_ERROR) 3446169689Skan ret = GS_OK; 3447169689Skan 3448169689Skan t = voidify_wrapper_expr (wrap, *expr_p); 3449169689Skan gcc_assert (t == *expr_p); 3450169689Skan 3451169689Skan if (want_value) 3452169689Skan { 3453169689Skan gimplify_and_add (wrap, pre_p); 3454169689Skan *expr_p = unshare_expr (*to_p); 3455169689Skan } 3456169689Skan else 3457169689Skan *expr_p = wrap; 3458169689Skan return GS_OK; 3459169689Skan } 3460169689Skan 3461169689Skan default: 3462169689Skan ret = GS_UNHANDLED; 3463169689Skan break; 3464169689Skan } 3465169689Skan 3466169689Skan return ret; 3467169689Skan} 3468169689Skan 3469169689Skan/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is 3470169689Skan a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with 3471169689Skan DECL_COMPLEX_GIMPLE_REG_P set. */ 3472169689Skan 3473169689Skanstatic enum gimplify_status 3474169689Skangimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value) 3475169689Skan{ 3476169689Skan enum tree_code code, ocode; 3477169689Skan tree lhs, rhs, new_rhs, other, realpart, imagpart; 3478169689Skan 3479169689Skan lhs = TREE_OPERAND (*expr_p, 0); 3480169689Skan rhs = TREE_OPERAND (*expr_p, 1); 3481169689Skan code = TREE_CODE (lhs); 3482169689Skan lhs = TREE_OPERAND (lhs, 0); 3483169689Skan 3484169689Skan ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; 3485169689Skan other = build1 (ocode, TREE_TYPE (rhs), lhs); 3486169689Skan other = get_formal_tmp_var (other, pre_p); 3487169689Skan 3488169689Skan realpart = code == REALPART_EXPR ? rhs : other; 3489169689Skan imagpart = code == REALPART_EXPR ? other : rhs; 3490169689Skan 3491169689Skan if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart)) 3492169689Skan new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart); 3493169689Skan else 3494169689Skan new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart); 3495169689Skan 3496169689Skan TREE_OPERAND (*expr_p, 0) = lhs; 3497169689Skan TREE_OPERAND (*expr_p, 1) = new_rhs; 3498169689Skan 3499169689Skan if (want_value) 3500169689Skan { 3501169689Skan append_to_statement_list (*expr_p, pre_p); 3502169689Skan *expr_p = rhs; 3503169689Skan } 3504169689Skan 3505169689Skan return GS_ALL_DONE; 3506169689Skan} 3507169689Skan 3508169689Skan/* Gimplify the MODIFY_EXPR node pointed to by EXPR_P. 3509169689Skan 3510169689Skan modify_expr 3511169689Skan : varname '=' rhs 3512169689Skan | '*' ID '=' rhs 3513169689Skan 3514169689Skan PRE_P points to the list where side effects that must happen before 3515169689Skan *EXPR_P should be stored. 3516169689Skan 3517169689Skan POST_P points to the list where side effects that must happen after 3518169689Skan *EXPR_P should be stored. 3519169689Skan 3520169689Skan WANT_VALUE is nonzero iff we want to use the value of this expression 3521169689Skan in another expression. */ 3522169689Skan 3523169689Skanstatic enum gimplify_status 3524169689Skangimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) 3525169689Skan{ 3526169689Skan tree *from_p = &TREE_OPERAND (*expr_p, 1); 3527169689Skan tree *to_p = &TREE_OPERAND (*expr_p, 0); 3528169689Skan enum gimplify_status ret = GS_UNHANDLED; 3529169689Skan 3530169689Skan gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR 3531169689Skan || TREE_CODE (*expr_p) == INIT_EXPR); 3532169689Skan 3533220150Smm /* See if any simplifications can be done based on what the RHS is. */ 3534220150Smm ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 3535220150Smm want_value); 3536220150Smm if (ret != GS_UNHANDLED) 3537220150Smm return ret; 3538220150Smm 3539220150Smm /* For zero sized types only gimplify the left hand side and right hand 3540220150Smm side as statements and throw away the assignment. Do this after 3541220150Smm gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable 3542220150Smm types properly. */ 3543169689Skan if (zero_sized_type (TREE_TYPE (*from_p))) 3544169689Skan { 3545169689Skan gimplify_stmt (from_p); 3546169689Skan gimplify_stmt (to_p); 3547169689Skan append_to_statement_list (*from_p, pre_p); 3548169689Skan append_to_statement_list (*to_p, pre_p); 3549169689Skan *expr_p = NULL_TREE; 3550169689Skan return GS_ALL_DONE; 3551169689Skan } 3552169689Skan 3553169689Skan /* If the value being copied is of variable width, compute the length 3554169689Skan of the copy into a WITH_SIZE_EXPR. Note that we need to do this 3555169689Skan before gimplifying any of the operands so that we can resolve any 3556169689Skan PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses 3557169689Skan the size of the expression to be copied, not of the destination, so 3558169689Skan that is what we must here. */ 3559169689Skan maybe_with_size_expr (from_p); 3560169689Skan 3561169689Skan ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 3562169689Skan if (ret == GS_ERROR) 3563169689Skan return ret; 3564169689Skan 3565169689Skan ret = gimplify_expr (from_p, pre_p, post_p, 3566169689Skan rhs_predicate_for (*to_p), fb_rvalue); 3567169689Skan if (ret == GS_ERROR) 3568169689Skan return ret; 3569169689Skan 3570169689Skan /* Now see if the above changed *from_p to something we handle specially. */ 3571169689Skan ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 3572169689Skan want_value); 3573169689Skan if (ret != GS_UNHANDLED) 3574169689Skan return ret; 3575169689Skan 3576169689Skan /* If we've got a variable sized assignment between two lvalues (i.e. does 3577169689Skan not involve a call), then we can make things a bit more straightforward 3578169689Skan by converting the assignment to memcpy or memset. */ 3579169689Skan if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) 3580169689Skan { 3581169689Skan tree from = TREE_OPERAND (*from_p, 0); 3582169689Skan tree size = TREE_OPERAND (*from_p, 1); 3583169689Skan 3584169689Skan if (TREE_CODE (from) == CONSTRUCTOR) 3585169689Skan return gimplify_modify_expr_to_memset (expr_p, size, want_value); 3586169689Skan if (is_gimple_addressable (from)) 3587169689Skan { 3588169689Skan *from_p = from; 3589169689Skan return gimplify_modify_expr_to_memcpy (expr_p, size, want_value); 3590169689Skan } 3591169689Skan } 3592169689Skan 3593169689Skan /* Transform partial stores to non-addressable complex variables into 3594169689Skan total stores. This allows us to use real instead of virtual operands 3595169689Skan for these variables, which improves optimization. */ 3596169689Skan if ((TREE_CODE (*to_p) == REALPART_EXPR 3597169689Skan || TREE_CODE (*to_p) == IMAGPART_EXPR) 3598169689Skan && is_gimple_reg (TREE_OPERAND (*to_p, 0))) 3599169689Skan return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); 3600169689Skan 3601169689Skan if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) 3602169689Skan { 3603169689Skan /* If we've somehow already got an SSA_NAME on the LHS, then 3604169689Skan we're probably modified it twice. Not good. */ 3605169689Skan gcc_assert (TREE_CODE (*to_p) != SSA_NAME); 3606169689Skan *to_p = make_ssa_name (*to_p, *expr_p); 3607169689Skan } 3608169689Skan 3609169689Skan if (want_value) 3610169689Skan { 3611169689Skan append_to_statement_list (*expr_p, pre_p); 3612169689Skan *expr_p = *to_p; 3613169689Skan return GS_OK; 3614169689Skan } 3615169689Skan 3616169689Skan return GS_ALL_DONE; 3617169689Skan} 3618169689Skan 3619169689Skan/* Gimplify a comparison between two variable-sized objects. Do this 3620169689Skan with a call to BUILT_IN_MEMCMP. */ 3621169689Skan 3622169689Skanstatic enum gimplify_status 3623169689Skangimplify_variable_sized_compare (tree *expr_p) 3624169689Skan{ 3625169689Skan tree op0 = TREE_OPERAND (*expr_p, 0); 3626169689Skan tree op1 = TREE_OPERAND (*expr_p, 1); 3627169689Skan tree args, t, dest; 3628169689Skan 3629169689Skan t = TYPE_SIZE_UNIT (TREE_TYPE (op0)); 3630169689Skan t = unshare_expr (t); 3631169689Skan t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0); 3632169689Skan args = tree_cons (NULL, t, NULL); 3633169689Skan t = build_fold_addr_expr (op1); 3634169689Skan args = tree_cons (NULL, t, args); 3635169689Skan dest = build_fold_addr_expr (op0); 3636169689Skan args = tree_cons (NULL, dest, args); 3637169689Skan t = implicit_built_in_decls[BUILT_IN_MEMCMP]; 3638169689Skan t = build_function_call_expr (t, args); 3639169689Skan *expr_p 3640169689Skan = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node); 3641169689Skan 3642169689Skan return GS_OK; 3643169689Skan} 3644169689Skan 3645169689Skan/* Gimplify a comparison between two aggregate objects of integral scalar 3646169689Skan mode as a comparison between the bitwise equivalent scalar values. */ 3647169689Skan 3648169689Skanstatic enum gimplify_status 3649169689Skangimplify_scalar_mode_aggregate_compare (tree *expr_p) 3650169689Skan{ 3651169689Skan tree op0 = TREE_OPERAND (*expr_p, 0); 3652169689Skan tree op1 = TREE_OPERAND (*expr_p, 1); 3653169689Skan 3654169689Skan tree type = TREE_TYPE (op0); 3655169689Skan tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1); 3656169689Skan 3657169689Skan op0 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op0); 3658169689Skan op1 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op1); 3659169689Skan 3660169689Skan *expr_p 3661169689Skan = fold_build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1); 3662169689Skan 3663169689Skan return GS_OK; 3664169689Skan} 3665169689Skan 3666169689Skan/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P 3667169689Skan points to the expression to gimplify. 3668169689Skan 3669169689Skan Expressions of the form 'a && b' are gimplified to: 3670169689Skan 3671169689Skan a && b ? true : false 3672169689Skan 3673169689Skan gimplify_cond_expr will do the rest. 3674169689Skan 3675169689Skan PRE_P points to the list where side effects that must happen before 3676169689Skan *EXPR_P should be stored. */ 3677169689Skan 3678169689Skanstatic enum gimplify_status 3679169689Skangimplify_boolean_expr (tree *expr_p) 3680169689Skan{ 3681169689Skan /* Preserve the original type of the expression. */ 3682169689Skan tree type = TREE_TYPE (*expr_p); 3683169689Skan 3684169689Skan *expr_p = build3 (COND_EXPR, type, *expr_p, 3685169689Skan fold_convert (type, boolean_true_node), 3686169689Skan fold_convert (type, boolean_false_node)); 3687169689Skan 3688169689Skan return GS_OK; 3689169689Skan} 3690169689Skan 3691169689Skan/* Gimplifies an expression sequence. This function gimplifies each 3692169689Skan expression and re-writes the original expression with the last 3693169689Skan expression of the sequence in GIMPLE form. 3694169689Skan 3695169689Skan PRE_P points to the list where the side effects for all the 3696169689Skan expressions in the sequence will be emitted. 3697169689Skan 3698169689Skan WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */ 3699169689Skan/* ??? Should rearrange to share the pre-queue with all the indirect 3700169689Skan invocations of gimplify_expr. Would probably save on creations 3701169689Skan of statement_list nodes. */ 3702169689Skan 3703169689Skanstatic enum gimplify_status 3704169689Skangimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value) 3705169689Skan{ 3706169689Skan tree t = *expr_p; 3707169689Skan 3708169689Skan do 3709169689Skan { 3710169689Skan tree *sub_p = &TREE_OPERAND (t, 0); 3711169689Skan 3712169689Skan if (TREE_CODE (*sub_p) == COMPOUND_EXPR) 3713169689Skan gimplify_compound_expr (sub_p, pre_p, false); 3714169689Skan else 3715169689Skan gimplify_stmt (sub_p); 3716169689Skan append_to_statement_list (*sub_p, pre_p); 3717169689Skan 3718169689Skan t = TREE_OPERAND (t, 1); 3719169689Skan } 3720169689Skan while (TREE_CODE (t) == COMPOUND_EXPR); 3721169689Skan 3722169689Skan *expr_p = t; 3723169689Skan if (want_value) 3724169689Skan return GS_OK; 3725169689Skan else 3726169689Skan { 3727169689Skan gimplify_stmt (expr_p); 3728169689Skan return GS_ALL_DONE; 3729169689Skan } 3730169689Skan} 3731169689Skan 3732169689Skan/* Gimplifies a statement list. These may be created either by an 3733169689Skan enlightened front-end, or by shortcut_cond_expr. */ 3734169689Skan 3735169689Skanstatic enum gimplify_status 3736169689Skangimplify_statement_list (tree *expr_p, tree *pre_p) 3737169689Skan{ 3738169689Skan tree temp = voidify_wrapper_expr (*expr_p, NULL); 3739169689Skan 3740169689Skan tree_stmt_iterator i = tsi_start (*expr_p); 3741169689Skan 3742169689Skan while (!tsi_end_p (i)) 3743169689Skan { 3744169689Skan tree t; 3745169689Skan 3746169689Skan gimplify_stmt (tsi_stmt_ptr (i)); 3747169689Skan 3748169689Skan t = tsi_stmt (i); 3749169689Skan if (t == NULL) 3750169689Skan tsi_delink (&i); 3751169689Skan else if (TREE_CODE (t) == STATEMENT_LIST) 3752169689Skan { 3753169689Skan tsi_link_before (&i, t, TSI_SAME_STMT); 3754169689Skan tsi_delink (&i); 3755169689Skan } 3756169689Skan else 3757169689Skan tsi_next (&i); 3758169689Skan } 3759169689Skan 3760169689Skan if (temp) 3761169689Skan { 3762169689Skan append_to_statement_list (*expr_p, pre_p); 3763169689Skan *expr_p = temp; 3764169689Skan return GS_OK; 3765169689Skan } 3766169689Skan 3767169689Skan return GS_ALL_DONE; 3768169689Skan} 3769169689Skan 3770169689Skan/* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to 3771169689Skan gimplify. After gimplification, EXPR_P will point to a new temporary 3772169689Skan that holds the original value of the SAVE_EXPR node. 3773169689Skan 3774169689Skan PRE_P points to the list where side effects that must happen before 3775169689Skan *EXPR_P should be stored. */ 3776169689Skan 3777169689Skanstatic enum gimplify_status 3778169689Skangimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p) 3779169689Skan{ 3780169689Skan enum gimplify_status ret = GS_ALL_DONE; 3781169689Skan tree val; 3782169689Skan 3783169689Skan gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR); 3784169689Skan val = TREE_OPERAND (*expr_p, 0); 3785169689Skan 3786169689Skan /* If the SAVE_EXPR has not been resolved, then evaluate it once. */ 3787169689Skan if (!SAVE_EXPR_RESOLVED_P (*expr_p)) 3788169689Skan { 3789169689Skan /* The operand may be a void-valued expression such as SAVE_EXPRs 3790169689Skan generated by the Java frontend for class initialization. It is 3791169689Skan being executed only for its side-effects. */ 3792169689Skan if (TREE_TYPE (val) == void_type_node) 3793169689Skan { 3794169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 3795169689Skan is_gimple_stmt, fb_none); 3796169689Skan append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p); 3797169689Skan val = NULL; 3798169689Skan } 3799169689Skan else 3800169689Skan val = get_initialized_tmp_var (val, pre_p, post_p); 3801169689Skan 3802169689Skan TREE_OPERAND (*expr_p, 0) = val; 3803169689Skan SAVE_EXPR_RESOLVED_P (*expr_p) = 1; 3804169689Skan } 3805169689Skan 3806169689Skan *expr_p = val; 3807169689Skan 3808169689Skan return ret; 3809169689Skan} 3810169689Skan 3811169689Skan/* Re-write the ADDR_EXPR node pointed to by EXPR_P 3812169689Skan 3813169689Skan unary_expr 3814169689Skan : ... 3815169689Skan | '&' varname 3816169689Skan ... 3817169689Skan 3818169689Skan PRE_P points to the list where side effects that must happen before 3819169689Skan *EXPR_P should be stored. 3820169689Skan 3821169689Skan POST_P points to the list where side effects that must happen after 3822169689Skan *EXPR_P should be stored. */ 3823169689Skan 3824169689Skanstatic enum gimplify_status 3825169689Skangimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p) 3826169689Skan{ 3827169689Skan tree expr = *expr_p; 3828169689Skan tree op0 = TREE_OPERAND (expr, 0); 3829169689Skan enum gimplify_status ret; 3830169689Skan 3831169689Skan switch (TREE_CODE (op0)) 3832169689Skan { 3833169689Skan case INDIRECT_REF: 3834169689Skan case MISALIGNED_INDIRECT_REF: 3835169689Skan do_indirect_ref: 3836169689Skan /* Check if we are dealing with an expression of the form '&*ptr'. 3837169689Skan While the front end folds away '&*ptr' into 'ptr', these 3838169689Skan expressions may be generated internally by the compiler (e.g., 3839169689Skan builtins like __builtin_va_end). */ 3840169689Skan /* Caution: the silent array decomposition semantics we allow for 3841169689Skan ADDR_EXPR means we can't always discard the pair. */ 3842169689Skan /* Gimplification of the ADDR_EXPR operand may drop 3843169689Skan cv-qualification conversions, so make sure we add them if 3844169689Skan needed. */ 3845169689Skan { 3846169689Skan tree op00 = TREE_OPERAND (op0, 0); 3847169689Skan tree t_expr = TREE_TYPE (expr); 3848169689Skan tree t_op00 = TREE_TYPE (op00); 3849169689Skan 3850169689Skan if (!lang_hooks.types_compatible_p (t_expr, t_op00)) 3851169689Skan { 3852169689Skan#ifdef ENABLE_CHECKING 3853169689Skan tree t_op0 = TREE_TYPE (op0); 3854169689Skan gcc_assert (POINTER_TYPE_P (t_expr) 3855169689Skan && cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE 3856169689Skan ? TREE_TYPE (t_op0) : t_op0, 3857169689Skan TREE_TYPE (t_expr)) 3858169689Skan && POINTER_TYPE_P (t_op00) 3859169689Skan && cpt_same_type (t_op0, TREE_TYPE (t_op00))); 3860169689Skan#endif 3861169689Skan op00 = fold_convert (TREE_TYPE (expr), op00); 3862169689Skan } 3863169689Skan *expr_p = op00; 3864169689Skan ret = GS_OK; 3865169689Skan } 3866169689Skan break; 3867169689Skan 3868169689Skan case VIEW_CONVERT_EXPR: 3869169689Skan /* Take the address of our operand and then convert it to the type of 3870169689Skan this ADDR_EXPR. 3871169689Skan 3872169689Skan ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at 3873169689Skan all clear. The impact of this transformation is even less clear. */ 3874169689Skan 3875169689Skan /* If the operand is a useless conversion, look through it. Doing so 3876169689Skan guarantees that the ADDR_EXPR and its operand will remain of the 3877169689Skan same type. */ 3878169689Skan if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0))) 3879169689Skan op0 = TREE_OPERAND (op0, 0); 3880169689Skan 3881169689Skan *expr_p = fold_convert (TREE_TYPE (expr), 3882169689Skan build_fold_addr_expr (TREE_OPERAND (op0, 0))); 3883169689Skan ret = GS_OK; 3884169689Skan break; 3885169689Skan 3886169689Skan default: 3887169689Skan /* We use fb_either here because the C frontend sometimes takes 3888169689Skan the address of a call that returns a struct; see 3889169689Skan gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make 3890169689Skan the implied temporary explicit. */ 3891169689Skan ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, 3892169689Skan is_gimple_addressable, fb_either); 3893169689Skan if (ret != GS_ERROR) 3894169689Skan { 3895169689Skan op0 = TREE_OPERAND (expr, 0); 3896169689Skan 3897169689Skan /* For various reasons, the gimplification of the expression 3898169689Skan may have made a new INDIRECT_REF. */ 3899169689Skan if (TREE_CODE (op0) == INDIRECT_REF) 3900169689Skan goto do_indirect_ref; 3901169689Skan 3902169689Skan /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS 3903169689Skan is set properly. */ 3904169689Skan recompute_tree_invariant_for_addr_expr (expr); 3905169689Skan 3906169689Skan /* Mark the RHS addressable. */ 3907169689Skan lang_hooks.mark_addressable (TREE_OPERAND (expr, 0)); 3908169689Skan } 3909169689Skan break; 3910169689Skan } 3911169689Skan 3912169689Skan return ret; 3913169689Skan} 3914169689Skan 3915169689Skan/* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple 3916169689Skan value; output operands should be a gimple lvalue. */ 3917169689Skan 3918169689Skanstatic enum gimplify_status 3919169689Skangimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p) 3920169689Skan{ 3921169689Skan tree expr = *expr_p; 3922169689Skan int noutputs = list_length (ASM_OUTPUTS (expr)); 3923169689Skan const char **oconstraints 3924169689Skan = (const char **) alloca ((noutputs) * sizeof (const char *)); 3925169689Skan int i; 3926169689Skan tree link; 3927169689Skan const char *constraint; 3928169689Skan bool allows_mem, allows_reg, is_inout; 3929169689Skan enum gimplify_status ret, tret; 3930169689Skan 3931169689Skan ret = GS_ALL_DONE; 3932169689Skan for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link)) 3933169689Skan { 3934169689Skan size_t constraint_len; 3935169689Skan oconstraints[i] = constraint 3936169689Skan = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 3937169689Skan constraint_len = strlen (constraint); 3938169689Skan if (constraint_len == 0) 3939169689Skan continue; 3940169689Skan 3941169689Skan parse_output_constraint (&constraint, i, 0, 0, 3942169689Skan &allows_mem, &allows_reg, &is_inout); 3943169689Skan 3944169689Skan if (!allows_reg && allows_mem) 3945169689Skan lang_hooks.mark_addressable (TREE_VALUE (link)); 3946169689Skan 3947169689Skan tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 3948169689Skan is_inout ? is_gimple_min_lval : is_gimple_lvalue, 3949169689Skan fb_lvalue | fb_mayfail); 3950169689Skan if (tret == GS_ERROR) 3951169689Skan { 3952169689Skan error ("invalid lvalue in asm output %d", i); 3953169689Skan ret = tret; 3954169689Skan } 3955169689Skan 3956169689Skan if (is_inout) 3957169689Skan { 3958169689Skan /* An input/output operand. To give the optimizers more 3959169689Skan flexibility, split it into separate input and output 3960169689Skan operands. */ 3961169689Skan tree input; 3962169689Skan char buf[10]; 3963169689Skan 3964169689Skan /* Turn the in/out constraint into an output constraint. */ 3965169689Skan char *p = xstrdup (constraint); 3966169689Skan p[0] = '='; 3967169689Skan TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); 3968169689Skan 3969169689Skan /* And add a matching input constraint. */ 3970169689Skan if (allows_reg) 3971169689Skan { 3972169689Skan sprintf (buf, "%d", i); 3973169689Skan 3974169689Skan /* If there are multiple alternatives in the constraint, 3975169689Skan handle each of them individually. Those that allow register 3976169689Skan will be replaced with operand number, the others will stay 3977169689Skan unchanged. */ 3978169689Skan if (strchr (p, ',') != NULL) 3979169689Skan { 3980169689Skan size_t len = 0, buflen = strlen (buf); 3981169689Skan char *beg, *end, *str, *dst; 3982169689Skan 3983169689Skan for (beg = p + 1;;) 3984169689Skan { 3985169689Skan end = strchr (beg, ','); 3986169689Skan if (end == NULL) 3987169689Skan end = strchr (beg, '\0'); 3988169689Skan if ((size_t) (end - beg) < buflen) 3989169689Skan len += buflen + 1; 3990169689Skan else 3991169689Skan len += end - beg + 1; 3992169689Skan if (*end) 3993169689Skan beg = end + 1; 3994169689Skan else 3995169689Skan break; 3996169689Skan } 3997169689Skan 3998169689Skan str = (char *) alloca (len); 3999169689Skan for (beg = p + 1, dst = str;;) 4000169689Skan { 4001169689Skan const char *tem; 4002169689Skan bool mem_p, reg_p, inout_p; 4003169689Skan 4004169689Skan end = strchr (beg, ','); 4005169689Skan if (end) 4006169689Skan *end = '\0'; 4007169689Skan beg[-1] = '='; 4008169689Skan tem = beg - 1; 4009169689Skan parse_output_constraint (&tem, i, 0, 0, 4010169689Skan &mem_p, ®_p, &inout_p); 4011169689Skan if (dst != str) 4012169689Skan *dst++ = ','; 4013169689Skan if (reg_p) 4014169689Skan { 4015169689Skan memcpy (dst, buf, buflen); 4016169689Skan dst += buflen; 4017169689Skan } 4018169689Skan else 4019169689Skan { 4020169689Skan if (end) 4021169689Skan len = end - beg; 4022169689Skan else 4023169689Skan len = strlen (beg); 4024169689Skan memcpy (dst, beg, len); 4025169689Skan dst += len; 4026169689Skan } 4027169689Skan if (end) 4028169689Skan beg = end + 1; 4029169689Skan else 4030169689Skan break; 4031169689Skan } 4032169689Skan *dst = '\0'; 4033169689Skan input = build_string (dst - str, str); 4034169689Skan } 4035169689Skan else 4036169689Skan input = build_string (strlen (buf), buf); 4037169689Skan } 4038169689Skan else 4039169689Skan input = build_string (constraint_len - 1, constraint + 1); 4040169689Skan 4041169689Skan free (p); 4042169689Skan 4043169689Skan input = build_tree_list (build_tree_list (NULL_TREE, input), 4044169689Skan unshare_expr (TREE_VALUE (link))); 4045169689Skan ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); 4046169689Skan } 4047169689Skan } 4048169689Skan 4049169689Skan for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link)) 4050169689Skan { 4051169689Skan constraint 4052169689Skan = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 4053169689Skan parse_input_constraint (&constraint, 0, 0, noutputs, 0, 4054169689Skan oconstraints, &allows_mem, &allows_reg); 4055169689Skan 4056171825Skan /* If we can't make copies, we can only accept memory. */ 4057171825Skan if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link)))) 4058171825Skan { 4059171825Skan if (allows_mem) 4060171825Skan allows_reg = 0; 4061171825Skan else 4062171825Skan { 4063171825Skan error ("impossible constraint in %<asm%>"); 4064171825Skan error ("non-memory input %d must stay in memory", i); 4065171825Skan return GS_ERROR; 4066171825Skan } 4067171825Skan } 4068171825Skan 4069169689Skan /* If the operand is a memory input, it should be an lvalue. */ 4070169689Skan if (!allows_reg && allows_mem) 4071169689Skan { 4072169689Skan tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 4073169689Skan is_gimple_lvalue, fb_lvalue | fb_mayfail); 4074169689Skan lang_hooks.mark_addressable (TREE_VALUE (link)); 4075169689Skan if (tret == GS_ERROR) 4076169689Skan { 4077169689Skan error ("memory input %d is not directly addressable", i); 4078169689Skan ret = tret; 4079169689Skan } 4080169689Skan } 4081169689Skan else 4082169689Skan { 4083169689Skan tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 4084169689Skan is_gimple_asm_val, fb_rvalue); 4085169689Skan if (tret == GS_ERROR) 4086169689Skan ret = tret; 4087169689Skan } 4088169689Skan } 4089169689Skan 4090169689Skan return ret; 4091169689Skan} 4092169689Skan 4093169689Skan/* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding 4094169689Skan WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while 4095169689Skan gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we 4096169689Skan return to this function. 4097169689Skan 4098169689Skan FIXME should we complexify the prequeue handling instead? Or use flags 4099169689Skan for all the cleanups and let the optimizer tighten them up? The current 4100169689Skan code seems pretty fragile; it will break on a cleanup within any 4101169689Skan non-conditional nesting. But any such nesting would be broken, anyway; 4102169689Skan we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct 4103169689Skan and continues out of it. We can do that at the RTL level, though, so 4104169689Skan having an optimizer to tighten up try/finally regions would be a Good 4105169689Skan Thing. */ 4106169689Skan 4107169689Skanstatic enum gimplify_status 4108169689Skangimplify_cleanup_point_expr (tree *expr_p, tree *pre_p) 4109169689Skan{ 4110169689Skan tree_stmt_iterator iter; 4111169689Skan tree body; 4112169689Skan 4113169689Skan tree temp = voidify_wrapper_expr (*expr_p, NULL); 4114169689Skan 4115169689Skan /* We only care about the number of conditions between the innermost 4116169689Skan CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and 4117169689Skan any cleanups collected outside the CLEANUP_POINT_EXPR. */ 4118169689Skan int old_conds = gimplify_ctxp->conditions; 4119169689Skan tree old_cleanups = gimplify_ctxp->conditional_cleanups; 4120169689Skan gimplify_ctxp->conditions = 0; 4121169689Skan gimplify_ctxp->conditional_cleanups = NULL_TREE; 4122169689Skan 4123169689Skan body = TREE_OPERAND (*expr_p, 0); 4124169689Skan gimplify_to_stmt_list (&body); 4125169689Skan 4126169689Skan gimplify_ctxp->conditions = old_conds; 4127169689Skan gimplify_ctxp->conditional_cleanups = old_cleanups; 4128169689Skan 4129169689Skan for (iter = tsi_start (body); !tsi_end_p (iter); ) 4130169689Skan { 4131169689Skan tree *wce_p = tsi_stmt_ptr (iter); 4132169689Skan tree wce = *wce_p; 4133169689Skan 4134169689Skan if (TREE_CODE (wce) == WITH_CLEANUP_EXPR) 4135169689Skan { 4136169689Skan if (tsi_one_before_end_p (iter)) 4137169689Skan { 4138169689Skan tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT); 4139169689Skan tsi_delink (&iter); 4140169689Skan break; 4141169689Skan } 4142169689Skan else 4143169689Skan { 4144169689Skan tree sl, tfe; 4145169689Skan enum tree_code code; 4146169689Skan 4147169689Skan if (CLEANUP_EH_ONLY (wce)) 4148169689Skan code = TRY_CATCH_EXPR; 4149169689Skan else 4150169689Skan code = TRY_FINALLY_EXPR; 4151169689Skan 4152169689Skan sl = tsi_split_statement_list_after (&iter); 4153169689Skan tfe = build2 (code, void_type_node, sl, NULL_TREE); 4154169689Skan append_to_statement_list (TREE_OPERAND (wce, 0), 4155169689Skan &TREE_OPERAND (tfe, 1)); 4156169689Skan *wce_p = tfe; 4157169689Skan iter = tsi_start (sl); 4158169689Skan } 4159169689Skan } 4160169689Skan else 4161169689Skan tsi_next (&iter); 4162169689Skan } 4163169689Skan 4164169689Skan if (temp) 4165169689Skan { 4166169689Skan *expr_p = temp; 4167169689Skan append_to_statement_list (body, pre_p); 4168169689Skan return GS_OK; 4169169689Skan } 4170169689Skan else 4171169689Skan { 4172169689Skan *expr_p = body; 4173169689Skan return GS_ALL_DONE; 4174169689Skan } 4175169689Skan} 4176169689Skan 4177169689Skan/* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP 4178169689Skan is the cleanup action required. */ 4179169689Skan 4180169689Skanstatic void 4181169689Skangimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p) 4182169689Skan{ 4183169689Skan tree wce; 4184169689Skan 4185169689Skan /* Errors can result in improperly nested cleanups. Which results in 4186169689Skan confusion when trying to resolve the WITH_CLEANUP_EXPR. */ 4187169689Skan if (errorcount || sorrycount) 4188169689Skan return; 4189169689Skan 4190169689Skan if (gimple_conditional_context ()) 4191169689Skan { 4192169689Skan /* If we're in a conditional context, this is more complex. We only 4193169689Skan want to run the cleanup if we actually ran the initialization that 4194169689Skan necessitates it, but we want to run it after the end of the 4195169689Skan conditional context. So we wrap the try/finally around the 4196169689Skan condition and use a flag to determine whether or not to actually 4197169689Skan run the destructor. Thus 4198169689Skan 4199169689Skan test ? f(A()) : 0 4200169689Skan 4201169689Skan becomes (approximately) 4202169689Skan 4203169689Skan flag = 0; 4204169689Skan try { 4205169689Skan if (test) { A::A(temp); flag = 1; val = f(temp); } 4206169689Skan else { val = 0; } 4207169689Skan } finally { 4208169689Skan if (flag) A::~A(temp); 4209169689Skan } 4210169689Skan val 4211169689Skan */ 4212169689Skan 4213169689Skan tree flag = create_tmp_var (boolean_type_node, "cleanup"); 4214169689Skan tree ffalse = build2 (MODIFY_EXPR, void_type_node, flag, 4215169689Skan boolean_false_node); 4216169689Skan tree ftrue = build2 (MODIFY_EXPR, void_type_node, flag, 4217169689Skan boolean_true_node); 4218169689Skan cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL); 4219169689Skan wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup); 4220169689Skan append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups); 4221169689Skan append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups); 4222169689Skan append_to_statement_list (ftrue, pre_p); 4223169689Skan 4224169689Skan /* Because of this manipulation, and the EH edges that jump 4225169689Skan threading cannot redirect, the temporary (VAR) will appear 4226169689Skan to be used uninitialized. Don't warn. */ 4227169689Skan TREE_NO_WARNING (var) = 1; 4228169689Skan } 4229169689Skan else 4230169689Skan { 4231169689Skan wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup); 4232169689Skan CLEANUP_EH_ONLY (wce) = eh_only; 4233169689Skan append_to_statement_list (wce, pre_p); 4234169689Skan } 4235169689Skan 4236169689Skan gimplify_stmt (&TREE_OPERAND (wce, 0)); 4237169689Skan} 4238169689Skan 4239169689Skan/* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */ 4240169689Skan 4241169689Skanstatic enum gimplify_status 4242169689Skangimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p) 4243169689Skan{ 4244169689Skan tree targ = *expr_p; 4245169689Skan tree temp = TARGET_EXPR_SLOT (targ); 4246169689Skan tree init = TARGET_EXPR_INITIAL (targ); 4247169689Skan enum gimplify_status ret; 4248169689Skan 4249169689Skan if (init) 4250169689Skan { 4251169689Skan /* TARGET_EXPR temps aren't part of the enclosing block, so add it 4252169689Skan to the temps list. */ 4253169689Skan gimple_add_tmp_var (temp); 4254169689Skan 4255169689Skan /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the 4256169689Skan expression is supposed to initialize the slot. */ 4257169689Skan if (VOID_TYPE_P (TREE_TYPE (init))) 4258169689Skan ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); 4259169689Skan else 4260169689Skan { 4261169689Skan init = build2 (INIT_EXPR, void_type_node, temp, init); 4262169689Skan ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, 4263169689Skan fb_none); 4264169689Skan } 4265169689Skan if (ret == GS_ERROR) 4266169689Skan { 4267169689Skan /* PR c++/28266 Make sure this is expanded only once. */ 4268169689Skan TARGET_EXPR_INITIAL (targ) = NULL_TREE; 4269169689Skan return GS_ERROR; 4270169689Skan } 4271169689Skan append_to_statement_list (init, pre_p); 4272169689Skan 4273169689Skan /* If needed, push the cleanup for the temp. */ 4274169689Skan if (TARGET_EXPR_CLEANUP (targ)) 4275169689Skan { 4276169689Skan gimplify_stmt (&TARGET_EXPR_CLEANUP (targ)); 4277169689Skan gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), 4278169689Skan CLEANUP_EH_ONLY (targ), pre_p); 4279169689Skan } 4280169689Skan 4281169689Skan /* Only expand this once. */ 4282169689Skan TREE_OPERAND (targ, 3) = init; 4283169689Skan TARGET_EXPR_INITIAL (targ) = NULL_TREE; 4284169689Skan } 4285169689Skan else 4286169689Skan /* We should have expanded this before. */ 4287169689Skan gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp)); 4288169689Skan 4289169689Skan *expr_p = temp; 4290169689Skan return GS_OK; 4291169689Skan} 4292169689Skan 4293169689Skan/* Gimplification of expression trees. */ 4294169689Skan 4295169689Skan/* Gimplify an expression which appears at statement context; usually, this 4296169689Skan means replacing it with a suitably gimple STATEMENT_LIST. */ 4297169689Skan 4298169689Skanvoid 4299169689Skangimplify_stmt (tree *stmt_p) 4300169689Skan{ 4301169689Skan gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none); 4302169689Skan} 4303169689Skan 4304169689Skan/* Similarly, but force the result to be a STATEMENT_LIST. */ 4305169689Skan 4306169689Skanvoid 4307169689Skangimplify_to_stmt_list (tree *stmt_p) 4308169689Skan{ 4309169689Skan gimplify_stmt (stmt_p); 4310169689Skan if (!*stmt_p) 4311169689Skan *stmt_p = alloc_stmt_list (); 4312169689Skan else if (TREE_CODE (*stmt_p) != STATEMENT_LIST) 4313169689Skan { 4314169689Skan tree t = *stmt_p; 4315169689Skan *stmt_p = alloc_stmt_list (); 4316169689Skan append_to_statement_list (t, stmt_p); 4317169689Skan } 4318169689Skan} 4319169689Skan 4320169689Skan 4321169689Skan/* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels 4322169689Skan to CTX. If entries already exist, force them to be some flavor of private. 4323169689Skan If there is no enclosing parallel, do nothing. */ 4324169689Skan 4325169689Skanvoid 4326169689Skanomp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl) 4327169689Skan{ 4328169689Skan splay_tree_node n; 4329169689Skan 4330169689Skan if (decl == NULL || !DECL_P (decl)) 4331169689Skan return; 4332169689Skan 4333169689Skan do 4334169689Skan { 4335169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 4336169689Skan if (n != NULL) 4337169689Skan { 4338169689Skan if (n->value & GOVD_SHARED) 4339169689Skan n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN); 4340169689Skan else 4341169689Skan return; 4342169689Skan } 4343169689Skan else if (ctx->is_parallel) 4344169689Skan omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); 4345169689Skan 4346169689Skan ctx = ctx->outer_context; 4347169689Skan } 4348169689Skan while (ctx); 4349169689Skan} 4350169689Skan 4351169689Skan/* Similarly for each of the type sizes of TYPE. */ 4352169689Skan 4353169689Skanstatic void 4354169689Skanomp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type) 4355169689Skan{ 4356169689Skan if (type == NULL || type == error_mark_node) 4357169689Skan return; 4358169689Skan type = TYPE_MAIN_VARIANT (type); 4359169689Skan 4360169689Skan if (pointer_set_insert (ctx->privatized_types, type)) 4361169689Skan return; 4362169689Skan 4363169689Skan switch (TREE_CODE (type)) 4364169689Skan { 4365169689Skan case INTEGER_TYPE: 4366169689Skan case ENUMERAL_TYPE: 4367169689Skan case BOOLEAN_TYPE: 4368169689Skan case REAL_TYPE: 4369169689Skan omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type)); 4370169689Skan omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type)); 4371169689Skan break; 4372169689Skan 4373169689Skan case ARRAY_TYPE: 4374169689Skan omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 4375169689Skan omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type)); 4376169689Skan break; 4377169689Skan 4378169689Skan case RECORD_TYPE: 4379169689Skan case UNION_TYPE: 4380169689Skan case QUAL_UNION_TYPE: 4381169689Skan { 4382169689Skan tree field; 4383169689Skan for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 4384169689Skan if (TREE_CODE (field) == FIELD_DECL) 4385169689Skan { 4386169689Skan omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field)); 4387169689Skan omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field)); 4388169689Skan } 4389169689Skan } 4390169689Skan break; 4391169689Skan 4392169689Skan case POINTER_TYPE: 4393169689Skan case REFERENCE_TYPE: 4394169689Skan omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 4395169689Skan break; 4396169689Skan 4397169689Skan default: 4398169689Skan break; 4399169689Skan } 4400169689Skan 4401169689Skan omp_firstprivatize_variable (ctx, TYPE_SIZE (type)); 4402169689Skan omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type)); 4403169689Skan lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type); 4404169689Skan} 4405169689Skan 4406169689Skan/* Add an entry for DECL in the OpenMP context CTX with FLAGS. */ 4407169689Skan 4408169689Skanstatic void 4409169689Skanomp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) 4410169689Skan{ 4411169689Skan splay_tree_node n; 4412169689Skan unsigned int nflags; 4413169689Skan tree t; 4414169689Skan 4415169689Skan if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) 4416169689Skan return; 4417169689Skan 4418169689Skan /* Never elide decls whose type has TREE_ADDRESSABLE set. This means 4419169689Skan there are constructors involved somewhere. */ 4420169689Skan if (TREE_ADDRESSABLE (TREE_TYPE (decl)) 4421169689Skan || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) 4422169689Skan flags |= GOVD_SEEN; 4423169689Skan 4424169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 4425169689Skan if (n != NULL) 4426169689Skan { 4427169689Skan /* We shouldn't be re-adding the decl with the same data 4428169689Skan sharing class. */ 4429169689Skan gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0); 4430169689Skan /* The only combination of data sharing classes we should see is 4431169689Skan FIRSTPRIVATE and LASTPRIVATE. */ 4432169689Skan nflags = n->value | flags; 4433169689Skan gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS) 4434169689Skan == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)); 4435169689Skan n->value = nflags; 4436169689Skan return; 4437169689Skan } 4438169689Skan 4439169689Skan /* When adding a variable-sized variable, we have to handle all sorts 4440169689Skan of additional bits of data: the pointer replacement variable, and 4441169689Skan the parameters of the type. */ 4442169689Skan if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 4443169689Skan { 4444169689Skan /* Add the pointer replacement variable as PRIVATE if the variable 4445169689Skan replacement is private, else FIRSTPRIVATE since we'll need the 4446169689Skan address of the original variable either for SHARED, or for the 4447169689Skan copy into or out of the context. */ 4448169689Skan if (!(flags & GOVD_LOCAL)) 4449169689Skan { 4450169689Skan nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE; 4451169689Skan nflags |= flags & GOVD_SEEN; 4452169689Skan t = DECL_VALUE_EXPR (decl); 4453169689Skan gcc_assert (TREE_CODE (t) == INDIRECT_REF); 4454169689Skan t = TREE_OPERAND (t, 0); 4455169689Skan gcc_assert (DECL_P (t)); 4456169689Skan omp_add_variable (ctx, t, nflags); 4457169689Skan } 4458169689Skan 4459169689Skan /* Add all of the variable and type parameters (which should have 4460169689Skan been gimplified to a formal temporary) as FIRSTPRIVATE. */ 4461169689Skan omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl)); 4462169689Skan omp_firstprivatize_variable (ctx, DECL_SIZE (decl)); 4463169689Skan omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 4464169689Skan 4465169689Skan /* The variable-sized variable itself is never SHARED, only some form 4466169689Skan of PRIVATE. The sharing would take place via the pointer variable 4467169689Skan which we remapped above. */ 4468169689Skan if (flags & GOVD_SHARED) 4469169689Skan flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE 4470169689Skan | (flags & (GOVD_SEEN | GOVD_EXPLICIT)); 4471169689Skan 4472169689Skan /* We're going to make use of the TYPE_SIZE_UNIT at least in the 4473169689Skan alloca statement we generate for the variable, so make sure it 4474169689Skan is available. This isn't automatically needed for the SHARED 4475169689Skan case, since we won't be allocating local storage then. 4476169689Skan For local variables TYPE_SIZE_UNIT might not be gimplified yet, 4477169689Skan in this case omp_notice_variable will be called later 4478169689Skan on when it is gimplified. */ 4479169689Skan else if (! (flags & GOVD_LOCAL)) 4480169689Skan omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true); 4481169689Skan } 4482169689Skan else if (lang_hooks.decls.omp_privatize_by_reference (decl)) 4483169689Skan { 4484169689Skan gcc_assert ((flags & GOVD_LOCAL) == 0); 4485169689Skan omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 4486169689Skan 4487169689Skan /* Similar to the direct variable sized case above, we'll need the 4488169689Skan size of references being privatized. */ 4489169689Skan if ((flags & GOVD_SHARED) == 0) 4490169689Skan { 4491169689Skan t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); 4492169689Skan if (TREE_CODE (t) != INTEGER_CST) 4493169689Skan omp_notice_variable (ctx, t, true); 4494169689Skan } 4495169689Skan } 4496169689Skan 4497169689Skan splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags); 4498169689Skan} 4499169689Skan 4500169689Skan/* Record the fact that DECL was used within the OpenMP context CTX. 4501169689Skan IN_CODE is true when real code uses DECL, and false when we should 4502169689Skan merely emit default(none) errors. Return true if DECL is going to 4503169689Skan be remapped and thus DECL shouldn't be gimplified into its 4504169689Skan DECL_VALUE_EXPR (if any). */ 4505169689Skan 4506169689Skanstatic bool 4507169689Skanomp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) 4508169689Skan{ 4509169689Skan splay_tree_node n; 4510169689Skan unsigned flags = in_code ? GOVD_SEEN : 0; 4511169689Skan bool ret = false, shared; 4512169689Skan 4513169689Skan if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) 4514169689Skan return false; 4515169689Skan 4516169689Skan /* Threadprivate variables are predetermined. */ 4517169689Skan if (is_global_var (decl)) 4518169689Skan { 4519169689Skan if (DECL_THREAD_LOCAL_P (decl)) 4520169689Skan return false; 4521169689Skan 4522169689Skan if (DECL_HAS_VALUE_EXPR_P (decl)) 4523169689Skan { 4524169689Skan tree value = get_base_address (DECL_VALUE_EXPR (decl)); 4525169689Skan 4526169689Skan if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) 4527169689Skan return false; 4528169689Skan } 4529169689Skan } 4530169689Skan 4531169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 4532169689Skan if (n == NULL) 4533169689Skan { 4534169689Skan enum omp_clause_default_kind default_kind, kind; 4535169689Skan 4536169689Skan if (!ctx->is_parallel) 4537169689Skan goto do_outer; 4538169689Skan 4539169689Skan /* ??? Some compiler-generated variables (like SAVE_EXPRs) could be 4540169689Skan remapped firstprivate instead of shared. To some extent this is 4541169689Skan addressed in omp_firstprivatize_type_sizes, but not effectively. */ 4542169689Skan default_kind = ctx->default_kind; 4543169689Skan kind = lang_hooks.decls.omp_predetermined_sharing (decl); 4544169689Skan if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 4545169689Skan default_kind = kind; 4546169689Skan 4547169689Skan switch (default_kind) 4548169689Skan { 4549169689Skan case OMP_CLAUSE_DEFAULT_NONE: 4550169689Skan error ("%qs not specified in enclosing parallel", 4551169689Skan IDENTIFIER_POINTER (DECL_NAME (decl))); 4552169689Skan error ("%Henclosing parallel", &ctx->location); 4553169689Skan /* FALLTHRU */ 4554169689Skan case OMP_CLAUSE_DEFAULT_SHARED: 4555169689Skan flags |= GOVD_SHARED; 4556169689Skan break; 4557169689Skan case OMP_CLAUSE_DEFAULT_PRIVATE: 4558169689Skan flags |= GOVD_PRIVATE; 4559169689Skan break; 4560169689Skan default: 4561169689Skan gcc_unreachable (); 4562169689Skan } 4563169689Skan 4564169689Skan omp_add_variable (ctx, decl, flags); 4565169689Skan 4566169689Skan shared = (flags & GOVD_SHARED) != 0; 4567169689Skan ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 4568169689Skan goto do_outer; 4569169689Skan } 4570169689Skan 4571169689Skan shared = ((flags | n->value) & GOVD_SHARED) != 0; 4572169689Skan ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 4573169689Skan 4574169689Skan /* If nothing changed, there's nothing left to do. */ 4575169689Skan if ((n->value & flags) == flags) 4576169689Skan return ret; 4577169689Skan flags |= n->value; 4578169689Skan n->value = flags; 4579169689Skan 4580169689Skan do_outer: 4581169689Skan /* If the variable is private in the current context, then we don't 4582169689Skan need to propagate anything to an outer context. */ 4583169689Skan if (flags & GOVD_PRIVATE) 4584169689Skan return ret; 4585169689Skan if (ctx->outer_context 4586169689Skan && omp_notice_variable (ctx->outer_context, decl, in_code)) 4587169689Skan return true; 4588169689Skan return ret; 4589169689Skan} 4590169689Skan 4591169689Skan/* Verify that DECL is private within CTX. If there's specific information 4592169689Skan to the contrary in the innermost scope, generate an error. */ 4593169689Skan 4594169689Skanstatic bool 4595169689Skanomp_is_private (struct gimplify_omp_ctx *ctx, tree decl) 4596169689Skan{ 4597169689Skan splay_tree_node n; 4598169689Skan 4599169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 4600169689Skan if (n != NULL) 4601169689Skan { 4602169689Skan if (n->value & GOVD_SHARED) 4603169689Skan { 4604169689Skan if (ctx == gimplify_omp_ctxp) 4605169689Skan { 4606169689Skan error ("iteration variable %qs should be private", 4607169689Skan IDENTIFIER_POINTER (DECL_NAME (decl))); 4608169689Skan n->value = GOVD_PRIVATE; 4609169689Skan return true; 4610169689Skan } 4611169689Skan else 4612169689Skan return false; 4613169689Skan } 4614169689Skan else if ((n->value & GOVD_EXPLICIT) != 0 4615169689Skan && (ctx == gimplify_omp_ctxp 4616169689Skan || (ctx->is_combined_parallel 4617169689Skan && gimplify_omp_ctxp->outer_context == ctx))) 4618169689Skan { 4619169689Skan if ((n->value & GOVD_FIRSTPRIVATE) != 0) 4620169689Skan error ("iteration variable %qs should not be firstprivate", 4621169689Skan IDENTIFIER_POINTER (DECL_NAME (decl))); 4622169689Skan else if ((n->value & GOVD_REDUCTION) != 0) 4623169689Skan error ("iteration variable %qs should not be reduction", 4624169689Skan IDENTIFIER_POINTER (DECL_NAME (decl))); 4625169689Skan } 4626169689Skan return true; 4627169689Skan } 4628169689Skan 4629169689Skan if (ctx->is_parallel) 4630169689Skan return false; 4631169689Skan else if (ctx->outer_context) 4632169689Skan return omp_is_private (ctx->outer_context, decl); 4633169689Skan else 4634169689Skan return !is_global_var (decl); 4635169689Skan} 4636169689Skan 4637169689Skan/* Return true if DECL is private within a parallel region 4638169689Skan that binds to the current construct's context or in parallel 4639169689Skan region's REDUCTION clause. */ 4640169689Skan 4641169689Skanstatic bool 4642169689Skanomp_check_private (struct gimplify_omp_ctx *ctx, tree decl) 4643169689Skan{ 4644169689Skan splay_tree_node n; 4645169689Skan 4646169689Skan do 4647169689Skan { 4648169689Skan ctx = ctx->outer_context; 4649169689Skan if (ctx == NULL) 4650169689Skan return !(is_global_var (decl) 4651169689Skan /* References might be private, but might be shared too. */ 4652169689Skan || lang_hooks.decls.omp_privatize_by_reference (decl)); 4653169689Skan 4654169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 4655169689Skan if (n != NULL) 4656169689Skan return (n->value & GOVD_SHARED) == 0; 4657169689Skan } 4658169689Skan while (!ctx->is_parallel); 4659169689Skan return false; 4660169689Skan} 4661169689Skan 4662169689Skan/* Scan the OpenMP clauses in *LIST_P, installing mappings into a new 4663169689Skan and previous omp contexts. */ 4664169689Skan 4665169689Skanstatic void 4666169689Skangimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel, 4667169689Skan bool in_combined_parallel) 4668169689Skan{ 4669169689Skan struct gimplify_omp_ctx *ctx, *outer_ctx; 4670169689Skan tree c; 4671169689Skan 4672169689Skan ctx = new_omp_context (in_parallel, in_combined_parallel); 4673169689Skan outer_ctx = ctx->outer_context; 4674169689Skan 4675169689Skan while ((c = *list_p) != NULL) 4676169689Skan { 4677169689Skan enum gimplify_status gs; 4678169689Skan bool remove = false; 4679169689Skan bool notice_outer = true; 4680169689Skan const char *check_non_private = NULL; 4681169689Skan unsigned int flags; 4682169689Skan tree decl; 4683169689Skan 4684169689Skan switch (OMP_CLAUSE_CODE (c)) 4685169689Skan { 4686169689Skan case OMP_CLAUSE_PRIVATE: 4687169689Skan flags = GOVD_PRIVATE | GOVD_EXPLICIT; 4688169689Skan notice_outer = false; 4689169689Skan goto do_add; 4690169689Skan case OMP_CLAUSE_SHARED: 4691169689Skan flags = GOVD_SHARED | GOVD_EXPLICIT; 4692169689Skan goto do_add; 4693169689Skan case OMP_CLAUSE_FIRSTPRIVATE: 4694169689Skan flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; 4695169689Skan check_non_private = "firstprivate"; 4696169689Skan goto do_add; 4697169689Skan case OMP_CLAUSE_LASTPRIVATE: 4698169689Skan flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT; 4699169689Skan check_non_private = "lastprivate"; 4700169689Skan goto do_add; 4701169689Skan case OMP_CLAUSE_REDUCTION: 4702169689Skan flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; 4703169689Skan check_non_private = "reduction"; 4704169689Skan goto do_add; 4705169689Skan 4706169689Skan do_add: 4707169689Skan decl = OMP_CLAUSE_DECL (c); 4708169689Skan if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) 4709169689Skan { 4710169689Skan remove = true; 4711169689Skan break; 4712169689Skan } 4713169689Skan omp_add_variable (ctx, decl, flags); 4714169689Skan if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 4715169689Skan && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) 4716169689Skan { 4717169689Skan omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 4718169689Skan GOVD_LOCAL | GOVD_SEEN); 4719169689Skan gimplify_omp_ctxp = ctx; 4720169689Skan push_gimplify_context (); 4721169689Skan gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c)); 4722169689Skan pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c)); 4723169689Skan push_gimplify_context (); 4724169689Skan gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c)); 4725169689Skan pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c)); 4726169689Skan gimplify_omp_ctxp = outer_ctx; 4727169689Skan } 4728169689Skan if (notice_outer) 4729169689Skan goto do_notice; 4730169689Skan break; 4731169689Skan 4732169689Skan case OMP_CLAUSE_COPYIN: 4733169689Skan case OMP_CLAUSE_COPYPRIVATE: 4734169689Skan decl = OMP_CLAUSE_DECL (c); 4735169689Skan if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) 4736169689Skan { 4737169689Skan remove = true; 4738169689Skan break; 4739169689Skan } 4740169689Skan do_notice: 4741169689Skan if (outer_ctx) 4742169689Skan omp_notice_variable (outer_ctx, decl, true); 4743169689Skan if (check_non_private 4744169689Skan && !in_parallel 4745169689Skan && omp_check_private (ctx, decl)) 4746169689Skan { 4747169689Skan error ("%s variable %qs is private in outer context", 4748169689Skan check_non_private, IDENTIFIER_POINTER (DECL_NAME (decl))); 4749169689Skan remove = true; 4750169689Skan } 4751169689Skan break; 4752169689Skan 4753169689Skan case OMP_CLAUSE_IF: 4754169689Skan OMP_CLAUSE_OPERAND (c, 0) 4755169689Skan = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); 4756169689Skan /* Fall through. */ 4757169689Skan 4758169689Skan case OMP_CLAUSE_SCHEDULE: 4759169689Skan case OMP_CLAUSE_NUM_THREADS: 4760169689Skan gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, 4761169689Skan is_gimple_val, fb_rvalue); 4762169689Skan if (gs == GS_ERROR) 4763169689Skan remove = true; 4764169689Skan break; 4765169689Skan 4766169689Skan case OMP_CLAUSE_NOWAIT: 4767169689Skan case OMP_CLAUSE_ORDERED: 4768169689Skan break; 4769169689Skan 4770169689Skan case OMP_CLAUSE_DEFAULT: 4771169689Skan ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c); 4772169689Skan break; 4773169689Skan 4774169689Skan default: 4775169689Skan gcc_unreachable (); 4776169689Skan } 4777169689Skan 4778169689Skan if (remove) 4779169689Skan *list_p = OMP_CLAUSE_CHAIN (c); 4780169689Skan else 4781169689Skan list_p = &OMP_CLAUSE_CHAIN (c); 4782169689Skan } 4783169689Skan 4784169689Skan gimplify_omp_ctxp = ctx; 4785169689Skan} 4786169689Skan 4787169689Skan/* For all variables that were not actually used within the context, 4788169689Skan remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */ 4789169689Skan 4790169689Skanstatic int 4791169689Skangimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) 4792169689Skan{ 4793169689Skan tree *list_p = (tree *) data; 4794169689Skan tree decl = (tree) n->key; 4795169689Skan unsigned flags = n->value; 4796169689Skan enum omp_clause_code code; 4797169689Skan tree clause; 4798169689Skan bool private_debug; 4799169689Skan 4800169689Skan if (flags & (GOVD_EXPLICIT | GOVD_LOCAL)) 4801169689Skan return 0; 4802169689Skan if ((flags & GOVD_SEEN) == 0) 4803169689Skan return 0; 4804169689Skan if (flags & GOVD_DEBUG_PRIVATE) 4805169689Skan { 4806169689Skan gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE); 4807169689Skan private_debug = true; 4808169689Skan } 4809169689Skan else 4810169689Skan private_debug 4811169689Skan = lang_hooks.decls.omp_private_debug_clause (decl, 4812169689Skan !!(flags & GOVD_SHARED)); 4813169689Skan if (private_debug) 4814169689Skan code = OMP_CLAUSE_PRIVATE; 4815169689Skan else if (flags & GOVD_SHARED) 4816169689Skan { 4817169689Skan if (is_global_var (decl)) 4818171825Skan { 4819171825Skan struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; 4820171825Skan while (ctx != NULL) 4821171825Skan { 4822171825Skan splay_tree_node on 4823171825Skan = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 4824171825Skan if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE 4825171825Skan | GOVD_PRIVATE | GOVD_REDUCTION)) != 0) 4826171825Skan break; 4827171825Skan ctx = ctx->outer_context; 4828171825Skan } 4829171825Skan if (ctx == NULL) 4830171825Skan return 0; 4831171825Skan } 4832169689Skan code = OMP_CLAUSE_SHARED; 4833169689Skan } 4834169689Skan else if (flags & GOVD_PRIVATE) 4835169689Skan code = OMP_CLAUSE_PRIVATE; 4836169689Skan else if (flags & GOVD_FIRSTPRIVATE) 4837169689Skan code = OMP_CLAUSE_FIRSTPRIVATE; 4838169689Skan else 4839169689Skan gcc_unreachable (); 4840169689Skan 4841169689Skan clause = build_omp_clause (code); 4842169689Skan OMP_CLAUSE_DECL (clause) = decl; 4843169689Skan OMP_CLAUSE_CHAIN (clause) = *list_p; 4844169689Skan if (private_debug) 4845169689Skan OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1; 4846169689Skan *list_p = clause; 4847169689Skan 4848169689Skan return 0; 4849169689Skan} 4850169689Skan 4851169689Skanstatic void 4852169689Skangimplify_adjust_omp_clauses (tree *list_p) 4853169689Skan{ 4854169689Skan struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 4855169689Skan tree c, decl; 4856169689Skan 4857169689Skan while ((c = *list_p) != NULL) 4858169689Skan { 4859169689Skan splay_tree_node n; 4860169689Skan bool remove = false; 4861169689Skan 4862169689Skan switch (OMP_CLAUSE_CODE (c)) 4863169689Skan { 4864169689Skan case OMP_CLAUSE_PRIVATE: 4865169689Skan case OMP_CLAUSE_SHARED: 4866169689Skan case OMP_CLAUSE_FIRSTPRIVATE: 4867169689Skan decl = OMP_CLAUSE_DECL (c); 4868169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 4869169689Skan remove = !(n->value & GOVD_SEEN); 4870169689Skan if (! remove) 4871169689Skan { 4872169689Skan bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED; 4873169689Skan if ((n->value & GOVD_DEBUG_PRIVATE) 4874169689Skan || lang_hooks.decls.omp_private_debug_clause (decl, shared)) 4875169689Skan { 4876169689Skan gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0 4877169689Skan || ((n->value & GOVD_DATA_SHARE_CLASS) 4878169689Skan == GOVD_PRIVATE)); 4879169689Skan OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE); 4880169689Skan OMP_CLAUSE_PRIVATE_DEBUG (c) = 1; 4881169689Skan } 4882169689Skan } 4883169689Skan break; 4884169689Skan 4885169689Skan case OMP_CLAUSE_LASTPRIVATE: 4886169689Skan /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to 4887169689Skan accurately reflect the presence of a FIRSTPRIVATE clause. */ 4888169689Skan decl = OMP_CLAUSE_DECL (c); 4889169689Skan n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 4890169689Skan OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) 4891169689Skan = (n->value & GOVD_FIRSTPRIVATE) != 0; 4892169689Skan break; 4893169689Skan 4894169689Skan case OMP_CLAUSE_REDUCTION: 4895169689Skan case OMP_CLAUSE_COPYIN: 4896169689Skan case OMP_CLAUSE_COPYPRIVATE: 4897169689Skan case OMP_CLAUSE_IF: 4898169689Skan case OMP_CLAUSE_NUM_THREADS: 4899169689Skan case OMP_CLAUSE_SCHEDULE: 4900169689Skan case OMP_CLAUSE_NOWAIT: 4901169689Skan case OMP_CLAUSE_ORDERED: 4902169689Skan case OMP_CLAUSE_DEFAULT: 4903169689Skan break; 4904169689Skan 4905169689Skan default: 4906169689Skan gcc_unreachable (); 4907169689Skan } 4908169689Skan 4909169689Skan if (remove) 4910169689Skan *list_p = OMP_CLAUSE_CHAIN (c); 4911169689Skan else 4912169689Skan list_p = &OMP_CLAUSE_CHAIN (c); 4913169689Skan } 4914169689Skan 4915169689Skan /* Add in any implicit data sharing. */ 4916169689Skan splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, list_p); 4917169689Skan 4918169689Skan gimplify_omp_ctxp = ctx->outer_context; 4919169689Skan delete_omp_context (ctx); 4920169689Skan} 4921169689Skan 4922169689Skan/* Gimplify the contents of an OMP_PARALLEL statement. This involves 4923169689Skan gimplification of the body, as well as scanning the body for used 4924169689Skan variables. We need to do this scan now, because variable-sized 4925169689Skan decls will be decomposed during gimplification. */ 4926169689Skan 4927169689Skanstatic enum gimplify_status 4928169689Skangimplify_omp_parallel (tree *expr_p, tree *pre_p) 4929169689Skan{ 4930169689Skan tree expr = *expr_p; 4931169689Skan 4932169689Skan gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, true, 4933169689Skan OMP_PARALLEL_COMBINED (expr)); 4934169689Skan 4935169689Skan push_gimplify_context (); 4936169689Skan 4937169689Skan gimplify_stmt (&OMP_PARALLEL_BODY (expr)); 4938169689Skan 4939169689Skan if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR) 4940169689Skan pop_gimplify_context (OMP_PARALLEL_BODY (expr)); 4941169689Skan else 4942169689Skan pop_gimplify_context (NULL_TREE); 4943169689Skan 4944169689Skan gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr)); 4945169689Skan 4946169689Skan return GS_ALL_DONE; 4947169689Skan} 4948169689Skan 4949169689Skan/* Gimplify the gross structure of an OMP_FOR statement. */ 4950169689Skan 4951169689Skanstatic enum gimplify_status 4952169689Skangimplify_omp_for (tree *expr_p, tree *pre_p) 4953169689Skan{ 4954169689Skan tree for_stmt, decl, t; 4955169689Skan enum gimplify_status ret = 0; 4956169689Skan 4957169689Skan for_stmt = *expr_p; 4958169689Skan 4959169689Skan gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false, false); 4960169689Skan 4961169689Skan t = OMP_FOR_INIT (for_stmt); 4962169689Skan gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 4963169689Skan decl = TREE_OPERAND (t, 0); 4964169689Skan gcc_assert (DECL_P (decl)); 4965169689Skan gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))); 4966169689Skan 4967169689Skan /* Make sure the iteration variable is private. */ 4968169689Skan if (omp_is_private (gimplify_omp_ctxp, decl)) 4969169689Skan omp_notice_variable (gimplify_omp_ctxp, decl, true); 4970169689Skan else 4971169689Skan omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN); 4972169689Skan 4973169689Skan ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt), 4974169689Skan NULL, is_gimple_val, fb_rvalue); 4975169689Skan 4976169689Skan t = OMP_FOR_COND (for_stmt); 4977169689Skan gcc_assert (COMPARISON_CLASS_P (t)); 4978169689Skan gcc_assert (TREE_OPERAND (t, 0) == decl); 4979169689Skan 4980169689Skan ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt), 4981169689Skan NULL, is_gimple_val, fb_rvalue); 4982169689Skan 4983169689Skan t = OMP_FOR_INCR (for_stmt); 4984169689Skan switch (TREE_CODE (t)) 4985169689Skan { 4986169689Skan case PREINCREMENT_EXPR: 4987169689Skan case POSTINCREMENT_EXPR: 4988169689Skan t = build_int_cst (TREE_TYPE (decl), 1); 4989169689Skan goto build_modify; 4990169689Skan case PREDECREMENT_EXPR: 4991169689Skan case POSTDECREMENT_EXPR: 4992169689Skan t = build_int_cst (TREE_TYPE (decl), -1); 4993169689Skan goto build_modify; 4994169689Skan build_modify: 4995169689Skan t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t); 4996169689Skan t = build2 (MODIFY_EXPR, void_type_node, decl, t); 4997169689Skan OMP_FOR_INCR (for_stmt) = t; 4998169689Skan break; 4999169689Skan 5000169689Skan case MODIFY_EXPR: 5001169689Skan gcc_assert (TREE_OPERAND (t, 0) == decl); 5002169689Skan t = TREE_OPERAND (t, 1); 5003169689Skan switch (TREE_CODE (t)) 5004169689Skan { 5005169689Skan case PLUS_EXPR: 5006169689Skan if (TREE_OPERAND (t, 1) == decl) 5007169689Skan { 5008169689Skan TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0); 5009169689Skan TREE_OPERAND (t, 0) = decl; 5010169689Skan break; 5011169689Skan } 5012169689Skan case MINUS_EXPR: 5013169689Skan gcc_assert (TREE_OPERAND (t, 0) == decl); 5014169689Skan break; 5015169689Skan default: 5016169689Skan gcc_unreachable (); 5017169689Skan } 5018169689Skan 5019169689Skan ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt), 5020169689Skan NULL, is_gimple_val, fb_rvalue); 5021169689Skan break; 5022169689Skan 5023169689Skan default: 5024169689Skan gcc_unreachable (); 5025169689Skan } 5026169689Skan 5027169689Skan gimplify_to_stmt_list (&OMP_FOR_BODY (for_stmt)); 5028169689Skan gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt)); 5029169689Skan 5030169689Skan return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR; 5031169689Skan} 5032169689Skan 5033169689Skan/* Gimplify the gross structure of other OpenMP worksharing constructs. 5034169689Skan In particular, OMP_SECTIONS and OMP_SINGLE. */ 5035169689Skan 5036169689Skanstatic enum gimplify_status 5037169689Skangimplify_omp_workshare (tree *expr_p, tree *pre_p) 5038169689Skan{ 5039169689Skan tree stmt = *expr_p; 5040169689Skan 5041169689Skan gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false); 5042169689Skan gimplify_to_stmt_list (&OMP_BODY (stmt)); 5043169689Skan gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt)); 5044169689Skan 5045169689Skan return GS_ALL_DONE; 5046169689Skan} 5047169689Skan 5048169689Skan/* A subroutine of gimplify_omp_atomic. The front end is supposed to have 5049169689Skan stabilized the lhs of the atomic operation as *ADDR. Return true if 5050169689Skan EXPR is this stabilized form. */ 5051169689Skan 5052169689Skanstatic bool 5053169689Skangoa_lhs_expr_p (tree expr, tree addr) 5054169689Skan{ 5055169689Skan /* Also include casts to other type variants. The C front end is fond 5056169689Skan of adding these for e.g. volatile variables. This is like 5057169689Skan STRIP_TYPE_NOPS but includes the main variant lookup. */ 5058169689Skan while ((TREE_CODE (expr) == NOP_EXPR 5059169689Skan || TREE_CODE (expr) == CONVERT_EXPR 5060169689Skan || TREE_CODE (expr) == NON_LVALUE_EXPR) 5061169689Skan && TREE_OPERAND (expr, 0) != error_mark_node 5062169689Skan && (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) 5063169689Skan == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0))))) 5064169689Skan expr = TREE_OPERAND (expr, 0); 5065169689Skan 5066169689Skan if (TREE_CODE (expr) == INDIRECT_REF && TREE_OPERAND (expr, 0) == addr) 5067169689Skan return true; 5068169689Skan if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0)) 5069169689Skan return true; 5070169689Skan return false; 5071169689Skan} 5072169689Skan 5073169689Skan/* A subroutine of gimplify_omp_atomic. Attempt to implement the atomic 5074169689Skan operation as a __sync_fetch_and_op builtin. INDEX is log2 of the 5075169689Skan size of the data type, and thus usable to find the index of the builtin 5076169689Skan decl. Returns GS_UNHANDLED if the expression is not of the proper form. */ 5077169689Skan 5078169689Skanstatic enum gimplify_status 5079169689Skangimplify_omp_atomic_fetch_op (tree *expr_p, tree addr, tree rhs, int index) 5080169689Skan{ 5081169689Skan enum built_in_function base; 5082169689Skan tree decl, args, itype; 5083169689Skan enum insn_code *optab; 5084169689Skan 5085169689Skan /* Check for one of the supported fetch-op operations. */ 5086169689Skan switch (TREE_CODE (rhs)) 5087169689Skan { 5088169689Skan case PLUS_EXPR: 5089169689Skan base = BUILT_IN_FETCH_AND_ADD_N; 5090169689Skan optab = sync_add_optab; 5091169689Skan break; 5092169689Skan case MINUS_EXPR: 5093169689Skan base = BUILT_IN_FETCH_AND_SUB_N; 5094169689Skan optab = sync_add_optab; 5095169689Skan break; 5096169689Skan case BIT_AND_EXPR: 5097169689Skan base = BUILT_IN_FETCH_AND_AND_N; 5098169689Skan optab = sync_and_optab; 5099169689Skan break; 5100169689Skan case BIT_IOR_EXPR: 5101169689Skan base = BUILT_IN_FETCH_AND_OR_N; 5102169689Skan optab = sync_ior_optab; 5103169689Skan break; 5104169689Skan case BIT_XOR_EXPR: 5105169689Skan base = BUILT_IN_FETCH_AND_XOR_N; 5106169689Skan optab = sync_xor_optab; 5107169689Skan break; 5108169689Skan default: 5109169689Skan return GS_UNHANDLED; 5110169689Skan } 5111169689Skan 5112169689Skan /* Make sure the expression is of the proper form. */ 5113169689Skan if (goa_lhs_expr_p (TREE_OPERAND (rhs, 0), addr)) 5114169689Skan rhs = TREE_OPERAND (rhs, 1); 5115169689Skan else if (commutative_tree_code (TREE_CODE (rhs)) 5116169689Skan && goa_lhs_expr_p (TREE_OPERAND (rhs, 1), addr)) 5117169689Skan rhs = TREE_OPERAND (rhs, 0); 5118169689Skan else 5119169689Skan return GS_UNHANDLED; 5120169689Skan 5121169689Skan decl = built_in_decls[base + index + 1]; 5122169689Skan itype = TREE_TYPE (TREE_TYPE (decl)); 5123169689Skan 5124169689Skan if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing) 5125169689Skan return GS_UNHANDLED; 5126169689Skan 5127169689Skan args = tree_cons (NULL, fold_convert (itype, rhs), NULL); 5128169689Skan args = tree_cons (NULL, addr, args); 5129169689Skan *expr_p = build_function_call_expr (decl, args); 5130169689Skan return GS_OK; 5131169689Skan} 5132169689Skan 5133169689Skan/* A subroutine of gimplify_omp_atomic_pipeline. Walk *EXPR_P and replace 5134169689Skan appearances of *LHS_ADDR with LHS_VAR. If an expression does not involve 5135169689Skan the lhs, evaluate it into a temporary. Return 1 if the lhs appeared as 5136169689Skan a subexpression, 0 if it did not, or -1 if an error was encountered. */ 5137169689Skan 5138169689Skanstatic int 5139169689Skangoa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var) 5140169689Skan{ 5141169689Skan tree expr = *expr_p; 5142169689Skan int saw_lhs; 5143169689Skan 5144169689Skan if (goa_lhs_expr_p (expr, lhs_addr)) 5145169689Skan { 5146169689Skan *expr_p = lhs_var; 5147169689Skan return 1; 5148169689Skan } 5149169689Skan if (is_gimple_val (expr)) 5150169689Skan return 0; 5151169689Skan 5152169689Skan saw_lhs = 0; 5153169689Skan switch (TREE_CODE_CLASS (TREE_CODE (expr))) 5154169689Skan { 5155169689Skan case tcc_binary: 5156169689Skan saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 5157169689Skan lhs_addr, lhs_var); 5158169689Skan case tcc_unary: 5159169689Skan saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 5160169689Skan lhs_addr, lhs_var); 5161169689Skan break; 5162169689Skan default: 5163169689Skan break; 5164169689Skan } 5165169689Skan 5166169689Skan if (saw_lhs == 0) 5167169689Skan { 5168169689Skan enum gimplify_status gs; 5169169689Skan gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue); 5170169689Skan if (gs != GS_ALL_DONE) 5171169689Skan saw_lhs = -1; 5172169689Skan } 5173169689Skan 5174169689Skan return saw_lhs; 5175169689Skan} 5176169689Skan 5177169689Skan/* A subroutine of gimplify_omp_atomic. Implement the atomic operation as: 5178169689Skan 5179169689Skan oldval = *addr; 5180169689Skan repeat: 5181169689Skan newval = rhs; // with oldval replacing *addr in rhs 5182169689Skan oldval = __sync_val_compare_and_swap (addr, oldval, newval); 5183169689Skan if (oldval != newval) 5184169689Skan goto repeat; 5185169689Skan 5186169689Skan INDEX is log2 of the size of the data type, and thus usable to find the 5187169689Skan index of the builtin decl. */ 5188169689Skan 5189169689Skanstatic enum gimplify_status 5190169689Skangimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr, 5191169689Skan tree rhs, int index) 5192169689Skan{ 5193169689Skan tree oldval, oldival, oldival2, newval, newival, label; 5194169689Skan tree type, itype, cmpxchg, args, x, iaddr; 5195169689Skan 5196169689Skan cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1]; 5197169689Skan type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); 5198169689Skan itype = TREE_TYPE (TREE_TYPE (cmpxchg)); 5199169689Skan 5200169689Skan if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing) 5201169689Skan return GS_UNHANDLED; 5202169689Skan 5203169689Skan oldval = create_tmp_var (type, NULL); 5204169689Skan newval = create_tmp_var (type, NULL); 5205169689Skan 5206169689Skan /* Precompute as much of RHS as possible. In the same walk, replace 5207169689Skan occurrences of the lhs value with our temporary. */ 5208169689Skan if (goa_stabilize_expr (&rhs, pre_p, addr, oldval) < 0) 5209169689Skan return GS_ERROR; 5210169689Skan 5211169689Skan x = build_fold_indirect_ref (addr); 5212169689Skan x = build2 (MODIFY_EXPR, void_type_node, oldval, x); 5213169689Skan gimplify_and_add (x, pre_p); 5214169689Skan 5215169689Skan /* For floating-point values, we'll need to view-convert them to integers 5216169689Skan so that we can perform the atomic compare and swap. Simplify the 5217169689Skan following code by always setting up the "i"ntegral variables. */ 5218169689Skan if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) 5219169689Skan { 5220169689Skan oldival = oldval; 5221169689Skan newival = newval; 5222169689Skan iaddr = addr; 5223169689Skan } 5224169689Skan else 5225169689Skan { 5226169689Skan oldival = create_tmp_var (itype, NULL); 5227169689Skan newival = create_tmp_var (itype, NULL); 5228169689Skan 5229169689Skan x = build1 (VIEW_CONVERT_EXPR, itype, oldval); 5230169689Skan x = build2 (MODIFY_EXPR, void_type_node, oldival, x); 5231169689Skan gimplify_and_add (x, pre_p); 5232169689Skan iaddr = fold_convert (build_pointer_type (itype), addr); 5233169689Skan } 5234169689Skan 5235169689Skan oldival2 = create_tmp_var (itype, NULL); 5236169689Skan 5237169689Skan label = create_artificial_label (); 5238169689Skan x = build1 (LABEL_EXPR, void_type_node, label); 5239169689Skan gimplify_and_add (x, pre_p); 5240169689Skan 5241169689Skan x = build2 (MODIFY_EXPR, void_type_node, newval, rhs); 5242169689Skan gimplify_and_add (x, pre_p); 5243169689Skan 5244169689Skan if (newval != newival) 5245169689Skan { 5246169689Skan x = build1 (VIEW_CONVERT_EXPR, itype, newval); 5247169689Skan x = build2 (MODIFY_EXPR, void_type_node, newival, x); 5248169689Skan gimplify_and_add (x, pre_p); 5249169689Skan } 5250169689Skan 5251169689Skan x = build2 (MODIFY_EXPR, void_type_node, oldival2, 5252169689Skan fold_convert (itype, oldival)); 5253169689Skan gimplify_and_add (x, pre_p); 5254169689Skan 5255169689Skan args = tree_cons (NULL, fold_convert (itype, newival), NULL); 5256169689Skan args = tree_cons (NULL, fold_convert (itype, oldival), args); 5257169689Skan args = tree_cons (NULL, iaddr, args); 5258169689Skan x = build_function_call_expr (cmpxchg, args); 5259169689Skan if (oldval == oldival) 5260169689Skan x = fold_convert (type, x); 5261169689Skan x = build2 (MODIFY_EXPR, void_type_node, oldival, x); 5262169689Skan gimplify_and_add (x, pre_p); 5263169689Skan 5264169689Skan /* For floating point, be prepared for the loop backedge. */ 5265169689Skan if (oldval != oldival) 5266169689Skan { 5267169689Skan x = build1 (VIEW_CONVERT_EXPR, type, oldival); 5268169689Skan x = build2 (MODIFY_EXPR, void_type_node, oldval, x); 5269169689Skan gimplify_and_add (x, pre_p); 5270169689Skan } 5271169689Skan 5272169689Skan /* Note that we always perform the comparison as an integer, even for 5273169689Skan floating point. This allows the atomic operation to properly 5274169689Skan succeed even with NaNs and -0.0. */ 5275169689Skan x = build3 (COND_EXPR, void_type_node, 5276169689Skan build2 (NE_EXPR, boolean_type_node, oldival, oldival2), 5277169689Skan build1 (GOTO_EXPR, void_type_node, label), NULL); 5278169689Skan gimplify_and_add (x, pre_p); 5279169689Skan 5280169689Skan *expr_p = NULL; 5281169689Skan return GS_ALL_DONE; 5282169689Skan} 5283169689Skan 5284169689Skan/* A subroutine of gimplify_omp_atomic. Implement the atomic operation as: 5285169689Skan 5286169689Skan GOMP_atomic_start (); 5287169689Skan *addr = rhs; 5288169689Skan GOMP_atomic_end (); 5289169689Skan 5290169689Skan The result is not globally atomic, but works so long as all parallel 5291169689Skan references are within #pragma omp atomic directives. According to 5292169689Skan responses received from omp@openmp.org, appears to be within spec. 5293169689Skan Which makes sense, since that's how several other compilers handle 5294169689Skan this situation as well. */ 5295169689Skan 5296169689Skanstatic enum gimplify_status 5297169689Skangimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs) 5298169689Skan{ 5299169689Skan tree t; 5300169689Skan 5301169689Skan t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START]; 5302169689Skan t = build_function_call_expr (t, NULL); 5303169689Skan gimplify_and_add (t, pre_p); 5304169689Skan 5305169689Skan t = build_fold_indirect_ref (addr); 5306169689Skan t = build2 (MODIFY_EXPR, void_type_node, t, rhs); 5307169689Skan gimplify_and_add (t, pre_p); 5308169689Skan 5309169689Skan t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END]; 5310169689Skan t = build_function_call_expr (t, NULL); 5311169689Skan gimplify_and_add (t, pre_p); 5312169689Skan 5313169689Skan *expr_p = NULL; 5314169689Skan return GS_ALL_DONE; 5315169689Skan} 5316169689Skan 5317169689Skan/* Gimplify an OMP_ATOMIC statement. */ 5318169689Skan 5319169689Skanstatic enum gimplify_status 5320169689Skangimplify_omp_atomic (tree *expr_p, tree *pre_p) 5321169689Skan{ 5322169689Skan tree addr = TREE_OPERAND (*expr_p, 0); 5323169689Skan tree rhs = TREE_OPERAND (*expr_p, 1); 5324169689Skan tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); 5325169689Skan HOST_WIDE_INT index; 5326169689Skan 5327169689Skan /* Make sure the type is one of the supported sizes. */ 5328169689Skan index = tree_low_cst (TYPE_SIZE_UNIT (type), 1); 5329169689Skan index = exact_log2 (index); 5330169689Skan if (index >= 0 && index <= 4) 5331169689Skan { 5332169689Skan enum gimplify_status gs; 5333169689Skan unsigned int align; 5334169689Skan 5335169689Skan if (DECL_P (TREE_OPERAND (addr, 0))) 5336169689Skan align = DECL_ALIGN_UNIT (TREE_OPERAND (addr, 0)); 5337169689Skan else if (TREE_CODE (TREE_OPERAND (addr, 0)) == COMPONENT_REF 5338169689Skan && TREE_CODE (TREE_OPERAND (TREE_OPERAND (addr, 0), 1)) 5339169689Skan == FIELD_DECL) 5340169689Skan align = DECL_ALIGN_UNIT (TREE_OPERAND (TREE_OPERAND (addr, 0), 1)); 5341169689Skan else 5342169689Skan align = TYPE_ALIGN_UNIT (type); 5343169689Skan 5344169689Skan /* __sync builtins require strict data alignment. */ 5345169689Skan if (exact_log2 (align) >= index) 5346169689Skan { 5347169689Skan /* When possible, use specialized atomic update functions. */ 5348169689Skan if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) 5349169689Skan { 5350169689Skan gs = gimplify_omp_atomic_fetch_op (expr_p, addr, rhs, index); 5351169689Skan if (gs != GS_UNHANDLED) 5352169689Skan return gs; 5353169689Skan } 5354169689Skan 5355169689Skan /* If we don't have specialized __sync builtins, try and implement 5356169689Skan as a compare and swap loop. */ 5357169689Skan gs = gimplify_omp_atomic_pipeline (expr_p, pre_p, addr, rhs, index); 5358169689Skan if (gs != GS_UNHANDLED) 5359169689Skan return gs; 5360169689Skan } 5361169689Skan } 5362169689Skan 5363169689Skan /* The ultimate fallback is wrapping the operation in a mutex. */ 5364169689Skan return gimplify_omp_atomic_mutex (expr_p, pre_p, addr, rhs); 5365169689Skan} 5366169689Skan 5367169689Skan/* Gimplifies the expression tree pointed to by EXPR_P. Return 0 if 5368169689Skan gimplification failed. 5369169689Skan 5370169689Skan PRE_P points to the list where side effects that must happen before 5371169689Skan EXPR should be stored. 5372169689Skan 5373169689Skan POST_P points to the list where side effects that must happen after 5374169689Skan EXPR should be stored, or NULL if there is no suitable list. In 5375169689Skan that case, we copy the result to a temporary, emit the 5376169689Skan post-effects, and then return the temporary. 5377169689Skan 5378169689Skan GIMPLE_TEST_F points to a function that takes a tree T and 5379169689Skan returns nonzero if T is in the GIMPLE form requested by the 5380169689Skan caller. The GIMPLE predicates are in tree-gimple.c. 5381169689Skan 5382169689Skan This test is used twice. Before gimplification, the test is 5383169689Skan invoked to determine whether *EXPR_P is already gimple enough. If 5384169689Skan that fails, *EXPR_P is gimplified according to its code and 5385169689Skan GIMPLE_TEST_F is called again. If the test still fails, then a new 5386169689Skan temporary variable is created and assigned the value of the 5387169689Skan gimplified expression. 5388169689Skan 5389169689Skan FALLBACK tells the function what sort of a temporary we want. If the 1 5390169689Skan bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK. 5391169689Skan If both are set, either is OK, but an lvalue is preferable. 5392169689Skan 5393169689Skan The return value is either GS_ERROR or GS_ALL_DONE, since this function 5394169689Skan iterates until solution. */ 5395169689Skan 5396169689Skanenum gimplify_status 5397169689Skangimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, 5398169689Skan bool (* gimple_test_f) (tree), fallback_t fallback) 5399169689Skan{ 5400169689Skan tree tmp; 5401169689Skan tree internal_pre = NULL_TREE; 5402169689Skan tree internal_post = NULL_TREE; 5403169689Skan tree save_expr; 5404169689Skan int is_statement = (pre_p == NULL); 5405169689Skan location_t saved_location; 5406169689Skan enum gimplify_status ret; 5407169689Skan 5408169689Skan save_expr = *expr_p; 5409169689Skan if (save_expr == NULL_TREE) 5410169689Skan return GS_ALL_DONE; 5411169689Skan 5412169689Skan /* We used to check the predicate here and return immediately if it 5413169689Skan succeeds. This is wrong; the design is for gimplification to be 5414169689Skan idempotent, and for the predicates to only test for valid forms, not 5415169689Skan whether they are fully simplified. */ 5416169689Skan 5417169689Skan /* Set up our internal queues if needed. */ 5418169689Skan if (pre_p == NULL) 5419169689Skan pre_p = &internal_pre; 5420169689Skan if (post_p == NULL) 5421169689Skan post_p = &internal_post; 5422169689Skan 5423169689Skan saved_location = input_location; 5424169689Skan if (save_expr != error_mark_node 5425169689Skan && EXPR_HAS_LOCATION (*expr_p)) 5426169689Skan input_location = EXPR_LOCATION (*expr_p); 5427169689Skan 5428169689Skan /* Loop over the specific gimplifiers until the toplevel node 5429169689Skan remains the same. */ 5430169689Skan do 5431169689Skan { 5432169689Skan /* Strip away as many useless type conversions as possible 5433169689Skan at the toplevel. */ 5434169689Skan STRIP_USELESS_TYPE_CONVERSION (*expr_p); 5435169689Skan 5436169689Skan /* Remember the expr. */ 5437169689Skan save_expr = *expr_p; 5438169689Skan 5439169689Skan /* Die, die, die, my darling. */ 5440169689Skan if (save_expr == error_mark_node 5441169689Skan || (TREE_TYPE (save_expr) 5442169689Skan && TREE_TYPE (save_expr) == error_mark_node)) 5443169689Skan { 5444169689Skan ret = GS_ERROR; 5445169689Skan break; 5446169689Skan } 5447169689Skan 5448169689Skan /* Do any language-specific gimplification. */ 5449169689Skan ret = lang_hooks.gimplify_expr (expr_p, pre_p, post_p); 5450169689Skan if (ret == GS_OK) 5451169689Skan { 5452169689Skan if (*expr_p == NULL_TREE) 5453169689Skan break; 5454169689Skan if (*expr_p != save_expr) 5455169689Skan continue; 5456169689Skan } 5457169689Skan else if (ret != GS_UNHANDLED) 5458169689Skan break; 5459169689Skan 5460169689Skan ret = GS_OK; 5461169689Skan switch (TREE_CODE (*expr_p)) 5462169689Skan { 5463169689Skan /* First deal with the special cases. */ 5464169689Skan 5465169689Skan case POSTINCREMENT_EXPR: 5466169689Skan case POSTDECREMENT_EXPR: 5467169689Skan case PREINCREMENT_EXPR: 5468169689Skan case PREDECREMENT_EXPR: 5469169689Skan ret = gimplify_self_mod_expr (expr_p, pre_p, post_p, 5470169689Skan fallback != fb_none); 5471169689Skan break; 5472169689Skan 5473169689Skan case ARRAY_REF: 5474169689Skan case ARRAY_RANGE_REF: 5475169689Skan case REALPART_EXPR: 5476169689Skan case IMAGPART_EXPR: 5477169689Skan case COMPONENT_REF: 5478169689Skan case VIEW_CONVERT_EXPR: 5479169689Skan ret = gimplify_compound_lval (expr_p, pre_p, post_p, 5480169689Skan fallback ? fallback : fb_rvalue); 5481169689Skan break; 5482169689Skan 5483169689Skan case COND_EXPR: 5484169689Skan ret = gimplify_cond_expr (expr_p, pre_p, fallback); 5485169689Skan /* C99 code may assign to an array in a structure value of a 5486169689Skan conditional expression, and this has undefined behavior 5487169689Skan only on execution, so create a temporary if an lvalue is 5488169689Skan required. */ 5489169689Skan if (fallback == fb_lvalue) 5490169689Skan { 5491169689Skan *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); 5492169689Skan lang_hooks.mark_addressable (*expr_p); 5493169689Skan } 5494169689Skan break; 5495169689Skan 5496169689Skan case CALL_EXPR: 5497169689Skan ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); 5498169689Skan /* C99 code may assign to an array in a structure returned 5499169689Skan from a function, and this has undefined behavior only on 5500169689Skan execution, so create a temporary if an lvalue is 5501169689Skan required. */ 5502169689Skan if (fallback == fb_lvalue) 5503169689Skan { 5504169689Skan *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); 5505169689Skan lang_hooks.mark_addressable (*expr_p); 5506169689Skan } 5507169689Skan break; 5508169689Skan 5509169689Skan case TREE_LIST: 5510169689Skan gcc_unreachable (); 5511169689Skan 5512169689Skan case COMPOUND_EXPR: 5513169689Skan ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); 5514169689Skan break; 5515169689Skan 5516169689Skan case MODIFY_EXPR: 5517169689Skan case INIT_EXPR: 5518169689Skan ret = gimplify_modify_expr (expr_p, pre_p, post_p, 5519169689Skan fallback != fb_none); 5520169689Skan 5521169689Skan /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer 5522169689Skan useful. */ 5523169689Skan if (*expr_p && TREE_CODE (*expr_p) == INIT_EXPR) 5524169689Skan TREE_SET_CODE (*expr_p, MODIFY_EXPR); 5525169689Skan break; 5526169689Skan 5527169689Skan case TRUTH_ANDIF_EXPR: 5528169689Skan case TRUTH_ORIF_EXPR: 5529169689Skan ret = gimplify_boolean_expr (expr_p); 5530169689Skan break; 5531169689Skan 5532169689Skan case TRUTH_NOT_EXPR: 5533169689Skan TREE_OPERAND (*expr_p, 0) 5534169689Skan = gimple_boolify (TREE_OPERAND (*expr_p, 0)); 5535169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5536169689Skan is_gimple_val, fb_rvalue); 5537169689Skan recalculate_side_effects (*expr_p); 5538169689Skan break; 5539169689Skan 5540169689Skan case ADDR_EXPR: 5541169689Skan ret = gimplify_addr_expr (expr_p, pre_p, post_p); 5542169689Skan break; 5543169689Skan 5544169689Skan case VA_ARG_EXPR: 5545169689Skan ret = gimplify_va_arg_expr (expr_p, pre_p, post_p); 5546169689Skan break; 5547169689Skan 5548169689Skan case CONVERT_EXPR: 5549169689Skan case NOP_EXPR: 5550169689Skan if (IS_EMPTY_STMT (*expr_p)) 5551169689Skan { 5552169689Skan ret = GS_ALL_DONE; 5553169689Skan break; 5554169689Skan } 5555169689Skan 5556169689Skan if (VOID_TYPE_P (TREE_TYPE (*expr_p)) 5557169689Skan || fallback == fb_none) 5558169689Skan { 5559169689Skan /* Just strip a conversion to void (or in void context) and 5560169689Skan try again. */ 5561169689Skan *expr_p = TREE_OPERAND (*expr_p, 0); 5562169689Skan break; 5563169689Skan } 5564169689Skan 5565169689Skan ret = gimplify_conversion (expr_p); 5566169689Skan if (ret == GS_ERROR) 5567169689Skan break; 5568169689Skan if (*expr_p != save_expr) 5569169689Skan break; 5570169689Skan /* FALLTHRU */ 5571169689Skan 5572169689Skan case FIX_TRUNC_EXPR: 5573169689Skan case FIX_CEIL_EXPR: 5574169689Skan case FIX_FLOOR_EXPR: 5575169689Skan case FIX_ROUND_EXPR: 5576169689Skan /* unary_expr: ... | '(' cast ')' val | ... */ 5577169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5578169689Skan is_gimple_val, fb_rvalue); 5579169689Skan recalculate_side_effects (*expr_p); 5580169689Skan break; 5581169689Skan 5582169689Skan case INDIRECT_REF: 5583169689Skan *expr_p = fold_indirect_ref (*expr_p); 5584169689Skan if (*expr_p != save_expr) 5585169689Skan break; 5586169689Skan /* else fall through. */ 5587169689Skan case ALIGN_INDIRECT_REF: 5588169689Skan case MISALIGNED_INDIRECT_REF: 5589169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5590169689Skan is_gimple_reg, fb_rvalue); 5591169689Skan recalculate_side_effects (*expr_p); 5592169689Skan break; 5593169689Skan 5594169689Skan /* Constants need not be gimplified. */ 5595169689Skan case INTEGER_CST: 5596169689Skan case REAL_CST: 5597169689Skan case STRING_CST: 5598169689Skan case COMPLEX_CST: 5599169689Skan case VECTOR_CST: 5600169689Skan ret = GS_ALL_DONE; 5601169689Skan break; 5602169689Skan 5603169689Skan case CONST_DECL: 5604169689Skan /* If we require an lvalue, such as for ADDR_EXPR, retain the 5605169689Skan CONST_DECL node. Otherwise the decl is replaceable by its 5606169689Skan value. */ 5607169689Skan /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */ 5608169689Skan if (fallback & fb_lvalue) 5609169689Skan ret = GS_ALL_DONE; 5610169689Skan else 5611169689Skan *expr_p = DECL_INITIAL (*expr_p); 5612169689Skan break; 5613169689Skan 5614169689Skan case DECL_EXPR: 5615169689Skan ret = gimplify_decl_expr (expr_p); 5616169689Skan break; 5617169689Skan 5618169689Skan case EXC_PTR_EXPR: 5619169689Skan /* FIXME make this a decl. */ 5620169689Skan ret = GS_ALL_DONE; 5621169689Skan break; 5622169689Skan 5623169689Skan case BIND_EXPR: 5624169689Skan ret = gimplify_bind_expr (expr_p, pre_p); 5625169689Skan break; 5626169689Skan 5627169689Skan case LOOP_EXPR: 5628169689Skan ret = gimplify_loop_expr (expr_p, pre_p); 5629169689Skan break; 5630169689Skan 5631169689Skan case SWITCH_EXPR: 5632169689Skan ret = gimplify_switch_expr (expr_p, pre_p); 5633169689Skan break; 5634169689Skan 5635169689Skan case EXIT_EXPR: 5636169689Skan ret = gimplify_exit_expr (expr_p); 5637169689Skan break; 5638169689Skan 5639169689Skan case GOTO_EXPR: 5640169689Skan /* If the target is not LABEL, then it is a computed jump 5641169689Skan and the target needs to be gimplified. */ 5642169689Skan if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL) 5643169689Skan ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p, 5644169689Skan NULL, is_gimple_val, fb_rvalue); 5645169689Skan break; 5646169689Skan 5647169689Skan case LABEL_EXPR: 5648169689Skan ret = GS_ALL_DONE; 5649169689Skan gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p)) 5650169689Skan == current_function_decl); 5651169689Skan break; 5652169689Skan 5653169689Skan case CASE_LABEL_EXPR: 5654169689Skan ret = gimplify_case_label_expr (expr_p); 5655169689Skan break; 5656169689Skan 5657169689Skan case RETURN_EXPR: 5658169689Skan ret = gimplify_return_expr (*expr_p, pre_p); 5659169689Skan break; 5660169689Skan 5661169689Skan case CONSTRUCTOR: 5662169689Skan /* Don't reduce this in place; let gimplify_init_constructor work its 5663169689Skan magic. Buf if we're just elaborating this for side effects, just 5664169689Skan gimplify any element that has side-effects. */ 5665169689Skan if (fallback == fb_none) 5666169689Skan { 5667169689Skan unsigned HOST_WIDE_INT ix; 5668169689Skan constructor_elt *ce; 5669169689Skan tree temp = NULL_TREE; 5670169689Skan for (ix = 0; 5671169689Skan VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (*expr_p), 5672169689Skan ix, ce); 5673169689Skan ix++) 5674169689Skan if (TREE_SIDE_EFFECTS (ce->value)) 5675169689Skan append_to_statement_list (ce->value, &temp); 5676169689Skan 5677169689Skan *expr_p = temp; 5678169689Skan ret = GS_OK; 5679169689Skan } 5680169689Skan /* C99 code may assign to an array in a constructed 5681169689Skan structure or union, and this has undefined behavior only 5682169689Skan on execution, so create a temporary if an lvalue is 5683169689Skan required. */ 5684169689Skan else if (fallback == fb_lvalue) 5685169689Skan { 5686169689Skan *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); 5687169689Skan lang_hooks.mark_addressable (*expr_p); 5688169689Skan } 5689169689Skan else 5690169689Skan ret = GS_ALL_DONE; 5691169689Skan break; 5692169689Skan 5693169689Skan /* The following are special cases that are not handled by the 5694169689Skan original GIMPLE grammar. */ 5695169689Skan 5696169689Skan /* SAVE_EXPR nodes are converted into a GIMPLE identifier and 5697169689Skan eliminated. */ 5698169689Skan case SAVE_EXPR: 5699169689Skan ret = gimplify_save_expr (expr_p, pre_p, post_p); 5700169689Skan break; 5701169689Skan 5702169689Skan case BIT_FIELD_REF: 5703169689Skan { 5704169689Skan enum gimplify_status r0, r1, r2; 5705169689Skan 5706169689Skan r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5707169689Skan is_gimple_lvalue, fb_either); 5708169689Skan r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 5709169689Skan is_gimple_val, fb_rvalue); 5710169689Skan r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p, 5711169689Skan is_gimple_val, fb_rvalue); 5712169689Skan recalculate_side_effects (*expr_p); 5713169689Skan 5714169689Skan ret = MIN (r0, MIN (r1, r2)); 5715169689Skan } 5716169689Skan break; 5717169689Skan 5718169689Skan case NON_LVALUE_EXPR: 5719169689Skan /* This should have been stripped above. */ 5720169689Skan gcc_unreachable (); 5721169689Skan 5722169689Skan case ASM_EXPR: 5723169689Skan ret = gimplify_asm_expr (expr_p, pre_p, post_p); 5724169689Skan break; 5725169689Skan 5726169689Skan case TRY_FINALLY_EXPR: 5727169689Skan case TRY_CATCH_EXPR: 5728169689Skan gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0)); 5729169689Skan gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1)); 5730169689Skan ret = GS_ALL_DONE; 5731169689Skan break; 5732169689Skan 5733169689Skan case CLEANUP_POINT_EXPR: 5734169689Skan ret = gimplify_cleanup_point_expr (expr_p, pre_p); 5735169689Skan break; 5736169689Skan 5737169689Skan case TARGET_EXPR: 5738169689Skan ret = gimplify_target_expr (expr_p, pre_p, post_p); 5739169689Skan break; 5740169689Skan 5741169689Skan case CATCH_EXPR: 5742169689Skan gimplify_to_stmt_list (&CATCH_BODY (*expr_p)); 5743169689Skan ret = GS_ALL_DONE; 5744169689Skan break; 5745169689Skan 5746169689Skan case EH_FILTER_EXPR: 5747169689Skan gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p)); 5748169689Skan ret = GS_ALL_DONE; 5749169689Skan break; 5750169689Skan 5751169689Skan case OBJ_TYPE_REF: 5752169689Skan { 5753169689Skan enum gimplify_status r0, r1; 5754169689Skan r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p, 5755169689Skan is_gimple_val, fb_rvalue); 5756169689Skan r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p, 5757169689Skan is_gimple_val, fb_rvalue); 5758169689Skan ret = MIN (r0, r1); 5759169689Skan } 5760169689Skan break; 5761169689Skan 5762169689Skan case LABEL_DECL: 5763169689Skan /* We get here when taking the address of a label. We mark 5764169689Skan the label as "forced"; meaning it can never be removed and 5765169689Skan it is a potential target for any computed goto. */ 5766169689Skan FORCED_LABEL (*expr_p) = 1; 5767169689Skan ret = GS_ALL_DONE; 5768169689Skan break; 5769169689Skan 5770169689Skan case STATEMENT_LIST: 5771169689Skan ret = gimplify_statement_list (expr_p, pre_p); 5772169689Skan break; 5773169689Skan 5774169689Skan case WITH_SIZE_EXPR: 5775169689Skan { 5776169689Skan gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 5777169689Skan post_p == &internal_post ? NULL : post_p, 5778169689Skan gimple_test_f, fallback); 5779169689Skan gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 5780169689Skan is_gimple_val, fb_rvalue); 5781169689Skan } 5782169689Skan break; 5783169689Skan 5784169689Skan case VAR_DECL: 5785169689Skan case PARM_DECL: 5786169689Skan ret = gimplify_var_or_parm_decl (expr_p); 5787169689Skan break; 5788169689Skan 5789169689Skan case RESULT_DECL: 5790169689Skan /* When within an OpenMP context, notice uses of variables. */ 5791169689Skan if (gimplify_omp_ctxp) 5792169689Skan omp_notice_variable (gimplify_omp_ctxp, *expr_p, true); 5793169689Skan ret = GS_ALL_DONE; 5794169689Skan break; 5795169689Skan 5796169689Skan case SSA_NAME: 5797169689Skan /* Allow callbacks into the gimplifier during optimization. */ 5798169689Skan ret = GS_ALL_DONE; 5799169689Skan break; 5800169689Skan 5801169689Skan case OMP_PARALLEL: 5802169689Skan ret = gimplify_omp_parallel (expr_p, pre_p); 5803169689Skan break; 5804169689Skan 5805169689Skan case OMP_FOR: 5806169689Skan ret = gimplify_omp_for (expr_p, pre_p); 5807169689Skan break; 5808169689Skan 5809169689Skan case OMP_SECTIONS: 5810169689Skan case OMP_SINGLE: 5811169689Skan ret = gimplify_omp_workshare (expr_p, pre_p); 5812169689Skan break; 5813169689Skan 5814169689Skan case OMP_SECTION: 5815169689Skan case OMP_MASTER: 5816169689Skan case OMP_ORDERED: 5817169689Skan case OMP_CRITICAL: 5818169689Skan gimplify_to_stmt_list (&OMP_BODY (*expr_p)); 5819169689Skan break; 5820169689Skan 5821169689Skan case OMP_ATOMIC: 5822169689Skan ret = gimplify_omp_atomic (expr_p, pre_p); 5823169689Skan break; 5824169689Skan 5825169689Skan case OMP_RETURN: 5826169689Skan case OMP_CONTINUE: 5827169689Skan ret = GS_ALL_DONE; 5828169689Skan break; 5829169689Skan 5830169689Skan default: 5831169689Skan switch (TREE_CODE_CLASS (TREE_CODE (*expr_p))) 5832169689Skan { 5833169689Skan case tcc_comparison: 5834169689Skan /* Handle comparison of objects of non scalar mode aggregates 5835169689Skan with a call to memcmp. It would be nice to only have to do 5836169689Skan this for variable-sized objects, but then we'd have to allow 5837169689Skan the same nest of reference nodes we allow for MODIFY_EXPR and 5838169689Skan that's too complex. 5839169689Skan 5840169689Skan Compare scalar mode aggregates as scalar mode values. Using 5841169689Skan memcmp for them would be very inefficient at best, and is 5842169689Skan plain wrong if bitfields are involved. */ 5843169689Skan 5844169689Skan { 5845169689Skan tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); 5846169689Skan 5847169689Skan if (!AGGREGATE_TYPE_P (type)) 5848169689Skan goto expr_2; 5849169689Skan else if (TYPE_MODE (type) != BLKmode) 5850169689Skan ret = gimplify_scalar_mode_aggregate_compare (expr_p); 5851169689Skan else 5852169689Skan ret = gimplify_variable_sized_compare (expr_p); 5853169689Skan 5854169689Skan break; 5855169689Skan } 5856169689Skan 5857169689Skan /* If *EXPR_P does not need to be special-cased, handle it 5858169689Skan according to its class. */ 5859169689Skan case tcc_unary: 5860169689Skan ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 5861169689Skan post_p, is_gimple_val, fb_rvalue); 5862169689Skan break; 5863169689Skan 5864169689Skan case tcc_binary: 5865169689Skan expr_2: 5866169689Skan { 5867169689Skan enum gimplify_status r0, r1; 5868169689Skan 5869169689Skan r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 5870169689Skan post_p, is_gimple_val, fb_rvalue); 5871169689Skan r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 5872169689Skan post_p, is_gimple_val, fb_rvalue); 5873169689Skan 5874169689Skan ret = MIN (r0, r1); 5875169689Skan break; 5876169689Skan } 5877169689Skan 5878169689Skan case tcc_declaration: 5879169689Skan case tcc_constant: 5880169689Skan ret = GS_ALL_DONE; 5881169689Skan goto dont_recalculate; 5882169689Skan 5883169689Skan default: 5884169689Skan gcc_assert (TREE_CODE (*expr_p) == TRUTH_AND_EXPR 5885169689Skan || TREE_CODE (*expr_p) == TRUTH_OR_EXPR 5886169689Skan || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR); 5887169689Skan goto expr_2; 5888169689Skan } 5889169689Skan 5890169689Skan recalculate_side_effects (*expr_p); 5891169689Skan dont_recalculate: 5892169689Skan break; 5893169689Skan } 5894169689Skan 5895169689Skan /* If we replaced *expr_p, gimplify again. */ 5896169689Skan if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr)) 5897169689Skan ret = GS_ALL_DONE; 5898169689Skan } 5899169689Skan while (ret == GS_OK); 5900169689Skan 5901169689Skan /* If we encountered an error_mark somewhere nested inside, either 5902169689Skan stub out the statement or propagate the error back out. */ 5903169689Skan if (ret == GS_ERROR) 5904169689Skan { 5905169689Skan if (is_statement) 5906169689Skan *expr_p = NULL; 5907169689Skan goto out; 5908169689Skan } 5909169689Skan 5910169689Skan /* This was only valid as a return value from the langhook, which 5911169689Skan we handled. Make sure it doesn't escape from any other context. */ 5912169689Skan gcc_assert (ret != GS_UNHANDLED); 5913169689Skan 5914169689Skan if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p)) 5915169689Skan { 5916169689Skan /* We aren't looking for a value, and we don't have a valid 5917169689Skan statement. If it doesn't have side-effects, throw it away. */ 5918169689Skan if (!TREE_SIDE_EFFECTS (*expr_p)) 5919169689Skan *expr_p = NULL; 5920169689Skan else if (!TREE_THIS_VOLATILE (*expr_p)) 5921169689Skan { 5922169689Skan /* This is probably a _REF that contains something nested that 5923169689Skan has side effects. Recurse through the operands to find it. */ 5924169689Skan enum tree_code code = TREE_CODE (*expr_p); 5925169689Skan 5926169689Skan switch (code) 5927169689Skan { 5928169689Skan case COMPONENT_REF: 5929169689Skan case REALPART_EXPR: 5930169689Skan case IMAGPART_EXPR: 5931169689Skan case VIEW_CONVERT_EXPR: 5932169689Skan gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5933169689Skan gimple_test_f, fallback); 5934169689Skan break; 5935169689Skan 5936169689Skan case ARRAY_REF: 5937169689Skan case ARRAY_RANGE_REF: 5938169689Skan gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5939169689Skan gimple_test_f, fallback); 5940169689Skan gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 5941169689Skan gimple_test_f, fallback); 5942169689Skan break; 5943169689Skan 5944169689Skan default: 5945169689Skan /* Anything else with side-effects must be converted to 5946169689Skan a valid statement before we get here. */ 5947169689Skan gcc_unreachable (); 5948169689Skan } 5949169689Skan 5950169689Skan *expr_p = NULL; 5951169689Skan } 5952169689Skan else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)) 5953169689Skan && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode) 5954169689Skan { 5955169689Skan /* Historically, the compiler has treated a bare reference 5956169689Skan to a non-BLKmode volatile lvalue as forcing a load. */ 5957169689Skan tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p)); 5958169689Skan /* Normally, we do not want to create a temporary for a 5959169689Skan TREE_ADDRESSABLE type because such a type should not be 5960169689Skan copied by bitwise-assignment. However, we make an 5961169689Skan exception here, as all we are doing here is ensuring that 5962169689Skan we read the bytes that make up the type. We use 5963169689Skan create_tmp_var_raw because create_tmp_var will abort when 5964169689Skan given a TREE_ADDRESSABLE type. */ 5965169689Skan tree tmp = create_tmp_var_raw (type, "vol"); 5966169689Skan gimple_add_tmp_var (tmp); 5967169689Skan *expr_p = build2 (MODIFY_EXPR, type, tmp, *expr_p); 5968169689Skan } 5969169689Skan else 5970169689Skan /* We can't do anything useful with a volatile reference to 5971169689Skan an incomplete type, so just throw it away. Likewise for 5972169689Skan a BLKmode type, since any implicit inner load should 5973169689Skan already have been turned into an explicit one by the 5974169689Skan gimplification process. */ 5975169689Skan *expr_p = NULL; 5976169689Skan } 5977169689Skan 5978169689Skan /* If we are gimplifying at the statement level, we're done. Tack 5979169689Skan everything together and replace the original statement with the 5980169689Skan gimplified form. */ 5981169689Skan if (fallback == fb_none || is_statement) 5982169689Skan { 5983169689Skan if (internal_pre || internal_post) 5984169689Skan { 5985169689Skan append_to_statement_list (*expr_p, &internal_pre); 5986169689Skan append_to_statement_list (internal_post, &internal_pre); 5987169689Skan annotate_all_with_locus (&internal_pre, input_location); 5988169689Skan *expr_p = internal_pre; 5989169689Skan } 5990169689Skan else if (!*expr_p) 5991169689Skan ; 5992169689Skan else if (TREE_CODE (*expr_p) == STATEMENT_LIST) 5993169689Skan annotate_all_with_locus (expr_p, input_location); 5994169689Skan else 5995169689Skan annotate_one_with_locus (*expr_p, input_location); 5996169689Skan goto out; 5997169689Skan } 5998169689Skan 5999169689Skan /* Otherwise we're gimplifying a subexpression, so the resulting value is 6000169689Skan interesting. */ 6001169689Skan 6002169689Skan /* If it's sufficiently simple already, we're done. Unless we are 6003169689Skan handling some post-effects internally; if that's the case, we need to 6004169689Skan copy into a temp before adding the post-effects to the tree. */ 6005169689Skan if (!internal_post && (*gimple_test_f) (*expr_p)) 6006169689Skan goto out; 6007169689Skan 6008169689Skan /* Otherwise, we need to create a new temporary for the gimplified 6009169689Skan expression. */ 6010169689Skan 6011169689Skan /* We can't return an lvalue if we have an internal postqueue. The 6012169689Skan object the lvalue refers to would (probably) be modified by the 6013169689Skan postqueue; we need to copy the value out first, which means an 6014169689Skan rvalue. */ 6015169689Skan if ((fallback & fb_lvalue) && !internal_post 6016169689Skan && is_gimple_addressable (*expr_p)) 6017169689Skan { 6018169689Skan /* An lvalue will do. Take the address of the expression, store it 6019169689Skan in a temporary, and replace the expression with an INDIRECT_REF of 6020169689Skan that temporary. */ 6021169689Skan tmp = build_fold_addr_expr (*expr_p); 6022169689Skan gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); 6023169689Skan *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp); 6024169689Skan } 6025169689Skan else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p)) 6026169689Skan { 6027169689Skan gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p))); 6028169689Skan 6029169689Skan /* An rvalue will do. Assign the gimplified expression into a new 6030169689Skan temporary TMP and replace the original expression with TMP. */ 6031169689Skan 6032169689Skan if (internal_post || (fallback & fb_lvalue)) 6033169689Skan /* The postqueue might change the value of the expression between 6034169689Skan the initialization and use of the temporary, so we can't use a 6035169689Skan formal temp. FIXME do we care? */ 6036169689Skan *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); 6037169689Skan else 6038169689Skan *expr_p = get_formal_tmp_var (*expr_p, pre_p); 6039169689Skan 6040169689Skan if (TREE_CODE (*expr_p) != SSA_NAME) 6041169689Skan DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1; 6042169689Skan } 6043169689Skan else 6044169689Skan { 6045169689Skan#ifdef ENABLE_CHECKING 6046169689Skan if (!(fallback & fb_mayfail)) 6047169689Skan { 6048169689Skan fprintf (stderr, "gimplification failed:\n"); 6049169689Skan print_generic_expr (stderr, *expr_p, 0); 6050169689Skan debug_tree (*expr_p); 6051169689Skan internal_error ("gimplification failed"); 6052169689Skan } 6053169689Skan#endif 6054169689Skan gcc_assert (fallback & fb_mayfail); 6055169689Skan /* If this is an asm statement, and the user asked for the 6056169689Skan impossible, don't die. Fail and let gimplify_asm_expr 6057169689Skan issue an error. */ 6058169689Skan ret = GS_ERROR; 6059169689Skan goto out; 6060169689Skan } 6061169689Skan 6062169689Skan /* Make sure the temporary matches our predicate. */ 6063169689Skan gcc_assert ((*gimple_test_f) (*expr_p)); 6064169689Skan 6065169689Skan if (internal_post) 6066169689Skan { 6067169689Skan annotate_all_with_locus (&internal_post, input_location); 6068169689Skan append_to_statement_list (internal_post, pre_p); 6069169689Skan } 6070169689Skan 6071169689Skan out: 6072169689Skan input_location = saved_location; 6073169689Skan return ret; 6074169689Skan} 6075169689Skan 6076169689Skan/* Look through TYPE for variable-sized objects and gimplify each such 6077169689Skan size that we find. Add to LIST_P any statements generated. */ 6078169689Skan 6079169689Skanvoid 6080169689Skangimplify_type_sizes (tree type, tree *list_p) 6081169689Skan{ 6082169689Skan tree field, t; 6083169689Skan 6084169689Skan if (type == NULL || type == error_mark_node) 6085169689Skan return; 6086169689Skan 6087169689Skan /* We first do the main variant, then copy into any other variants. */ 6088169689Skan type = TYPE_MAIN_VARIANT (type); 6089169689Skan 6090169689Skan /* Avoid infinite recursion. */ 6091169689Skan if (TYPE_SIZES_GIMPLIFIED (type)) 6092169689Skan return; 6093169689Skan 6094169689Skan TYPE_SIZES_GIMPLIFIED (type) = 1; 6095169689Skan 6096169689Skan switch (TREE_CODE (type)) 6097169689Skan { 6098169689Skan case INTEGER_TYPE: 6099169689Skan case ENUMERAL_TYPE: 6100169689Skan case BOOLEAN_TYPE: 6101169689Skan case REAL_TYPE: 6102169689Skan gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p); 6103169689Skan gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p); 6104169689Skan 6105169689Skan for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 6106169689Skan { 6107169689Skan TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); 6108169689Skan TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); 6109169689Skan } 6110169689Skan break; 6111169689Skan 6112169689Skan case ARRAY_TYPE: 6113169689Skan /* These types may not have declarations, so handle them here. */ 6114169689Skan gimplify_type_sizes (TREE_TYPE (type), list_p); 6115169689Skan gimplify_type_sizes (TYPE_DOMAIN (type), list_p); 6116169689Skan break; 6117169689Skan 6118169689Skan case RECORD_TYPE: 6119169689Skan case UNION_TYPE: 6120169689Skan case QUAL_UNION_TYPE: 6121169689Skan for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 6122169689Skan if (TREE_CODE (field) == FIELD_DECL) 6123169689Skan { 6124169689Skan gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); 6125169689Skan gimplify_type_sizes (TREE_TYPE (field), list_p); 6126169689Skan } 6127169689Skan break; 6128169689Skan 6129169689Skan case POINTER_TYPE: 6130169689Skan case REFERENCE_TYPE: 6131169689Skan /* We used to recurse on the pointed-to type here, which turned out to 6132169689Skan be incorrect because its definition might refer to variables not 6133169689Skan yet initialized at this point if a forward declaration is involved. 6134169689Skan 6135169689Skan It was actually useful for anonymous pointed-to types to ensure 6136169689Skan that the sizes evaluation dominates every possible later use of the 6137169689Skan values. Restricting to such types here would be safe since there 6138169689Skan is no possible forward declaration around, but would introduce an 6139169689Skan undesirable middle-end semantic to anonymity. We then defer to 6140169689Skan front-ends the responsibility of ensuring that the sizes are 6141169689Skan evaluated both early and late enough, e.g. by attaching artificial 6142169689Skan type declarations to the tree. */ 6143169689Skan break; 6144169689Skan 6145169689Skan default: 6146169689Skan break; 6147169689Skan } 6148169689Skan 6149169689Skan gimplify_one_sizepos (&TYPE_SIZE (type), list_p); 6150169689Skan gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p); 6151169689Skan 6152169689Skan for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 6153169689Skan { 6154169689Skan TYPE_SIZE (t) = TYPE_SIZE (type); 6155169689Skan TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type); 6156169689Skan TYPE_SIZES_GIMPLIFIED (t) = 1; 6157169689Skan } 6158169689Skan} 6159169689Skan 6160169689Skan/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P, 6161169689Skan a size or position, has had all of its SAVE_EXPRs evaluated. 6162169689Skan We add any required statements to STMT_P. */ 6163169689Skan 6164169689Skanvoid 6165169689Skangimplify_one_sizepos (tree *expr_p, tree *stmt_p) 6166169689Skan{ 6167169689Skan tree type, expr = *expr_p; 6168169689Skan 6169169689Skan /* We don't do anything if the value isn't there, is constant, or contains 6170169689Skan A PLACEHOLDER_EXPR. We also don't want to do anything if it's already 6171169689Skan a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier 6172169689Skan will want to replace it with a new variable, but that will cause problems 6173169689Skan if this type is from outside the function. It's OK to have that here. */ 6174169689Skan if (expr == NULL_TREE || TREE_CONSTANT (expr) 6175169689Skan || TREE_CODE (expr) == VAR_DECL 6176169689Skan || CONTAINS_PLACEHOLDER_P (expr)) 6177169689Skan return; 6178169689Skan 6179169689Skan type = TREE_TYPE (expr); 6180169689Skan *expr_p = unshare_expr (expr); 6181169689Skan 6182169689Skan gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue); 6183169689Skan expr = *expr_p; 6184169689Skan 6185169689Skan /* Verify that we've an exact type match with the original expression. 6186169689Skan In particular, we do not wish to drop a "sizetype" in favour of a 6187169689Skan type of similar dimensions. We don't want to pollute the generic 6188169689Skan type-stripping code with this knowledge because it doesn't matter 6189169689Skan for the bulk of GENERIC/GIMPLE. It only matters that TYPE_SIZE_UNIT 6190169689Skan and friends retain their "sizetype-ness". */ 6191169689Skan if (TREE_TYPE (expr) != type 6192169689Skan && TREE_CODE (type) == INTEGER_TYPE 6193169689Skan && TYPE_IS_SIZETYPE (type)) 6194169689Skan { 6195169689Skan tree tmp; 6196169689Skan 6197169689Skan *expr_p = create_tmp_var (type, NULL); 6198169689Skan tmp = build1 (NOP_EXPR, type, expr); 6199169689Skan tmp = build2 (MODIFY_EXPR, type, *expr_p, tmp); 6200169689Skan if (EXPR_HAS_LOCATION (expr)) 6201169689Skan SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr)); 6202169689Skan else 6203169689Skan SET_EXPR_LOCATION (tmp, input_location); 6204169689Skan 6205169689Skan gimplify_and_add (tmp, stmt_p); 6206169689Skan } 6207169689Skan} 6208169689Skan 6209169689Skan#ifdef ENABLE_CHECKING 6210169689Skan/* Compare types A and B for a "close enough" match. */ 6211169689Skan 6212169689Skanstatic bool 6213169689Skancpt_same_type (tree a, tree b) 6214169689Skan{ 6215169689Skan if (lang_hooks.types_compatible_p (a, b)) 6216169689Skan return true; 6217169689Skan 6218169689Skan /* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't 6219169689Skan link them together. This routine is intended to catch type errors 6220169689Skan that will affect the optimizers, and the optimizers don't add new 6221169689Skan dereferences of function pointers, so ignore it. */ 6222169689Skan if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE) 6223169689Skan && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE)) 6224169689Skan return true; 6225169689Skan 6226169689Skan /* ??? The C FE pushes type qualifiers after the fact into the type of 6227169689Skan the element from the type of the array. See build_unary_op's handling 6228169689Skan of ADDR_EXPR. This seems wrong -- if we were going to do this, we 6229169689Skan should have done it when creating the variable in the first place. 6230169689Skan Alternately, why aren't the two array types made variants? */ 6231169689Skan if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE) 6232169689Skan return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b)); 6233169689Skan 6234169689Skan /* And because of those, we have to recurse down through pointers. */ 6235169689Skan if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b)) 6236169689Skan return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b)); 6237169689Skan 6238169689Skan return false; 6239169689Skan} 6240169689Skan 6241169689Skan/* Check for some cases of the front end missing cast expressions. 6242169689Skan The type of a dereference should correspond to the pointer type; 6243169689Skan similarly the type of an address should match its object. */ 6244169689Skan 6245169689Skanstatic tree 6246169689Skancheck_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 6247169689Skan void *data ATTRIBUTE_UNUSED) 6248169689Skan{ 6249169689Skan tree t = *tp; 6250169689Skan tree ptype, otype, dtype; 6251169689Skan 6252169689Skan switch (TREE_CODE (t)) 6253169689Skan { 6254169689Skan case INDIRECT_REF: 6255169689Skan case ARRAY_REF: 6256169689Skan otype = TREE_TYPE (t); 6257169689Skan ptype = TREE_TYPE (TREE_OPERAND (t, 0)); 6258169689Skan dtype = TREE_TYPE (ptype); 6259169689Skan gcc_assert (cpt_same_type (otype, dtype)); 6260169689Skan break; 6261169689Skan 6262169689Skan case ADDR_EXPR: 6263169689Skan ptype = TREE_TYPE (t); 6264169689Skan otype = TREE_TYPE (TREE_OPERAND (t, 0)); 6265169689Skan dtype = TREE_TYPE (ptype); 6266169689Skan if (!cpt_same_type (otype, dtype)) 6267169689Skan { 6268169689Skan /* &array is allowed to produce a pointer to the element, rather than 6269169689Skan a pointer to the array type. We must allow this in order to 6270169689Skan properly represent assigning the address of an array in C into 6271169689Skan pointer to the element type. */ 6272169689Skan gcc_assert (TREE_CODE (otype) == ARRAY_TYPE 6273169689Skan && POINTER_TYPE_P (ptype) 6274169689Skan && cpt_same_type (TREE_TYPE (otype), dtype)); 6275169689Skan break; 6276169689Skan } 6277169689Skan break; 6278169689Skan 6279169689Skan default: 6280169689Skan return NULL_TREE; 6281169689Skan } 6282169689Skan 6283169689Skan 6284169689Skan return NULL_TREE; 6285169689Skan} 6286169689Skan#endif 6287169689Skan 6288169689Skan/* Gimplify the body of statements pointed to by BODY_P. FNDECL is the 6289169689Skan function decl containing BODY. */ 6290169689Skan 6291169689Skanvoid 6292169689Skangimplify_body (tree *body_p, tree fndecl, bool do_parms) 6293169689Skan{ 6294169689Skan location_t saved_location = input_location; 6295169689Skan tree body, parm_stmts; 6296169689Skan 6297169689Skan timevar_push (TV_TREE_GIMPLIFY); 6298169689Skan 6299169689Skan gcc_assert (gimplify_ctxp == NULL); 6300169689Skan push_gimplify_context (); 6301169689Skan 6302169689Skan /* Unshare most shared trees in the body and in that of any nested functions. 6303169689Skan It would seem we don't have to do this for nested functions because 6304169689Skan they are supposed to be output and then the outer function gimplified 6305169689Skan first, but the g++ front end doesn't always do it that way. */ 6306169689Skan unshare_body (body_p, fndecl); 6307169689Skan unvisit_body (body_p, fndecl); 6308169689Skan 6309169689Skan /* Make sure input_location isn't set to something wierd. */ 6310169689Skan input_location = DECL_SOURCE_LOCATION (fndecl); 6311169689Skan 6312169689Skan /* Resolve callee-copies. This has to be done before processing 6313169689Skan the body so that DECL_VALUE_EXPR gets processed correctly. */ 6314169689Skan parm_stmts = do_parms ? gimplify_parameters () : NULL; 6315169689Skan 6316169689Skan /* Gimplify the function's body. */ 6317169689Skan gimplify_stmt (body_p); 6318169689Skan body = *body_p; 6319169689Skan 6320169689Skan if (!body) 6321169689Skan body = alloc_stmt_list (); 6322169689Skan else if (TREE_CODE (body) == STATEMENT_LIST) 6323169689Skan { 6324169689Skan tree t = expr_only (*body_p); 6325169689Skan if (t) 6326169689Skan body = t; 6327169689Skan } 6328169689Skan 6329169689Skan /* If there isn't an outer BIND_EXPR, add one. */ 6330169689Skan if (TREE_CODE (body) != BIND_EXPR) 6331169689Skan { 6332169689Skan tree b = build3 (BIND_EXPR, void_type_node, NULL_TREE, 6333169689Skan NULL_TREE, NULL_TREE); 6334169689Skan TREE_SIDE_EFFECTS (b) = 1; 6335169689Skan append_to_statement_list_force (body, &BIND_EXPR_BODY (b)); 6336169689Skan body = b; 6337169689Skan } 6338169689Skan 6339169689Skan /* If we had callee-copies statements, insert them at the beginning 6340169689Skan of the function. */ 6341169689Skan if (parm_stmts) 6342169689Skan { 6343169689Skan append_to_statement_list_force (BIND_EXPR_BODY (body), &parm_stmts); 6344169689Skan BIND_EXPR_BODY (body) = parm_stmts; 6345169689Skan } 6346169689Skan 6347169689Skan /* Unshare again, in case gimplification was sloppy. */ 6348169689Skan unshare_all_trees (body); 6349169689Skan 6350169689Skan *body_p = body; 6351169689Skan 6352169689Skan pop_gimplify_context (body); 6353169689Skan gcc_assert (gimplify_ctxp == NULL); 6354169689Skan 6355169689Skan#ifdef ENABLE_CHECKING 6356169689Skan walk_tree (body_p, check_pointer_types_r, NULL, NULL); 6357169689Skan#endif 6358169689Skan 6359169689Skan timevar_pop (TV_TREE_GIMPLIFY); 6360169689Skan input_location = saved_location; 6361169689Skan} 6362169689Skan 6363169689Skan/* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL 6364169689Skan node for the function we want to gimplify. */ 6365169689Skan 6366169689Skanvoid 6367169689Skangimplify_function_tree (tree fndecl) 6368169689Skan{ 6369169689Skan tree oldfn, parm, ret; 6370169689Skan 6371169689Skan oldfn = current_function_decl; 6372169689Skan current_function_decl = fndecl; 6373169689Skan cfun = DECL_STRUCT_FUNCTION (fndecl); 6374169689Skan if (cfun == NULL) 6375169689Skan allocate_struct_function (fndecl); 6376169689Skan 6377169689Skan for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = TREE_CHAIN (parm)) 6378169689Skan { 6379169689Skan /* Preliminarily mark non-addressed complex variables as eligible 6380169689Skan for promotion to gimple registers. We'll transform their uses 6381169689Skan as we find them. */ 6382169689Skan if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE 6383169689Skan && !TREE_THIS_VOLATILE (parm) 6384169689Skan && !needs_to_live_in_memory (parm)) 6385169689Skan DECL_COMPLEX_GIMPLE_REG_P (parm) = 1; 6386169689Skan } 6387169689Skan 6388169689Skan ret = DECL_RESULT (fndecl); 6389169689Skan if (TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE 6390169689Skan && !needs_to_live_in_memory (ret)) 6391169689Skan DECL_COMPLEX_GIMPLE_REG_P (ret) = 1; 6392169689Skan 6393169689Skan gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true); 6394169689Skan 6395169689Skan /* If we're instrumenting function entry/exit, then prepend the call to 6396169689Skan the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to 6397169689Skan catch the exit hook. */ 6398169689Skan /* ??? Add some way to ignore exceptions for this TFE. */ 6399169689Skan if (flag_instrument_function_entry_exit 6400258501Spfg && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) 6401258501Spfg && !flag_instrument_functions_exclude_p (fndecl)) 6402169689Skan { 6403169689Skan tree tf, x, bind; 6404169689Skan 6405169689Skan tf = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL); 6406169689Skan TREE_SIDE_EFFECTS (tf) = 1; 6407169689Skan x = DECL_SAVED_TREE (fndecl); 6408169689Skan append_to_statement_list (x, &TREE_OPERAND (tf, 0)); 6409169689Skan x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT]; 6410169689Skan x = build_function_call_expr (x, NULL); 6411169689Skan append_to_statement_list (x, &TREE_OPERAND (tf, 1)); 6412169689Skan 6413169689Skan bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); 6414169689Skan TREE_SIDE_EFFECTS (bind) = 1; 6415169689Skan x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER]; 6416169689Skan x = build_function_call_expr (x, NULL); 6417169689Skan append_to_statement_list (x, &BIND_EXPR_BODY (bind)); 6418169689Skan append_to_statement_list (tf, &BIND_EXPR_BODY (bind)); 6419169689Skan 6420169689Skan DECL_SAVED_TREE (fndecl) = bind; 6421169689Skan } 6422169689Skan 6423169689Skan current_function_decl = oldfn; 6424169689Skan cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL; 6425169689Skan} 6426169689Skan 6427169689Skan 6428169689Skan/* Expands EXPR to list of gimple statements STMTS. If SIMPLE is true, 6429169689Skan force the result to be either ssa_name or an invariant, otherwise 6430169689Skan just force it to be a rhs expression. If VAR is not NULL, make the 6431169689Skan base variable of the final destination be VAR if suitable. */ 6432169689Skan 6433169689Skantree 6434169689Skanforce_gimple_operand (tree expr, tree *stmts, bool simple, tree var) 6435169689Skan{ 6436169689Skan tree t; 6437169689Skan enum gimplify_status ret; 6438169689Skan gimple_predicate gimple_test_f; 6439169689Skan 6440169689Skan *stmts = NULL_TREE; 6441169689Skan 6442169689Skan if (is_gimple_val (expr)) 6443169689Skan return expr; 6444169689Skan 6445169689Skan gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs; 6446169689Skan 6447169689Skan push_gimplify_context (); 6448169689Skan gimplify_ctxp->into_ssa = in_ssa_p; 6449169689Skan 6450169689Skan if (var) 6451169689Skan expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr); 6452169689Skan 6453169689Skan ret = gimplify_expr (&expr, stmts, NULL, 6454169689Skan gimple_test_f, fb_rvalue); 6455169689Skan gcc_assert (ret != GS_ERROR); 6456169689Skan 6457169689Skan if (referenced_vars) 6458169689Skan { 6459169689Skan for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t)) 6460169689Skan add_referenced_var (t); 6461169689Skan } 6462169689Skan 6463169689Skan pop_gimplify_context (NULL); 6464169689Skan 6465169689Skan return expr; 6466169689Skan} 6467169689Skan 6468169689Skan/* Invokes force_gimple_operand for EXPR with parameters SIMPLE_P and VAR. If 6469169689Skan some statements are produced, emits them before BSI. */ 6470169689Skan 6471169689Skantree 6472169689Skanforce_gimple_operand_bsi (block_stmt_iterator *bsi, tree expr, 6473169689Skan bool simple_p, tree var) 6474169689Skan{ 6475169689Skan tree stmts; 6476169689Skan 6477169689Skan expr = force_gimple_operand (expr, &stmts, simple_p, var); 6478169689Skan if (stmts) 6479169689Skan bsi_insert_before (bsi, stmts, BSI_SAME_STMT); 6480169689Skan 6481169689Skan return expr; 6482169689Skan} 6483169689Skan 6484169689Skan#include "gt-gimplify.h" 6485