| /* Gimple IR definitions. |
| |
| Copyright (C) 2007-2015 Free Software Foundation, Inc. |
| Contributed by Aldy Hernandez <aldyh@redhat.com> |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify it under |
| the terms of the GNU General Public License as published by the Free |
| Software Foundation; either version 3, or (at your option) any later |
| version. |
| |
| GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #ifndef GCC_GIMPLE_H |
| #define GCC_GIMPLE_H |
| |
| typedef gimple gimple_seq_node; |
| |
| enum gimple_code { |
| #define DEFGSCODE(SYM, STRING, STRUCT) SYM, |
| #include "gimple.def" |
| #undef DEFGSCODE |
| LAST_AND_UNUSED_GIMPLE_CODE |
| }; |
| |
| extern const char *const gimple_code_name[]; |
| extern const unsigned char gimple_rhs_class_table[]; |
| |
| /* Error out if a gimple tuple is addressed incorrectly. */ |
| #if defined ENABLE_GIMPLE_CHECKING |
| #define gcc_gimple_checking_assert(EXPR) gcc_assert (EXPR) |
| extern void gimple_check_failed (const_gimple, const char *, int, \ |
| const char *, enum gimple_code, \ |
| enum tree_code) ATTRIBUTE_NORETURN; |
| |
| #define GIMPLE_CHECK(GS, CODE) \ |
| do { \ |
| const_gimple __gs = (GS); \ |
| if (gimple_code (__gs) != (CODE)) \ |
| gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \ |
| (CODE), ERROR_MARK); \ |
| } while (0) |
| #else /* not ENABLE_GIMPLE_CHECKING */ |
| #define gcc_gimple_checking_assert(EXPR) ((void)(0 && (EXPR))) |
| #define GIMPLE_CHECK(GS, CODE) (void)0 |
| #endif |
| |
| /* Class of GIMPLE expressions suitable for the RHS of assignments. See |
| get_gimple_rhs_class. */ |
| enum gimple_rhs_class |
| { |
| GIMPLE_INVALID_RHS, /* The expression cannot be used on the RHS. */ |
| GIMPLE_TERNARY_RHS, /* The expression is a ternary operation. */ |
| GIMPLE_BINARY_RHS, /* The expression is a binary operation. */ |
| GIMPLE_UNARY_RHS, /* The expression is a unary operation. */ |
| GIMPLE_SINGLE_RHS /* The expression is a single object (an SSA |
| name, a _DECL, a _REF, etc. */ |
| }; |
| |
| /* Specific flags for individual GIMPLE statements. These flags are |
| always stored in gimple_statement_base.subcode and they may only be |
| defined for statement codes that do not use subcodes. |
| |
| Values for the masks can overlap as long as the overlapping values |
| are never used in the same statement class. |
| |
| The maximum mask value that can be defined is 1 << 15 (i.e., each |
| statement code can hold up to 16 bitflags). |
| |
| Keep this list sorted. */ |
| enum gf_mask { |
| GF_ASM_INPUT = 1 << 0, |
| GF_ASM_VOLATILE = 1 << 1, |
| GF_CALL_FROM_THUNK = 1 << 0, |
| GF_CALL_RETURN_SLOT_OPT = 1 << 1, |
| GF_CALL_TAILCALL = 1 << 2, |
| GF_CALL_VA_ARG_PACK = 1 << 3, |
| GF_CALL_NOTHROW = 1 << 4, |
| GF_CALL_ALLOCA_FOR_VAR = 1 << 5, |
| GF_CALL_INTERNAL = 1 << 6, |
| GF_CALL_CTRL_ALTERING = 1 << 7, |
| GF_CALL_WITH_BOUNDS = 1 << 8, |
| GF_OMP_PARALLEL_COMBINED = 1 << 0, |
| GF_OMP_FOR_KIND_MASK = (1 << 3) - 1, |
| GF_OMP_FOR_KIND_FOR = 0, |
| GF_OMP_FOR_KIND_DISTRIBUTE = 1, |
| GF_OMP_FOR_KIND_CILKFOR = 2, |
| GF_OMP_FOR_KIND_OACC_LOOP = 3, |
| /* Flag for SIMD variants of OMP_FOR kinds. */ |
| GF_OMP_FOR_SIMD = 1 << 2, |
| GF_OMP_FOR_KIND_SIMD = GF_OMP_FOR_SIMD | 0, |
| GF_OMP_FOR_KIND_CILKSIMD = GF_OMP_FOR_SIMD | 1, |
| GF_OMP_FOR_COMBINED = 1 << 3, |
| GF_OMP_FOR_COMBINED_INTO = 1 << 4, |
| GF_OMP_TARGET_KIND_MASK = (1 << 3) - 1, |
| GF_OMP_TARGET_KIND_REGION = 0, |
| GF_OMP_TARGET_KIND_DATA = 1, |
| GF_OMP_TARGET_KIND_UPDATE = 2, |
| GF_OMP_TARGET_KIND_OACC_PARALLEL = 3, |
| GF_OMP_TARGET_KIND_OACC_KERNELS = 4, |
| GF_OMP_TARGET_KIND_OACC_DATA = 5, |
| GF_OMP_TARGET_KIND_OACC_UPDATE = 6, |
| GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 7, |
| |
| /* True on an GIMPLE_OMP_RETURN statement if the return does not require |
| a thread synchronization via some sort of barrier. The exact barrier |
| that would otherwise be emitted is dependent on the OMP statement with |
| which this return is associated. */ |
| GF_OMP_RETURN_NOWAIT = 1 << 0, |
| |
| GF_OMP_SECTION_LAST = 1 << 0, |
| GF_OMP_ATOMIC_NEED_VALUE = 1 << 0, |
| GF_OMP_ATOMIC_SEQ_CST = 1 << 1, |
| GF_PREDICT_TAKEN = 1 << 15 |
| }; |
| |
| /* Currently, there are only two types of gimple debug stmt. Others are |
| envisioned, for example, to enable the generation of is_stmt notes |
| in line number information, to mark sequence points, etc. This |
| subcode is to be used to tell them apart. */ |
| enum gimple_debug_subcode { |
| GIMPLE_DEBUG_BIND = 0, |
| GIMPLE_DEBUG_SOURCE_BIND = 1 |
| }; |
| |
| /* Masks for selecting a pass local flag (PLF) to work on. These |
| masks are used by gimple_set_plf and gimple_plf. */ |
| enum plf_mask { |
| GF_PLF_1 = 1 << 0, |
| GF_PLF_2 = 1 << 1 |
| }; |
| |
| /* Data structure definitions for GIMPLE tuples. NOTE: word markers |
| are for 64 bit hosts. */ |
| |
| struct GTY((desc ("gimple_statement_structure (&%h)"), tag ("GSS_BASE"), |
| chain_next ("%h.next"), variable_size)) |
| gimple_statement_base |
| { |
| /* [ WORD 1 ] |
| Main identifying code for a tuple. */ |
| ENUM_BITFIELD(gimple_code) code : 8; |
| |
| /* Nonzero if a warning should not be emitted on this tuple. */ |
| unsigned int no_warning : 1; |
| |
| /* Nonzero if this tuple has been visited. Passes are responsible |
| for clearing this bit before using it. */ |
| unsigned int visited : 1; |
| |
| /* Nonzero if this tuple represents a non-temporal move. */ |
| unsigned int nontemporal_move : 1; |
| |
| /* Pass local flags. These flags are free for any pass to use as |
| they see fit. Passes should not assume that these flags contain |
| any useful value when the pass starts. Any initial state that |
| the pass requires should be set on entry to the pass. See |
| gimple_set_plf and gimple_plf for usage. */ |
| unsigned int plf : 2; |
| |
| /* Nonzero if this statement has been modified and needs to have its |
| operands rescanned. */ |
| unsigned modified : 1; |
| |
| /* Nonzero if this statement contains volatile operands. */ |
| unsigned has_volatile_ops : 1; |
| |
| /* Padding to get subcode to 16 bit alignment. */ |
| unsigned pad : 1; |
| |
| /* The SUBCODE field can be used for tuple-specific flags for tuples |
| that do not require subcodes. Note that SUBCODE should be at |
| least as wide as tree codes, as several tuples store tree codes |
| in there. */ |
| unsigned int subcode : 16; |
| |
| /* UID of this statement. This is used by passes that want to |
| assign IDs to statements. It must be assigned and used by each |
| pass. By default it should be assumed to contain garbage. */ |
| unsigned uid; |
| |
| /* [ WORD 2 ] |
| Locus information for debug info. */ |
| location_t location; |
| |
| /* Number of operands in this tuple. */ |
| unsigned num_ops; |
| |
| /* [ WORD 3 ] |
| Basic block holding this statement. */ |
| basic_block bb; |
| |
| /* [ WORD 4-5 ] |
| Linked lists of gimple statements. The next pointers form |
| a NULL terminated list, the prev pointers are a cyclic list. |
| A gimple statement is hence also a double-ended list of |
| statements, with the pointer itself being the first element, |
| and the prev pointer being the last. */ |
| gimple next; |
| gimple GTY((skip)) prev; |
| }; |
| |
| |
| /* Base structure for tuples with operands. */ |
| |
| /* This gimple subclass has no tag value. */ |
| struct GTY(()) |
| gimple_statement_with_ops_base : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] |
| SSA operand vectors. NOTE: It should be possible to |
| amalgamate these vectors with the operand vector OP. However, |
| the SSA operand vectors are organized differently and contain |
| more information (like immediate use chaining). */ |
| struct use_optype_d GTY((skip (""))) *use_ops; |
| }; |
| |
| |
| /* Statements that take register operands. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| gimple_statement_with_ops : public gimple_statement_with_ops_base |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8 ] |
| Operand vector. NOTE! This must always be the last field |
| of this structure. In particular, this means that this |
| structure cannot be embedded inside another one. */ |
| tree GTY((length ("%h.num_ops"))) op[1]; |
| }; |
| |
| |
| /* Base for statements that take both memory and register operands. */ |
| |
| struct GTY((tag("GSS_WITH_MEM_OPS_BASE"))) |
| gimple_statement_with_memory_ops_base : public gimple_statement_with_ops_base |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8-9 ] |
| Virtual operands for this statement. The GC will pick them |
| up via the ssa_names array. */ |
| tree GTY((skip (""))) vdef; |
| tree GTY((skip (""))) vuse; |
| }; |
| |
| |
| /* Statements that take both memory and register operands. */ |
| |
| struct GTY((tag("GSS_WITH_MEM_OPS"))) |
| gimple_statement_with_memory_ops : |
| public gimple_statement_with_memory_ops_base |
| { |
| /* [ WORD 1-9 ] : base class */ |
| |
| /* [ WORD 10 ] |
| Operand vector. NOTE! This must always be the last field |
| of this structure. In particular, this means that this |
| structure cannot be embedded inside another one. */ |
| tree GTY((length ("%h.num_ops"))) op[1]; |
| }; |
| |
| |
| /* Call statements that take both memory and register operands. */ |
| |
| struct GTY((tag("GSS_CALL"))) |
| gcall : public gimple_statement_with_memory_ops_base |
| { |
| /* [ WORD 1-9 ] : base class */ |
| |
| /* [ WORD 10-13 ] */ |
| struct pt_solution call_used; |
| struct pt_solution call_clobbered; |
| |
| /* [ WORD 14 ] */ |
| union GTY ((desc ("%1.subcode & GF_CALL_INTERNAL"))) { |
| tree GTY ((tag ("0"))) fntype; |
| enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn; |
| } u; |
| |
| /* [ WORD 15 ] |
| Operand vector. NOTE! This must always be the last field |
| of this structure. In particular, this means that this |
| structure cannot be embedded inside another one. */ |
| tree GTY((length ("%h.num_ops"))) op[1]; |
| }; |
| |
| |
| /* OMP statements. */ |
| |
| struct GTY((tag("GSS_OMP"))) |
| gimple_statement_omp : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| gimple_seq body; |
| }; |
| |
| |
| /* GIMPLE_BIND */ |
| |
| struct GTY((tag("GSS_BIND"))) |
| gbind : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] |
| Variables declared in this scope. */ |
| tree vars; |
| |
| /* [ WORD 8 ] |
| This is different than the BLOCK field in gimple_statement_base, |
| which is analogous to TREE_BLOCK (i.e., the lexical block holding |
| this statement). This field is the equivalent of BIND_EXPR_BLOCK |
| in tree land (i.e., the lexical scope defined by this bind). See |
| gimple-low.c. */ |
| tree block; |
| |
| /* [ WORD 9 ] */ |
| gimple_seq body; |
| }; |
| |
| |
| /* GIMPLE_CATCH */ |
| |
| struct GTY((tag("GSS_CATCH"))) |
| gcatch : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| tree types; |
| |
| /* [ WORD 8 ] */ |
| gimple_seq handler; |
| }; |
| |
| |
| /* GIMPLE_EH_FILTER */ |
| |
| struct GTY((tag("GSS_EH_FILTER"))) |
| geh_filter : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] |
| Filter types. */ |
| tree types; |
| |
| /* [ WORD 8 ] |
| Failure actions. */ |
| gimple_seq failure; |
| }; |
| |
| /* GIMPLE_EH_ELSE */ |
| |
| struct GTY((tag("GSS_EH_ELSE"))) |
| geh_else : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7,8 ] */ |
| gimple_seq n_body, e_body; |
| }; |
| |
| /* GIMPLE_EH_MUST_NOT_THROW */ |
| |
| struct GTY((tag("GSS_EH_MNT"))) |
| geh_mnt : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] Abort function decl. */ |
| tree fndecl; |
| }; |
| |
| /* GIMPLE_PHI */ |
| |
| struct GTY((tag("GSS_PHI"))) |
| gphi : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| unsigned capacity; |
| unsigned nargs; |
| |
| /* [ WORD 8 ] */ |
| tree result; |
| |
| /* [ WORD 9 ] */ |
| struct phi_arg_d GTY ((length ("%h.nargs"))) args[1]; |
| }; |
| |
| |
| /* GIMPLE_RESX, GIMPLE_EH_DISPATCH */ |
| |
| struct GTY((tag("GSS_EH_CTRL"))) |
| gimple_statement_eh_ctrl : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] |
| Exception region number. */ |
| int region; |
| }; |
| |
| struct GTY((tag("GSS_EH_CTRL"))) |
| gresx : public gimple_statement_eh_ctrl |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_RESX. */ |
| }; |
| |
| struct GTY((tag("GSS_EH_CTRL"))) |
| geh_dispatch : public gimple_statement_eh_ctrl |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_EH_DISPATH. */ |
| }; |
| |
| |
| /* GIMPLE_TRY */ |
| |
| struct GTY((tag("GSS_TRY"))) |
| gtry : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] |
| Expression to evaluate. */ |
| gimple_seq eval; |
| |
| /* [ WORD 8 ] |
| Cleanup expression. */ |
| gimple_seq cleanup; |
| }; |
| |
| /* Kind of GIMPLE_TRY statements. */ |
| enum gimple_try_flags |
| { |
| /* A try/catch. */ |
| GIMPLE_TRY_CATCH = 1 << 0, |
| |
| /* A try/finally. */ |
| GIMPLE_TRY_FINALLY = 1 << 1, |
| GIMPLE_TRY_KIND = GIMPLE_TRY_CATCH | GIMPLE_TRY_FINALLY, |
| |
| /* Analogous to TRY_CATCH_IS_CLEANUP. */ |
| GIMPLE_TRY_CATCH_IS_CLEANUP = 1 << 2 |
| }; |
| |
| /* GIMPLE_WITH_CLEANUP_EXPR */ |
| |
| struct GTY((tag("GSS_WCE"))) |
| gimple_statement_wce : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* Subcode: CLEANUP_EH_ONLY. True if the cleanup should only be |
| executed if an exception is thrown, not on normal exit of its |
| scope. This flag is analogous to the CLEANUP_EH_ONLY flag |
| in TARGET_EXPRs. */ |
| |
| /* [ WORD 7 ] |
| Cleanup expression. */ |
| gimple_seq cleanup; |
| }; |
| |
| |
| /* GIMPLE_ASM */ |
| |
| struct GTY((tag("GSS_ASM"))) |
| gasm : public gimple_statement_with_memory_ops_base |
| { |
| /* [ WORD 1-9 ] : base class */ |
| |
| /* [ WORD 10 ] |
| __asm__ statement. */ |
| const char *string; |
| |
| /* [ WORD 11 ] |
| Number of inputs, outputs, clobbers, labels. */ |
| unsigned char ni; |
| unsigned char no; |
| unsigned char nc; |
| unsigned char nl; |
| |
| /* [ WORD 12 ] |
| Operand vector. NOTE! This must always be the last field |
| of this structure. In particular, this means that this |
| structure cannot be embedded inside another one. */ |
| tree GTY((length ("%h.num_ops"))) op[1]; |
| }; |
| |
| /* GIMPLE_OMP_CRITICAL */ |
| |
| struct GTY((tag("GSS_OMP_CRITICAL"))) |
| gomp_critical : public gimple_statement_omp |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8 ] |
| Critical section name. */ |
| tree name; |
| }; |
| |
| |
| struct GTY(()) gimple_omp_for_iter { |
| /* Condition code. */ |
| enum tree_code cond; |
| |
| /* Index variable. */ |
| tree index; |
| |
| /* Initial value. */ |
| tree initial; |
| |
| /* Final value. */ |
| tree final; |
| |
| /* Increment. */ |
| tree incr; |
| }; |
| |
| /* GIMPLE_OMP_FOR */ |
| |
| struct GTY((tag("GSS_OMP_FOR"))) |
| gomp_for : public gimple_statement_omp |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8 ] */ |
| tree clauses; |
| |
| /* [ WORD 9 ] |
| Number of elements in iter array. */ |
| size_t collapse; |
| |
| /* [ WORD 10 ] */ |
| struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter; |
| |
| /* [ WORD 11 ] |
| Pre-body evaluated before the loop body begins. */ |
| gimple_seq pre_body; |
| }; |
| |
| |
| /* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET, GIMPLE_OMP_TASK */ |
| |
| struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) |
| gimple_statement_omp_parallel_layout : public gimple_statement_omp |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8 ] |
| Clauses. */ |
| tree clauses; |
| |
| /* [ WORD 9 ] |
| Child function holding the body of the parallel region. */ |
| tree child_fn; |
| |
| /* [ WORD 10 ] |
| Shared data argument. */ |
| tree data_arg; |
| }; |
| |
| /* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */ |
| struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) |
| gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_PARALLEL |
| || stmt->code == GIMPLE_OMP_TASK. */ |
| }; |
| |
| /* GIMPLE_OMP_PARALLEL */ |
| struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) |
| gomp_parallel : public gimple_statement_omp_taskreg |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_PARALLEL. */ |
| }; |
| |
| /* GIMPLE_OMP_TARGET */ |
| struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) |
| gomp_target : public gimple_statement_omp_parallel_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_TARGET. */ |
| }; |
| |
| /* GIMPLE_OMP_TASK */ |
| |
| struct GTY((tag("GSS_OMP_TASK"))) |
| gomp_task : public gimple_statement_omp_taskreg |
| { |
| /* [ WORD 1-10 ] : base class */ |
| |
| /* [ WORD 11 ] |
| Child function holding firstprivate initialization if needed. */ |
| tree copy_fn; |
| |
| /* [ WORD 12-13 ] |
| Size and alignment in bytes of the argument data block. */ |
| tree arg_size; |
| tree arg_align; |
| }; |
| |
| |
| /* GIMPLE_OMP_SECTION */ |
| /* Uses struct gimple_statement_omp. */ |
| |
| |
| /* GIMPLE_OMP_SECTIONS */ |
| |
| struct GTY((tag("GSS_OMP_SECTIONS"))) |
| gomp_sections : public gimple_statement_omp |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 8 ] */ |
| tree clauses; |
| |
| /* [ WORD 9 ] |
| The control variable used for deciding which of the sections to |
| execute. */ |
| tree control; |
| }; |
| |
| /* GIMPLE_OMP_CONTINUE. |
| |
| Note: This does not inherit from gimple_statement_omp, because we |
| do not need the body field. */ |
| |
| struct GTY((tag("GSS_OMP_CONTINUE"))) |
| gomp_continue : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| tree control_def; |
| |
| /* [ WORD 8 ] */ |
| tree control_use; |
| }; |
| |
| /* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */ |
| |
| struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) |
| gimple_statement_omp_single_layout : public gimple_statement_omp |
| { |
| /* [ WORD 1-7 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| tree clauses; |
| }; |
| |
| struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) |
| gomp_single : public gimple_statement_omp_single_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_SINGLE. */ |
| }; |
| |
| struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) |
| gomp_teams : public gimple_statement_omp_single_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_TEAMS. */ |
| }; |
| |
| |
| /* GIMPLE_OMP_ATOMIC_LOAD. |
| Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp |
| contains a sequence, which we don't need here. */ |
| |
| struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) |
| gomp_atomic_load : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7-8 ] */ |
| tree rhs, lhs; |
| }; |
| |
| /* GIMPLE_OMP_ATOMIC_STORE. |
| See note on GIMPLE_OMP_ATOMIC_LOAD. */ |
| |
| struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) |
| gimple_statement_omp_atomic_store_layout : public gimple_statement_base |
| { |
| /* [ WORD 1-6 ] : base class */ |
| |
| /* [ WORD 7 ] */ |
| tree val; |
| }; |
| |
| struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) |
| gomp_atomic_store : |
| public gimple_statement_omp_atomic_store_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_ATOMIC_STORE. */ |
| }; |
| |
| struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) |
| gimple_statement_omp_return : |
| public gimple_statement_omp_atomic_store_layout |
| { |
| /* No extra fields; adds invariant: |
| stmt->code == GIMPLE_OMP_RETURN. */ |
| }; |
| |
| /* GIMPLE_TRANSACTION. */ |
| |
| /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ |
| |
| /* The __transaction_atomic was declared [[outer]] or it is |
| __transaction_relaxed. */ |
| #define GTMA_IS_OUTER (1u << 0) |
| #define GTMA_IS_RELAXED (1u << 1) |
| #define GTMA_DECLARATION_MASK (GTMA_IS_OUTER | GTMA_IS_RELAXED) |
| |
| /* The transaction is seen to not have an abort. */ |
| #define GTMA_HAVE_ABORT (1u << 2) |
| /* The transaction is seen to have loads or stores. */ |
| #define GTMA_HAVE_LOAD (1u << 3) |
| #define GTMA_HAVE_STORE (1u << 4) |
| /* The transaction MAY enter serial irrevocable mode in its dynamic scope. */ |
| #define GTMA_MAY_ENTER_IRREVOCABLE (1u << 5) |
| /* The transaction WILL enter serial irrevocable mode. |
| An irrevocable block post-dominates the entire transaction, such |
| that all invocations of the transaction will go serial-irrevocable. |
| In such case, we don't bother instrumenting the transaction, and |
| tell the runtime that it should begin the transaction in |
| serial-irrevocable mode. */ |
| #define GTMA_DOES_GO_IRREVOCABLE (1u << 6) |
| /* The transaction contains no instrumentation code whatsover, most |
| likely because it is guaranteed to go irrevocable upon entry. */ |
| #define GTMA_HAS_NO_INSTRUMENTATION (1u << 7) |
| |
| struct GTY((tag("GSS_TRANSACTION"))) |
| gtransaction : public gimple_statement_with_memory_ops_base |
| { |
| /* [ WORD 1-9 ] : base class */ |
| |
| /* [ WORD 10 ] */ |
| gimple_seq body; |
| |
| /* [ WORD 11 ] */ |
| tree label; |
| }; |
| |
| #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM, |
| enum gimple_statement_structure_enum { |
| #include "gsstruct.def" |
| LAST_GSS_ENUM |
| }; |
| #undef DEFGSSTRUCT |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_COND |
| i.e. a conditional jump statement. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| gcond : public gimple_statement_with_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_DEBUG |
| i.e. a debug statement. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| gdebug : public gimple_statement_with_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_GOTO |
| i.e. a goto statement. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| ggoto : public gimple_statement_with_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_LABEL |
| i.e. a label statement. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| glabel : public gimple_statement_with_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_SWITCH |
| i.e. a switch statement. */ |
| |
| struct GTY((tag("GSS_WITH_OPS"))) |
| gswitch : public gimple_statement_with_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_ASSIGN |
| i.e. an assignment statement. */ |
| |
| struct GTY((tag("GSS_WITH_MEM_OPS"))) |
| gassign : public gimple_statement_with_memory_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ |
| }; |
| |
| /* A statement with the invariant that |
| stmt->code == GIMPLE_RETURN |
| i.e. a return statement. */ |
| |
| struct GTY((tag("GSS_WITH_MEM_OPS"))) |
| greturn : public gimple_statement_with_memory_ops |
| { |
| /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ |
| }; |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gasm *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_ASM; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gassign *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_ASSIGN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gbind *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_BIND; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gcall *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_CALL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gcatch *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_CATCH; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gcond *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_COND; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gdebug *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_DEBUG; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <ggoto *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_GOTO; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <glabel *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_LABEL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gresx *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_RESX; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <geh_dispatch *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_EH_DISPATCH; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <geh_else *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_EH_ELSE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <geh_filter *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_EH_FILTER; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <geh_mnt *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_EH_MUST_NOT_THROW; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_atomic_load *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_ATOMIC_LOAD; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_atomic_store *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_ATOMIC_STORE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gimple_statement_omp_return *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_RETURN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_continue *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_CONTINUE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_critical *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_CRITICAL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_for *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_FOR; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gimple_statement_omp_taskreg *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_parallel *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_PARALLEL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_target *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TARGET; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_sections *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_SECTIONS; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_single *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_SINGLE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_teams *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TEAMS; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gomp_task *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TASK; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gphi *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_PHI; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <greturn *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_RETURN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gswitch *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_SWITCH; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gtransaction *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_TRANSACTION; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gtry *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_TRY; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gimple_statement_wce *>::test (gimple gs) |
| { |
| return gs->code == GIMPLE_WITH_CLEANUP_EXPR; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gasm *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_ASM; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gbind *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_BIND; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gcall *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_CALL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gcatch *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_CATCH; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gresx *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_RESX; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const geh_dispatch *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_EH_DISPATCH; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const geh_filter *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_EH_FILTER; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_atomic_load *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_ATOMIC_LOAD; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_atomic_store *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_ATOMIC_STORE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gimple_statement_omp_return *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_RETURN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_continue *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_CONTINUE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_critical *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_CRITICAL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_for *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_FOR; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gimple_statement_omp_taskreg *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_parallel *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_PARALLEL; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_target *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TARGET; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_sections *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_SECTIONS; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_single *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_SINGLE; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_teams *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TEAMS; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gomp_task *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_OMP_TASK; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gphi *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_PHI; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gtransaction *>::test (const_gimple gs) |
| { |
| return gs->code == GIMPLE_TRANSACTION; |
| } |
| |
| /* Offset in bytes to the location of the operand vector. |
| Zero if there is no operand vector for this tuple structure. */ |
| extern size_t const gimple_ops_offset_[]; |
| |
| /* Map GIMPLE codes to GSS codes. */ |
| extern enum gimple_statement_structure_enum const gss_for_code_[]; |
| |
| /* This variable holds the currently expanded gimple statement for purposes |
| of comminucating the profile info to the builtin expanders. */ |
| extern gimple currently_expanding_gimple_stmt; |
| |
| #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO) |
| gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL); |
| greturn *gimple_build_return (tree); |
| void gimple_call_reset_alias_info (gcall *); |
| gcall *gimple_build_call_vec (tree, vec<tree> ); |
| gcall *gimple_build_call (tree, unsigned, ...); |
| gcall *gimple_build_call_valist (tree, unsigned, va_list); |
| gcall *gimple_build_call_internal (enum internal_fn, unsigned, ...); |
| gcall *gimple_build_call_internal_vec (enum internal_fn, vec<tree> ); |
| gcall *gimple_build_call_from_tree (tree); |
| gassign *gimple_build_assign (tree, tree CXX_MEM_STAT_INFO); |
| gassign *gimple_build_assign (tree, enum tree_code, |
| tree, tree, tree CXX_MEM_STAT_INFO); |
| gassign *gimple_build_assign (tree, enum tree_code, |
| tree, tree CXX_MEM_STAT_INFO); |
| gassign *gimple_build_assign (tree, enum tree_code, tree CXX_MEM_STAT_INFO); |
| gcond *gimple_build_cond (enum tree_code, tree, tree, tree, tree); |
| gcond *gimple_build_cond_from_tree (tree, tree, tree); |
| void gimple_cond_set_condition_from_tree (gcond *, tree); |
| glabel *gimple_build_label (tree label); |
| ggoto *gimple_build_goto (tree dest); |
| gimple gimple_build_nop (void); |
| gbind *gimple_build_bind (tree, gimple_seq, tree); |
| gasm *gimple_build_asm_vec (const char *, vec<tree, va_gc> *, |
| vec<tree, va_gc> *, vec<tree, va_gc> *, |
| vec<tree, va_gc> *); |
| gcatch *gimple_build_catch (tree, gimple_seq); |
| geh_filter *gimple_build_eh_filter (tree, gimple_seq); |
| geh_mnt *gimple_build_eh_must_not_throw (tree); |
| geh_else *gimple_build_eh_else (gimple_seq, gimple_seq); |
| gtry *gimple_build_try (gimple_seq, gimple_seq, |
| enum gimple_try_flags); |
| gimple gimple_build_wce (gimple_seq); |
| gresx *gimple_build_resx (int); |
| gswitch *gimple_build_switch_nlabels (unsigned, tree, tree); |
| gswitch *gimple_build_switch (tree, tree, vec<tree> ); |
| geh_dispatch *gimple_build_eh_dispatch (int); |
| gdebug *gimple_build_debug_bind_stat (tree, tree, gimple MEM_STAT_DECL); |
| #define gimple_build_debug_bind(var,val,stmt) \ |
| gimple_build_debug_bind_stat ((var), (val), (stmt) MEM_STAT_INFO) |
| gdebug *gimple_build_debug_source_bind_stat (tree, tree, gimple MEM_STAT_DECL); |
| #define gimple_build_debug_source_bind(var,val,stmt) \ |
| gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO) |
| gomp_critical *gimple_build_omp_critical (gimple_seq, tree); |
| gomp_for *gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq); |
| gomp_parallel *gimple_build_omp_parallel (gimple_seq, tree, tree, tree); |
| gomp_task *gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, |
| tree, tree); |
| gimple gimple_build_omp_section (gimple_seq); |
| gimple gimple_build_omp_master (gimple_seq); |
| gimple gimple_build_omp_taskgroup (gimple_seq); |
| gomp_continue *gimple_build_omp_continue (tree, tree); |
| gimple gimple_build_omp_ordered (gimple_seq); |
| gimple gimple_build_omp_return (bool); |
| gomp_sections *gimple_build_omp_sections (gimple_seq, tree); |
| gimple gimple_build_omp_sections_switch (void); |
| gomp_single *gimple_build_omp_single (gimple_seq, tree); |
| gomp_target *gimple_build_omp_target (gimple_seq, int, tree); |
| gomp_teams *gimple_build_omp_teams (gimple_seq, tree); |
| gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree); |
| gomp_atomic_store *gimple_build_omp_atomic_store (tree); |
| gtransaction *gimple_build_transaction (gimple_seq, tree); |
| gimple gimple_build_predict (enum br_predictor, enum prediction); |
| extern void gimple_seq_add_stmt (gimple_seq *, gimple); |
| extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple); |
| void gimple_seq_add_seq (gimple_seq *, gimple_seq); |
| void gimple_seq_add_seq_without_update (gimple_seq *, gimple_seq); |
| extern void annotate_all_with_location_after (gimple_seq, gimple_stmt_iterator, |
| location_t); |
| extern void annotate_all_with_location (gimple_seq, location_t); |
| bool empty_body_p (gimple_seq); |
| gimple_seq gimple_seq_copy (gimple_seq); |
| bool gimple_call_same_target_p (const_gimple, const_gimple); |
| int gimple_call_flags (const_gimple); |
| int gimple_call_arg_flags (const gcall *, unsigned); |
| int gimple_call_return_flags (const gcall *); |
| bool gimple_assign_copy_p (gimple); |
| bool gimple_assign_ssa_name_copy_p (gimple); |
| bool gimple_assign_unary_nop_p (gimple); |
| void gimple_set_bb (gimple, basic_block); |
| void gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *, tree); |
| void gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *, enum tree_code, |
| tree, tree, tree); |
| tree gimple_get_lhs (const_gimple); |
| void gimple_set_lhs (gimple, tree); |
| gimple gimple_copy (gimple); |
| bool gimple_has_side_effects (const_gimple); |
| bool gimple_could_trap_p_1 (gimple, bool, bool); |
| bool gimple_could_trap_p (gimple); |
| bool gimple_assign_rhs_could_trap_p (gimple); |
| extern void dump_gimple_statistics (void); |
| unsigned get_gimple_rhs_num_ops (enum tree_code); |
| extern tree canonicalize_cond_expr_cond (tree); |
| gcall *gimple_call_copy_skip_args (gcall *, bitmap); |
| extern bool gimple_compare_field_offset (tree, tree); |
| extern tree gimple_unsigned_type (tree); |
| extern tree gimple_signed_type (tree); |
| extern alias_set_type gimple_get_alias_set (tree); |
| extern bool gimple_ior_addresses_taken (bitmap, gimple); |
| extern bool gimple_builtin_call_types_compatible_p (const_gimple, tree); |
| extern bool gimple_call_builtin_p (const_gimple); |
| extern bool gimple_call_builtin_p (const_gimple, enum built_in_class); |
| extern bool gimple_call_builtin_p (const_gimple, enum built_in_function); |
| extern bool gimple_asm_clobbers_memory_p (const gasm *); |
| extern void dump_decl_set (FILE *, bitmap); |
| extern bool nonfreeing_call_p (gimple); |
| extern bool infer_nonnull_range (gimple, tree, bool, bool); |
| extern void sort_case_labels (vec<tree>); |
| extern void preprocess_case_label_vec_for_gimple (vec<tree>, tree, tree *); |
| extern void gimple_seq_set_location (gimple_seq, location_t); |
| extern void gimple_seq_discard (gimple_seq); |
| extern void maybe_remove_unused_call_args (struct function *, gimple); |
| |
| /* Formal (expression) temporary table handling: multiple occurrences of |
| the same scalar expression are evaluated into the same temporary. */ |
| |
| typedef struct gimple_temp_hash_elt |
| { |
| tree val; /* Key */ |
| tree temp; /* Value */ |
| } elt_t; |
| |
| /* Get the number of the next statement uid to be allocated. */ |
| static inline unsigned int |
| gimple_stmt_max_uid (struct function *fn) |
| { |
| return fn->last_stmt_uid; |
| } |
| |
| /* Set the number of the next statement uid to be allocated. */ |
| static inline void |
| set_gimple_stmt_max_uid (struct function *fn, unsigned int maxid) |
| { |
| fn->last_stmt_uid = maxid; |
| } |
| |
| /* Set the number of the next statement uid to be allocated. */ |
| static inline unsigned int |
| inc_gimple_stmt_max_uid (struct function *fn) |
| { |
| return fn->last_stmt_uid++; |
| } |
| |
| /* Return the first node in GIMPLE sequence S. */ |
| |
| static inline gimple_seq_node |
| gimple_seq_first (gimple_seq s) |
| { |
| return s; |
| } |
| |
| |
| /* Return the first statement in GIMPLE sequence S. */ |
| |
| static inline gimple |
| gimple_seq_first_stmt (gimple_seq s) |
| { |
| gimple_seq_node n = gimple_seq_first (s); |
| return n; |
| } |
| |
| /* Return the first statement in GIMPLE sequence S as a gbind *, |
| verifying that it has code GIMPLE_BIND in a checked build. */ |
| |
| static inline gbind * |
| gimple_seq_first_stmt_as_a_bind (gimple_seq s) |
| { |
| gimple_seq_node n = gimple_seq_first (s); |
| return as_a <gbind *> (n); |
| } |
| |
| |
| /* Return the last node in GIMPLE sequence S. */ |
| |
| static inline gimple_seq_node |
| gimple_seq_last (gimple_seq s) |
| { |
| return s ? s->prev : NULL; |
| } |
| |
| |
| /* Return the last statement in GIMPLE sequence S. */ |
| |
| static inline gimple |
| gimple_seq_last_stmt (gimple_seq s) |
| { |
| gimple_seq_node n = gimple_seq_last (s); |
| return n; |
| } |
| |
| |
| /* Set the last node in GIMPLE sequence *PS to LAST. */ |
| |
| static inline void |
| gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last) |
| { |
| (*ps)->prev = last; |
| } |
| |
| |
| /* Set the first node in GIMPLE sequence *PS to FIRST. */ |
| |
| static inline void |
| gimple_seq_set_first (gimple_seq *ps, gimple_seq_node first) |
| { |
| *ps = first; |
| } |
| |
| |
| /* Return true if GIMPLE sequence S is empty. */ |
| |
| static inline bool |
| gimple_seq_empty_p (gimple_seq s) |
| { |
| return s == NULL; |
| } |
| |
| /* Allocate a new sequence and initialize its first element with STMT. */ |
| |
| static inline gimple_seq |
| gimple_seq_alloc_with_stmt (gimple stmt) |
| { |
| gimple_seq seq = NULL; |
| gimple_seq_add_stmt (&seq, stmt); |
| return seq; |
| } |
| |
| |
| /* Returns the sequence of statements in BB. */ |
| |
| static inline gimple_seq |
| bb_seq (const_basic_block bb) |
| { |
| return (!(bb->flags & BB_RTL)) ? bb->il.gimple.seq : NULL; |
| } |
| |
| static inline gimple_seq * |
| bb_seq_addr (basic_block bb) |
| { |
| return (!(bb->flags & BB_RTL)) ? &bb->il.gimple.seq : NULL; |
| } |
| |
| /* Sets the sequence of statements in BB to SEQ. */ |
| |
| static inline void |
| set_bb_seq (basic_block bb, gimple_seq seq) |
| { |
| gcc_checking_assert (!(bb->flags & BB_RTL)); |
| bb->il.gimple.seq = seq; |
| } |
| |
| |
| /* Return the code for GIMPLE statement G. */ |
| |
| static inline enum gimple_code |
| gimple_code (const_gimple g) |
| { |
| return g->code; |
| } |
| |
| |
| /* Return the GSS code used by a GIMPLE code. */ |
| |
| static inline enum gimple_statement_structure_enum |
| gss_for_code (enum gimple_code code) |
| { |
| gcc_gimple_checking_assert ((unsigned int)code < LAST_AND_UNUSED_GIMPLE_CODE); |
| return gss_for_code_[code]; |
| } |
| |
| |
| /* Return which GSS code is used by GS. */ |
| |
| static inline enum gimple_statement_structure_enum |
| gimple_statement_structure (gimple gs) |
| { |
| return gss_for_code (gimple_code (gs)); |
| } |
| |
| |
| /* Return true if statement G has sub-statements. This is only true for |
| High GIMPLE statements. */ |
| |
| static inline bool |
| gimple_has_substatements (gimple g) |
| { |
| switch (gimple_code (g)) |
| { |
| case GIMPLE_BIND: |
| case GIMPLE_CATCH: |
| case GIMPLE_EH_FILTER: |
| case GIMPLE_EH_ELSE: |
| case GIMPLE_TRY: |
| case GIMPLE_OMP_FOR: |
| case GIMPLE_OMP_MASTER: |
| case GIMPLE_OMP_TASKGROUP: |
| case GIMPLE_OMP_ORDERED: |
| case GIMPLE_OMP_SECTION: |
| case GIMPLE_OMP_PARALLEL: |
| case GIMPLE_OMP_TASK: |
| case GIMPLE_OMP_SECTIONS: |
| case GIMPLE_OMP_SINGLE: |
| case GIMPLE_OMP_TARGET: |
| case GIMPLE_OMP_TEAMS: |
| case GIMPLE_OMP_CRITICAL: |
| case GIMPLE_WITH_CLEANUP_EXPR: |
| case GIMPLE_TRANSACTION: |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| |
| /* Return the basic block holding statement G. */ |
| |
| static inline basic_block |
| gimple_bb (const_gimple g) |
| { |
| return g->bb; |
| } |
| |
| |
| /* Return the lexical scope block holding statement G. */ |
| |
| static inline tree |
| gimple_block (const_gimple g) |
| { |
| return LOCATION_BLOCK (g->location); |
| } |
| |
| |
| /* Set BLOCK to be the lexical scope block holding statement G. */ |
| |
| static inline void |
| gimple_set_block (gimple g, tree block) |
| { |
| if (block) |
| g->location = |
| COMBINE_LOCATION_DATA (line_table, g->location, block); |
| else |
| g->location = LOCATION_LOCUS (g->location); |
| } |
| |
| |
| /* Return location information for statement G. */ |
| |
| static inline location_t |
| gimple_location (const_gimple g) |
| { |
| return g->location; |
| } |
| |
| /* Return location information for statement G if g is not NULL. |
| Otherwise, UNKNOWN_LOCATION is returned. */ |
| |
| static inline location_t |
| gimple_location_safe (const_gimple g) |
| { |
| return g ? gimple_location (g) : UNKNOWN_LOCATION; |
| } |
| |
| /* Return pointer to location information for statement G. */ |
| |
| static inline const location_t * |
| gimple_location_ptr (const_gimple g) |
| { |
| return &g->location; |
| } |
| |
| |
| /* Set location information for statement G. */ |
| |
| static inline void |
| gimple_set_location (gimple g, location_t location) |
| { |
| g->location = location; |
| } |
| |
| |
| /* Return true if G contains location information. */ |
| |
| static inline bool |
| gimple_has_location (const_gimple g) |
| { |
| return LOCATION_LOCUS (gimple_location (g)) != UNKNOWN_LOCATION; |
| } |
| |
| |
| /* Return the file name of the location of STMT. */ |
| |
| static inline const char * |
| gimple_filename (const_gimple stmt) |
| { |
| return LOCATION_FILE (gimple_location (stmt)); |
| } |
| |
| |
| /* Return the line number of the location of STMT. */ |
| |
| static inline int |
| gimple_lineno (const_gimple stmt) |
| { |
| return LOCATION_LINE (gimple_location (stmt)); |
| } |
| |
| |
| /* Determine whether SEQ is a singleton. */ |
| |
| static inline bool |
| gimple_seq_singleton_p (gimple_seq seq) |
| { |
| return ((gimple_seq_first (seq) != NULL) |
| && (gimple_seq_first (seq) == gimple_seq_last (seq))); |
| } |
| |
| /* Return true if no warnings should be emitted for statement STMT. */ |
| |
| static inline bool |
| gimple_no_warning_p (const_gimple stmt) |
| { |
| return stmt->no_warning; |
| } |
| |
| /* Set the no_warning flag of STMT to NO_WARNING. */ |
| |
| static inline void |
| gimple_set_no_warning (gimple stmt, bool no_warning) |
| { |
| stmt->no_warning = (unsigned) no_warning; |
| } |
| |
| /* Set the visited status on statement STMT to VISITED_P. |
| |
| Please note that this 'visited' property of the gimple statement is |
| supposed to be undefined at pass boundaries. This means that a |
| given pass should not assume it contains any useful value when the |
| pass starts and thus can set it to any value it sees fit. |
| |
| You can learn more about the visited property of the gimple |
| statement by reading the comments of the 'visited' data member of |
| struct gimple statement_base. |
| */ |
| |
| static inline void |
| gimple_set_visited (gimple stmt, bool visited_p) |
| { |
| stmt->visited = (unsigned) visited_p; |
| } |
| |
| |
| /* Return the visited status for statement STMT. |
| |
| Please note that this 'visited' property of the gimple statement is |
| supposed to be undefined at pass boundaries. This means that a |
| given pass should not assume it contains any useful value when the |
| pass starts and thus can set it to any value it sees fit. |
| |
| You can learn more about the visited property of the gimple |
| statement by reading the comments of the 'visited' data member of |
| struct gimple statement_base. */ |
| |
| static inline bool |
| gimple_visited_p (gimple stmt) |
| { |
| return stmt->visited; |
| } |
| |
| |
| /* Set pass local flag PLF on statement STMT to VAL_P. |
| |
| Please note that this PLF property of the gimple statement is |
| supposed to be undefined at pass boundaries. This means that a |
| given pass should not assume it contains any useful value when the |
| pass starts and thus can set it to any value it sees fit. |
| |
| You can learn more about the PLF property by reading the comment of |
| the 'plf' data member of struct gimple_statement_structure. */ |
| |
| static inline void |
| gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) |
| { |
| if (val_p) |
| stmt->plf |= (unsigned int) plf; |
| else |
| stmt->plf &= ~((unsigned int) plf); |
| } |
| |
| |
| /* Return the value of pass local flag PLF on statement STMT. |
| |
| Please note that this 'plf' property of the gimple statement is |
| supposed to be undefined at pass boundaries. This means that a |
| given pass should not assume it contains any useful value when the |
| pass starts and thus can set it to any value it sees fit. |
| |
| You can learn more about the plf property by reading the comment of |
| the 'plf' data member of struct gimple_statement_structure. */ |
| |
| static inline unsigned int |
| gimple_plf (gimple stmt, enum plf_mask plf) |
| { |
| return stmt->plf & ((unsigned int) plf); |
| } |
| |
| |
| /* Set the UID of statement. |
| |
| Please note that this UID property is supposed to be undefined at |
| pass boundaries. This means that a given pass should not assume it |
| contains any useful value when the pass starts and thus can set it |
| to any value it sees fit. */ |
| |
| static inline void |
| gimple_set_uid (gimple g, unsigned uid) |
| { |
| g->uid = uid; |
| } |
| |
| |
| /* Return the UID of statement. |
| |
| Please note that this UID property is supposed to be undefined at |
| pass boundaries. This means that a given pass should not assume it |
| contains any useful value when the pass starts and thus can set it |
| to any value it sees fit. */ |
| |
| static inline unsigned |
| gimple_uid (const_gimple g) |
| { |
| return g->uid; |
| } |
| |
| |
| /* Make statement G a singleton sequence. */ |
| |
| static inline void |
| gimple_init_singleton (gimple g) |
| { |
| g->next = NULL; |
| g->prev = g; |
| } |
| |
| |
| /* Return true if GIMPLE statement G has register or memory operands. */ |
| |
| static inline bool |
| gimple_has_ops (const_gimple g) |
| { |
| return gimple_code (g) >= GIMPLE_COND && gimple_code (g) <= GIMPLE_RETURN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gimple_statement_with_ops *>::test (const_gimple gs) |
| { |
| return gimple_has_ops (gs); |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gimple_statement_with_ops *>::test (gimple gs) |
| { |
| return gimple_has_ops (gs); |
| } |
| |
| /* Return true if GIMPLE statement G has memory operands. */ |
| |
| static inline bool |
| gimple_has_mem_ops (const_gimple g) |
| { |
| return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN; |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <const gimple_statement_with_memory_ops *>::test (const_gimple gs) |
| { |
| return gimple_has_mem_ops (gs); |
| } |
| |
| template <> |
| template <> |
| inline bool |
| is_a_helper <gimple_statement_with_memory_ops *>::test (gimple gs) |
| { |
| return gimple_has_mem_ops (gs); |
| } |
| |
| /* Return the set of USE operands for statement G. */ |
| |
| static inline struct use_optype_d * |
| gimple_use_ops (const_gimple g) |
| { |
| const gimple_statement_with_ops *ops_stmt = |
| dyn_cast <const gimple_statement_with_ops *> (g); |
| if (!ops_stmt) |
| return NULL; |
| return ops_stmt->use_ops; |
| } |
| |
| |
| /* Set USE to be the set of USE operands for statement G. */ |
| |
| static inline void |
| gimple_set_use_ops (gimple g, struct use_optype_d *use) |
| { |
| gimple_statement_with_ops *ops_stmt = |
| as_a <gimple_statement_with_ops *> (g); |
| ops_stmt->use_ops = use; |
| } |
| |
| |
| /* Return the single VUSE operand of the statement G. */ |
| |
| static inline tree |
| gimple_vuse (const_gimple g) |
| { |
| const gimple_statement_with_memory_ops *mem_ops_stmt = |
| dyn_cast <const gimple_statement_with_memory_ops *> (g); |
| if (!mem_ops_stmt) |
| return NULL_TREE; |
| return mem_ops_stmt->vuse; |
| } |
| |
| /* Return the single VDEF operand of the statement G. */ |
| |
| static inline tree |
| gimple_vdef (const_gimple g) |
| { |
| const gimple_statement_with_memory_ops *mem_ops_stmt = |
| dyn_cast <const gimple_statement_with_memory_ops *> (g); |
| if (!mem_ops_stmt) |
| return NULL_TREE; |
| return mem_ops_stmt->vdef; |
| } |
| |
| /* Return the single VUSE operand of the statement G. */ |
| |
| static inline tree * |
| gimple_vuse_ptr (gimple g) |
| { |
| gimple_statement_with_memory_ops *mem_ops_stmt = |
| dyn_cast <gimple_statement_with_memory_ops *> (g); |
| if (!mem_ops_stmt) |
| return NULL; |
| return &mem_ops_stmt->vuse; |
| } |
| |
| /* Return the single VDEF operand of the statement G. */ |
| |
| static inline tree * |
| gimple_vdef_ptr (gimple g) |
| { |
| gimple_statement_with_memory_ops *mem_ops_stmt = |
| dyn_cast <gimple_statement_with_memory_ops *> (g); |
| if (!mem_ops_stmt) |
| return NULL; |
| return &mem_ops_stmt->vdef; |
| } |
| |
| /* Set the single VUSE operand of the statement G. */ |
| |
| static inline void |
| gimple_set_vuse (gimple g, tree vuse) |
| { |
| gimple_statement_with_memory_ops *mem_ops_stmt = |
| as_a <gimple_statement_with_memory_ops *> (g); |
| mem_ops_stmt->vuse = vuse; |
| } |
| |
| /* Set the single VDEF operand of the statement G. */ |
| |
| static inline void |
| gimple_set_vdef (gimple g, tree vdef) |
| { |
| gimple_statement_with_memory_ops *mem_ops_stmt = |
| as_a <gimple_statement_with_memory_ops *> (g); |
| mem_ops_stmt->vdef = vdef; |
| } |
| |
| |
| /* Return true if statement G has operands and the modified field has |
| been set. */ |
| |
| static inline bool |
| gimple_modified_p (const_gimple g) |
| { |
| return (gimple_has_ops (g)) ? (bool) g->modified : false; |
| } |
| |
| |
| /* Set the MODIFIED flag to MODIFIEDP, iff the gimple statement G has |
| a MODIFIED field. */ |
| |
| static inline void |
| gimple_set_modified (gimple s, bool modifiedp) |
| { |
| if (gimple_has_ops (s)) |
| s->modified = (unsigned) modifiedp; |
| } |
| |
| |
| /* Return the tree code for the expression computed by STMT. This is |
| only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For |
| GIMPLE_CALL, return CALL_EXPR as the expression code for |
| consistency. This is useful when the caller needs to deal with the |
| three kinds of computation that GIMPLE supports. */ |
| |
| static inline enum tree_code |
| gimple_expr_code (const_gimple stmt) |
| { |
| enum gimple_code code = gimple_code (stmt); |
| if (code == GIMPLE_ASSIGN || code == GIMPLE_COND) |
| return (enum tree_code) stmt->subcode; |
| else |
| { |
| gcc_gimple_checking_assert (code == GIMPLE_CALL); |
| return CALL_EXPR; |
| } |
| } |
| |
| |
| /* Return true if statement STMT contains volatile operands. */ |
| |
| static inline bool |
| gimple_has_volatile_ops (const_gimple stmt) |
| { |
| if (gimple_has_mem_ops (stmt)) |
| return stmt->has_volatile_ops; |
| else |
| return false; |
| } |
| |
| |
| /* Set the HAS_VOLATILE_OPS flag to VOLATILEP. */ |
| |
| static inline void |
| gimple_set_has_volatile_ops (gimple stmt, bool volatilep) |
| { |
| if (gimple_has_mem_ops (stmt)) |
| stmt->has_volatile_ops = (unsigned) volatilep; |
| } |
| |
| /* Return true if STMT is in a transaction. */ |
| |
| static inline bool |
| gimple_in_transaction (gimple stmt) |
| { |
| return bb_in_transaction (gimple_bb (stmt)); |
| } |
| |
| /* Return true if statement STMT may access memory. */ |
| |
| static inline bool |
| gimple_references_memory_p (gimple stmt) |
| { |
| return gimple_has_mem_ops (stmt) && gimple_vuse (stmt); |
| } |
| |
| |
| /* Return the subcode for OMP statement S. */ |
| |
| static inline unsigned |
| gimple_omp_subcode (const_gimple s) |
| { |
| gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD |
| && gimple_code (s) <= GIMPLE_OMP_TEAMS); |
| return s->subcode; |
| } |
| |
| /* Set the subcode for OMP statement S to SUBCODE. */ |
| |
| static inline void |
| gimple_omp_set_subcode (gimple s, unsigned int subcode) |
| { |
| /* We only have 16 bits for the subcode. Assert that we are not |
| overflowing it. */ |
| gcc_gimple_checking_assert (subcode < (1 << 16)); |
| s->subcode = subcode; |
| } |
| |
| /* Set the nowait flag on OMP_RETURN statement S. */ |
| |
| static inline void |
| gimple_omp_return_set_nowait (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_OMP_RETURN); |
| s->subcode |= GF_OMP_RETURN_NOWAIT; |
| } |
| |
| |
| /* Return true if OMP return statement G has the GF_OMP_RETURN_NOWAIT |
| flag set. */ |
| |
| static inline bool |
| gimple_omp_return_nowait_p (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); |
| return (gimple_omp_subcode (g) & GF_OMP_RETURN_NOWAIT) != 0; |
| } |
| |
| |
| /* Set the LHS of OMP return. */ |
| |
| static inline void |
| gimple_omp_return_set_lhs (gimple g, tree lhs) |
| { |
| gimple_statement_omp_return *omp_return_stmt = |
| as_a <gimple_statement_omp_return *> (g); |
| omp_return_stmt->val = lhs; |
| } |
| |
| |
| /* Get the LHS of OMP return. */ |
| |
| static inline tree |
| gimple_omp_return_lhs (const_gimple g) |
| { |
| const gimple_statement_omp_return *omp_return_stmt = |
| as_a <const gimple_statement_omp_return *> (g); |
| return omp_return_stmt->val; |
| } |
| |
| |
| /* Return a pointer to the LHS of OMP return. */ |
| |
| static inline tree * |
| gimple_omp_return_lhs_ptr (gimple g) |
| { |
| gimple_statement_omp_return *omp_return_stmt = |
| as_a <gimple_statement_omp_return *> (g); |
| return &omp_return_stmt->val; |
| } |
| |
| |
| /* Return true if OMP section statement G has the GF_OMP_SECTION_LAST |
| flag set. */ |
| |
| static inline bool |
| gimple_omp_section_last_p (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); |
| return (gimple_omp_subcode (g) & GF_OMP_SECTION_LAST) != 0; |
| } |
| |
| |
| /* Set the GF_OMP_SECTION_LAST flag on G. */ |
| |
| static inline void |
| gimple_omp_section_set_last (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); |
| g->subcode |= GF_OMP_SECTION_LAST; |
| } |
| |
| |
| /* Return true if OMP parallel statement G has the |
| GF_OMP_PARALLEL_COMBINED flag set. */ |
| |
| static inline bool |
| gimple_omp_parallel_combined_p (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); |
| return (gimple_omp_subcode (g) & GF_OMP_PARALLEL_COMBINED) != 0; |
| } |
| |
| |
| /* Set the GF_OMP_PARALLEL_COMBINED field in G depending on the boolean |
| value of COMBINED_P. */ |
| |
| static inline void |
| gimple_omp_parallel_set_combined_p (gimple g, bool combined_p) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); |
| if (combined_p) |
| g->subcode |= GF_OMP_PARALLEL_COMBINED; |
| else |
| g->subcode &= ~GF_OMP_PARALLEL_COMBINED; |
| } |
| |
| |
| /* Return true if OMP atomic load/store statement G has the |
| GF_OMP_ATOMIC_NEED_VALUE flag set. */ |
| |
| static inline bool |
| gimple_omp_atomic_need_value_p (const_gimple g) |
| { |
| if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| return (gimple_omp_subcode (g) & GF_OMP_ATOMIC_NEED_VALUE) != 0; |
| } |
| |
| |
| /* Set the GF_OMP_ATOMIC_NEED_VALUE flag on G. */ |
| |
| static inline void |
| gimple_omp_atomic_set_need_value (gimple g) |
| { |
| if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| g->subcode |= GF_OMP_ATOMIC_NEED_VALUE; |
| } |
| |
| |
| /* Return true if OMP atomic load/store statement G has the |
| GF_OMP_ATOMIC_SEQ_CST flag set. */ |
| |
| static inline bool |
| gimple_omp_atomic_seq_cst_p (const_gimple g) |
| { |
| if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| return (gimple_omp_subcode (g) & GF_OMP_ATOMIC_SEQ_CST) != 0; |
| } |
| |
| |
| /* Set the GF_OMP_ATOMIC_SEQ_CST flag on G. */ |
| |
| static inline void |
| gimple_omp_atomic_set_seq_cst (gimple g) |
| { |
| if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| g->subcode |= GF_OMP_ATOMIC_SEQ_CST; |
| } |
| |
| |
| /* Return the number of operands for statement GS. */ |
| |
| static inline unsigned |
| gimple_num_ops (const_gimple gs) |
| { |
| return gs->num_ops; |
| } |
| |
| |
| /* Set the number of operands for statement GS. */ |
| |
| static inline void |
| gimple_set_num_ops (gimple gs, unsigned num_ops) |
| { |
| gs->num_ops = num_ops; |
| } |
| |
| |
| /* Return the array of operands for statement GS. */ |
| |
| static inline tree * |
| gimple_ops (gimple gs) |
| { |
| size_t off; |
| |
| /* All the tuples have their operand vector at the very bottom |
| of the structure. Note that those structures that do not |
| have an operand vector have a zero offset. */ |
| off = gimple_ops_offset_[gimple_statement_structure (gs)]; |
| gcc_gimple_checking_assert (off != 0); |
| |
| return (tree *) ((char *) gs + off); |
| } |
| |
| |
| /* Return operand I for statement GS. */ |
| |
| static inline tree |
| gimple_op (const_gimple gs, unsigned i) |
| { |
| if (gimple_has_ops (gs)) |
| { |
| gcc_gimple_checking_assert (i < gimple_num_ops (gs)); |
| return gimple_ops (CONST_CAST_GIMPLE (gs))[i]; |
| } |
| else |
| return NULL_TREE; |
| } |
| |
| /* Return a pointer to operand I for statement GS. */ |
| |
| static inline tree * |
| gimple_op_ptr (const_gimple gs, unsigned i) |
| { |
| if (gimple_has_ops (gs)) |
| { |
| gcc_gimple_checking_assert (i < gimple_num_ops (gs)); |
| return gimple_ops (CONST_CAST_GIMPLE (gs)) + i; |
| } |
| else |
| return NULL; |
| } |
| |
| /* Set operand I of statement GS to OP. */ |
| |
| static inline void |
| gimple_set_op (gimple gs, unsigned i, tree op) |
| { |
| gcc_gimple_checking_assert (gimple_has_ops (gs) && i < gimple_num_ops (gs)); |
| |
| /* Note. It may be tempting to assert that OP matches |
| is_gimple_operand, but that would be wrong. Different tuples |
| accept slightly different sets of tree operands. Each caller |
| should perform its own validation. */ |
| gimple_ops (gs)[i] = op; |
| } |
| |
| /* Return true if GS is a GIMPLE_ASSIGN. */ |
| |
| static inline bool |
| is_gimple_assign (const_gimple gs) |
| { |
| return gimple_code (gs) == GIMPLE_ASSIGN; |
| } |
| |
| /* Determine if expression CODE is one of the valid expressions that can |
| be used on the RHS of GIMPLE assignments. */ |
| |
| static inline enum gimple_rhs_class |
| get_gimple_rhs_class (enum tree_code code) |
| { |
| return (enum gimple_rhs_class) gimple_rhs_class_table[(int) code]; |
| } |
| |
| /* Return the LHS of assignment statement GS. */ |
| |
| static inline tree |
| gimple_assign_lhs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Return a pointer to the LHS of assignment statement GS. */ |
| |
| static inline tree * |
| gimple_assign_lhs_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op_ptr (gs, 0); |
| } |
| |
| |
| /* Set LHS to be the LHS operand of assignment statement GS. */ |
| |
| static inline void |
| gimple_assign_set_lhs (gimple gs, tree lhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| gimple_set_op (gs, 0, lhs); |
| |
| if (lhs && TREE_CODE (lhs) == SSA_NAME) |
| SSA_NAME_DEF_STMT (lhs) = gs; |
| } |
| |
| |
| /* Return the first operand on the RHS of assignment statement GS. */ |
| |
| static inline tree |
| gimple_assign_rhs1 (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op (gs, 1); |
| } |
| |
| |
| /* Return a pointer to the first operand on the RHS of assignment |
| statement GS. */ |
| |
| static inline tree * |
| gimple_assign_rhs1_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op_ptr (gs, 1); |
| } |
| |
| /* Set RHS to be the first operand on the RHS of assignment statement GS. */ |
| |
| static inline void |
| gimple_assign_set_rhs1 (gimple gs, tree rhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| gimple_set_op (gs, 1, rhs); |
| } |
| |
| |
| /* Return the second operand on the RHS of assignment statement GS. |
| If GS does not have two operands, NULL is returned instead. */ |
| |
| static inline tree |
| gimple_assign_rhs2 (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| if (gimple_num_ops (gs) >= 3) |
| return gimple_op (gs, 2); |
| else |
| return NULL_TREE; |
| } |
| |
| |
| /* Return a pointer to the second operand on the RHS of assignment |
| statement GS. */ |
| |
| static inline tree * |
| gimple_assign_rhs2_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op_ptr (gs, 2); |
| } |
| |
| |
| /* Set RHS to be the second operand on the RHS of assignment statement GS. */ |
| |
| static inline void |
| gimple_assign_set_rhs2 (gimple gs, tree rhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| gimple_set_op (gs, 2, rhs); |
| } |
| |
| /* Return the third operand on the RHS of assignment statement GS. |
| If GS does not have two operands, NULL is returned instead. */ |
| |
| static inline tree |
| gimple_assign_rhs3 (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| if (gimple_num_ops (gs) >= 4) |
| return gimple_op (gs, 3); |
| else |
| return NULL_TREE; |
| } |
| |
| /* Return a pointer to the third operand on the RHS of assignment |
| statement GS. */ |
| |
| static inline tree * |
| gimple_assign_rhs3_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gimple_op_ptr (gs, 3); |
| } |
| |
| |
| /* Set RHS to be the third operand on the RHS of assignment statement GS. */ |
| |
| static inline void |
| gimple_assign_set_rhs3 (gimple gs, tree rhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| gimple_set_op (gs, 3, rhs); |
| } |
| |
| /* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers |
| which expect to see only two operands. */ |
| |
| static inline void |
| gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code, |
| tree op1, tree op2) |
| { |
| gimple_assign_set_rhs_with_ops (gsi, code, op1, op2, NULL); |
| } |
| |
| /* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers |
| which expect to see only one operands. */ |
| |
| static inline void |
| gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code, |
| tree op1) |
| { |
| gimple_assign_set_rhs_with_ops (gsi, code, op1, NULL, NULL); |
| } |
| |
| /* Returns true if GS is a nontemporal move. */ |
| |
| static inline bool |
| gimple_assign_nontemporal_move_p (const gassign *gs) |
| { |
| return gs->nontemporal_move; |
| } |
| |
| /* Sets nontemporal move flag of GS to NONTEMPORAL. */ |
| |
| static inline void |
| gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| gs->nontemporal_move = nontemporal; |
| } |
| |
| |
| /* Return the code of the expression computed on the rhs of assignment |
| statement GS. In case that the RHS is a single object, returns the |
| tree code of the object. */ |
| |
| static inline enum tree_code |
| gimple_assign_rhs_code (const_gimple gs) |
| { |
| enum tree_code code; |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| |
| code = (enum tree_code) gs->subcode; |
| /* While we initially set subcode to the TREE_CODE of the rhs for |
| GIMPLE_SINGLE_RHS assigns we do not update that subcode to stay |
| in sync when we rewrite stmts into SSA form or do SSA propagations. */ |
| if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS) |
| code = TREE_CODE (gimple_assign_rhs1 (gs)); |
| |
| return code; |
| } |
| |
| |
| /* Set CODE to be the code for the expression computed on the RHS of |
| assignment S. */ |
| |
| static inline void |
| gimple_assign_set_rhs_code (gimple s, enum tree_code code) |
| { |
| GIMPLE_CHECK (s, GIMPLE_ASSIGN); |
| s->subcode = code; |
| } |
| |
| |
| /* Return the gimple rhs class of the code of the expression computed on |
| the rhs of assignment statement GS. |
| This will never return GIMPLE_INVALID_RHS. */ |
| |
| static inline enum gimple_rhs_class |
| gimple_assign_rhs_class (const_gimple gs) |
| { |
| return get_gimple_rhs_class (gimple_assign_rhs_code (gs)); |
| } |
| |
| /* Return true if GS is an assignment with a singleton RHS, i.e., |
| there is no operator associated with the assignment itself. |
| Unlike gimple_assign_copy_p, this predicate returns true for |
| any RHS operand, including those that perform an operation |
| and do not have the semantics of a copy, such as COND_EXPR. */ |
| |
| static inline bool |
| gimple_assign_single_p (const_gimple gs) |
| { |
| return (is_gimple_assign (gs) |
| && gimple_assign_rhs_class (gs) == GIMPLE_SINGLE_RHS); |
| } |
| |
| /* Return true if GS performs a store to its lhs. */ |
| |
| static inline bool |
| gimple_store_p (const_gimple gs) |
| { |
| tree lhs = gimple_get_lhs (gs); |
| return lhs && !is_gimple_reg (lhs); |
| } |
| |
| /* Return true if GS is an assignment that loads from its rhs1. */ |
| |
| static inline bool |
| gimple_assign_load_p (const_gimple gs) |
| { |
| tree rhs; |
| if (!gimple_assign_single_p (gs)) |
| return false; |
| rhs = gimple_assign_rhs1 (gs); |
| if (TREE_CODE (rhs) == WITH_SIZE_EXPR) |
| return true; |
| rhs = get_base_address (rhs); |
| return (DECL_P (rhs) |
| || TREE_CODE (rhs) == MEM_REF || TREE_CODE (rhs) == TARGET_MEM_REF); |
| } |
| |
| |
| /* Return true if S is a type-cast assignment. */ |
| |
| static inline bool |
| gimple_assign_cast_p (const_gimple s) |
| { |
| if (is_gimple_assign (s)) |
| { |
| enum tree_code sc = gimple_assign_rhs_code (s); |
| return CONVERT_EXPR_CODE_P (sc) |
| || sc == VIEW_CONVERT_EXPR |
| || sc == FIX_TRUNC_EXPR; |
| } |
| |
| return false; |
| } |
| |
| /* Return true if S is a clobber statement. */ |
| |
| static inline bool |
| gimple_clobber_p (const_gimple s) |
| { |
| return gimple_assign_single_p (s) |
| && TREE_CLOBBER_P (gimple_assign_rhs1 (s)); |
| } |
| |
| /* Return true if GS is a GIMPLE_CALL. */ |
| |
| static inline bool |
| is_gimple_call (const_gimple gs) |
| { |
| return gimple_code (gs) == GIMPLE_CALL; |
| } |
| |
| /* Return the LHS of call statement GS. */ |
| |
| static inline tree |
| gimple_call_lhs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Return a pointer to the LHS of call statement GS. */ |
| |
| static inline tree * |
| gimple_call_lhs_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op_ptr (gs, 0); |
| } |
| |
| |
| /* Set LHS to be the LHS operand of call statement GS. */ |
| |
| static inline void |
| gimple_call_set_lhs (gimple gs, tree lhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| gimple_set_op (gs, 0, lhs); |
| if (lhs && TREE_CODE (lhs) == SSA_NAME) |
| SSA_NAME_DEF_STMT (lhs) = gs; |
| } |
| |
| |
| /* Return true if call GS calls an internal-only function, as enumerated |
| by internal_fn. */ |
| |
| static inline bool |
| gimple_call_internal_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return (gs->subcode & GF_CALL_INTERNAL) != 0; |
| } |
| |
| |
| /* Return true if call GS is marked as instrumented by |
| Pointer Bounds Checker. */ |
| |
| static inline bool |
| gimple_call_with_bounds_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return (gs->subcode & GF_CALL_WITH_BOUNDS) != 0; |
| } |
| |
| |
| /* If INSTRUMENTED_P is true, marm statement GS as instrumented by |
| Pointer Bounds Checker. */ |
| |
| static inline void |
| gimple_call_set_with_bounds (gimple gs, bool with_bounds) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| if (with_bounds) |
| gs->subcode |= GF_CALL_WITH_BOUNDS; |
| else |
| gs->subcode &= ~GF_CALL_WITH_BOUNDS; |
| } |
| |
| |
| /* Return the target of internal call GS. */ |
| |
| static inline enum internal_fn |
| gimple_call_internal_fn (const_gimple gs) |
| { |
| gcc_gimple_checking_assert (gimple_call_internal_p (gs)); |
| return static_cast <const gcall *> (gs)->u.internal_fn; |
| } |
| |
| /* If CTRL_ALTERING_P is true, mark GIMPLE_CALL S to be a stmt |
| that could alter control flow. */ |
| |
| static inline void |
| gimple_call_set_ctrl_altering (gimple s, bool ctrl_altering_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (ctrl_altering_p) |
| s->subcode |= GF_CALL_CTRL_ALTERING; |
| else |
| s->subcode &= ~GF_CALL_CTRL_ALTERING; |
| } |
| |
| /* Return true if call GS calls an func whose GF_CALL_CTRL_ALTERING |
| flag is set. Such call could not be a stmt in the middle of a bb. */ |
| |
| static inline bool |
| gimple_call_ctrl_altering_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return (gs->subcode & GF_CALL_CTRL_ALTERING) != 0; |
| } |
| |
| |
| /* Return the function type of the function called by GS. */ |
| |
| static inline tree |
| gimple_call_fntype (const_gimple gs) |
| { |
| const gcall *call_stmt = as_a <const gcall *> (gs); |
| if (gimple_call_internal_p (gs)) |
| return NULL_TREE; |
| return call_stmt->u.fntype; |
| } |
| |
| /* Set the type of the function called by CALL_STMT to FNTYPE. */ |
| |
| static inline void |
| gimple_call_set_fntype (gcall *call_stmt, tree fntype) |
| { |
| gcc_gimple_checking_assert (!gimple_call_internal_p (call_stmt)); |
| call_stmt->u.fntype = fntype; |
| } |
| |
| |
| /* Return the tree node representing the function called by call |
| statement GS. */ |
| |
| static inline tree |
| gimple_call_fn (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op (gs, 1); |
| } |
| |
| /* Return a pointer to the tree node representing the function called by call |
| statement GS. */ |
| |
| static inline tree * |
| gimple_call_fn_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op_ptr (gs, 1); |
| } |
| |
| |
| /* Set FN to be the function called by call statement GS. */ |
| |
| static inline void |
| gimple_call_set_fn (gcall *gs, tree fn) |
| { |
| gcc_gimple_checking_assert (!gimple_call_internal_p (gs)); |
| gimple_set_op (gs, 1, fn); |
| } |
| |
| |
| /* Set FNDECL to be the function called by call statement GS. */ |
| |
| static inline void |
| gimple_call_set_fndecl (gimple gs, tree decl) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| gcc_gimple_checking_assert (!gimple_call_internal_p (gs)); |
| gimple_set_op (gs, 1, build_fold_addr_expr_loc (gimple_location (gs), decl)); |
| } |
| |
| |
| /* Set internal function FN to be the function called by call statement CALL_STMT. */ |
| |
| static inline void |
| gimple_call_set_internal_fn (gcall *call_stmt, enum internal_fn fn) |
| { |
| gcc_gimple_checking_assert (gimple_call_internal_p (call_stmt)); |
| call_stmt->u.internal_fn = fn; |
| } |
| |
| |
| /* If a given GIMPLE_CALL's callee is a FUNCTION_DECL, return it. |
| Otherwise return NULL. This function is analogous to |
| get_callee_fndecl in tree land. */ |
| |
| static inline tree |
| gimple_call_fndecl (const_gimple gs) |
| { |
| return gimple_call_addr_fndecl (gimple_call_fn (gs)); |
| } |
| |
| |
| /* Return the type returned by call statement GS. */ |
| |
| static inline tree |
| gimple_call_return_type (const gcall *gs) |
| { |
| tree type = gimple_call_fntype (gs); |
| |
| if (type == NULL_TREE) |
| return TREE_TYPE (gimple_call_lhs (gs)); |
| |
| /* The type returned by a function is the type of its |
| function type. */ |
| return TREE_TYPE (type); |
| } |
| |
| |
| /* Return the static chain for call statement GS. */ |
| |
| static inline tree |
| gimple_call_chain (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op (gs, 2); |
| } |
| |
| |
| /* Return a pointer to the static chain for call statement CALL_STMT. */ |
| |
| static inline tree * |
| gimple_call_chain_ptr (const gcall *call_stmt) |
| { |
| return gimple_op_ptr (call_stmt, 2); |
| } |
| |
| /* Set CHAIN to be the static chain for call statement CALL_STMT. */ |
| |
| static inline void |
| gimple_call_set_chain (gcall *call_stmt, tree chain) |
| { |
| gimple_set_op (call_stmt, 2, chain); |
| } |
| |
| |
| /* Return the number of arguments used by call statement GS. */ |
| |
| static inline unsigned |
| gimple_call_num_args (const_gimple gs) |
| { |
| unsigned num_ops; |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| num_ops = gimple_num_ops (gs); |
| return num_ops - 3; |
| } |
| |
| |
| /* Return the argument at position INDEX for call statement GS. */ |
| |
| static inline tree |
| gimple_call_arg (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op (gs, index + 3); |
| } |
| |
| |
| /* Return a pointer to the argument at position INDEX for call |
| statement GS. */ |
| |
| static inline tree * |
| gimple_call_arg_ptr (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op_ptr (gs, index + 3); |
| } |
| |
| |
| /* Set ARG to be the argument at position INDEX for call statement GS. */ |
| |
| static inline void |
| gimple_call_set_arg (gimple gs, unsigned index, tree arg) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| gimple_set_op (gs, index + 3, arg); |
| } |
| |
| |
| /* If TAIL_P is true, mark call statement S as being a tail call |
| (i.e., a call just before the exit of a function). These calls are |
| candidate for tail call optimization. */ |
| |
| static inline void |
| gimple_call_set_tail (gcall *s, bool tail_p) |
| { |
| if (tail_p) |
| s->subcode |= GF_CALL_TAILCALL; |
| else |
| s->subcode &= ~GF_CALL_TAILCALL; |
| } |
| |
| |
| /* Return true if GIMPLE_CALL S is marked as a tail call. */ |
| |
| static inline bool |
| gimple_call_tail_p (gcall *s) |
| { |
| return (s->subcode & GF_CALL_TAILCALL) != 0; |
| } |
| |
| |
| /* If RETURN_SLOT_OPT_P is true mark GIMPLE_CALL S as valid for return |
| slot optimization. This transformation uses the target of the call |
| expansion as the return slot for calls that return in memory. */ |
| |
| static inline void |
| gimple_call_set_return_slot_opt (gcall *s, bool return_slot_opt_p) |
| { |
| if (return_slot_opt_p) |
| s->subcode |= GF_CALL_RETURN_SLOT_OPT; |
| else |
| s->subcode &= ~GF_CALL_RETURN_SLOT_OPT; |
| } |
| |
| |
| /* Return true if S is marked for return slot optimization. */ |
| |
| static inline bool |
| gimple_call_return_slot_opt_p (gcall *s) |
| { |
| return (s->subcode & GF_CALL_RETURN_SLOT_OPT) != 0; |
| } |
| |
| |
| /* If FROM_THUNK_P is true, mark GIMPLE_CALL S as being the jump from a |
| thunk to the thunked-to function. */ |
| |
| static inline void |
| gimple_call_set_from_thunk (gcall *s, bool from_thunk_p) |
| { |
| if (from_thunk_p) |
| s->subcode |= GF_CALL_FROM_THUNK; |
| else |
| s->subcode &= ~GF_CALL_FROM_THUNK; |
| } |
| |
| |
| /* Return true if GIMPLE_CALL S is a jump from a thunk. */ |
| |
| static inline bool |
| gimple_call_from_thunk_p (gcall *s) |
| { |
| return (s->subcode & GF_CALL_FROM_THUNK) != 0; |
| } |
| |
| |
| /* If PASS_ARG_PACK_P is true, GIMPLE_CALL S is a stdarg call that needs the |
| argument pack in its argument list. */ |
| |
| static inline void |
| gimple_call_set_va_arg_pack (gcall *s, bool pass_arg_pack_p) |
| { |
| if (pass_arg_pack_p) |
| s->subcode |= GF_CALL_VA_ARG_PACK; |
| else |
| s->subcode &= ~GF_CALL_VA_ARG_PACK; |
| } |
| |
| |
| /* Return true if GIMPLE_CALL S is a stdarg call that needs the |
| argument pack in its argument list. */ |
| |
| static inline bool |
| gimple_call_va_arg_pack_p (gcall *s) |
| { |
| return (s->subcode & GF_CALL_VA_ARG_PACK) != 0; |
| } |
| |
| |
| /* Return true if S is a noreturn call. */ |
| |
| static inline bool |
| gimple_call_noreturn_p (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (gimple_call_flags (s) & ECF_NORETURN) != 0; |
| } |
| |
| |
| /* If NOTHROW_P is true, GIMPLE_CALL S is a call that is known to not throw |
| even if the called function can throw in other cases. */ |
| |
| static inline void |
| gimple_call_set_nothrow (gcall *s, bool nothrow_p) |
| { |
| if (nothrow_p) |
| s->subcode |= GF_CALL_NOTHROW; |
| else |
| s->subcode &= ~GF_CALL_NOTHROW; |
| } |
| |
| /* Return true if S is a nothrow call. */ |
| |
| static inline bool |
| gimple_call_nothrow_p (gcall *s) |
| { |
| return (gimple_call_flags (s) & ECF_NOTHROW) != 0; |
| } |
| |
| /* If FOR_VAR is true, GIMPLE_CALL S is a call to builtin_alloca that |
| is known to be emitted for VLA objects. Those are wrapped by |
| stack_save/stack_restore calls and hence can't lead to unbounded |
| stack growth even when they occur in loops. */ |
| |
| static inline void |
| gimple_call_set_alloca_for_var (gcall *s, bool for_var) |
| { |
| if (for_var) |
| s->subcode |= GF_CALL_ALLOCA_FOR_VAR; |
| else |
| s->subcode &= ~GF_CALL_ALLOCA_FOR_VAR; |
| } |
| |
| /* Return true of S is a call to builtin_alloca emitted for VLA objects. */ |
| |
| static inline bool |
| gimple_call_alloca_for_var_p (gcall *s) |
| { |
| return (s->subcode & GF_CALL_ALLOCA_FOR_VAR) != 0; |
| } |
| |
| /* Copy all the GF_CALL_* flags from ORIG_CALL to DEST_CALL. */ |
| |
| static inline void |
| gimple_call_copy_flags (gcall *dest_call, gcall *orig_call) |
| { |
| dest_call->subcode = orig_call->subcode; |
| } |
| |
| |
| /* Return a pointer to the points-to solution for the set of call-used |
| variables of the call CALL_STMT. */ |
| |
| static inline struct pt_solution * |
| gimple_call_use_set (gcall *call_stmt) |
| { |
| return &call_stmt->call_used; |
| } |
| |
| |
| /* Return a pointer to the points-to solution for the set of call-used |
| variables of the call CALL_STMT. */ |
| |
| static inline struct pt_solution * |
| gimple_call_clobber_set (gcall *call_stmt) |
| { |
| return &call_stmt->call_clobbered; |
| } |
| |
| |
| /* Returns true if this is a GIMPLE_ASSIGN or a GIMPLE_CALL with a |
| non-NULL lhs. */ |
| |
| static inline bool |
| gimple_has_lhs (gimple stmt) |
| { |
| return (is_gimple_assign (stmt) |
| || (is_gimple_call (stmt) |
| && gimple_call_lhs (stmt) != NULL_TREE)); |
| } |
| |
| |
| /* Return the code of the predicate computed by conditional statement GS. */ |
| |
| static inline enum tree_code |
| gimple_cond_code (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| return (enum tree_code) gs->subcode; |
| } |
| |
| |
| /* Set CODE to be the predicate code for the conditional statement GS. */ |
| |
| static inline void |
| gimple_cond_set_code (gcond *gs, enum tree_code code) |
| { |
| gs->subcode = code; |
| } |
| |
| |
| /* Return the LHS of the predicate computed by conditional statement GS. */ |
| |
| static inline tree |
| gimple_cond_lhs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| return gimple_op (gs, 0); |
| } |
| |
| /* Return the pointer to the LHS of the predicate computed by conditional |
| statement GS. */ |
| |
| static inline tree * |
| gimple_cond_lhs_ptr (const gcond *gs) |
| { |
| return gimple_op_ptr (gs, 0); |
| } |
| |
| /* Set LHS to be the LHS operand of the predicate computed by |
| conditional statement GS. */ |
| |
| static inline void |
| gimple_cond_set_lhs (gcond *gs, tree lhs) |
| { |
| gimple_set_op (gs, 0, lhs); |
| } |
| |
| |
| /* Return the RHS operand of the predicate computed by conditional GS. */ |
| |
| static inline tree |
| gimple_cond_rhs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| return gimple_op (gs, 1); |
| } |
| |
| /* Return the pointer to the RHS operand of the predicate computed by |
| conditional GS. */ |
| |
| static inline tree * |
| gimple_cond_rhs_ptr (const gcond *gs) |
| { |
| return gimple_op_ptr (gs, 1); |
| } |
| |
| |
| /* Set RHS to be the RHS operand of the predicate computed by |
| conditional statement GS. */ |
| |
| static inline void |
| gimple_cond_set_rhs (gcond *gs, tree rhs) |
| { |
| gimple_set_op (gs, 1, rhs); |
| } |
| |
| |
| /* Return the label used by conditional statement GS when its |
| predicate evaluates to true. */ |
| |
| static inline tree |
| gimple_cond_true_label (const gcond *gs) |
| { |
| return gimple_op (gs, 2); |
| } |
| |
| |
| /* Set LABEL to be the label used by conditional statement GS when its |
| predicate evaluates to true. */ |
| |
| static inline void |
| gimple_cond_set_true_label (gcond *gs, tree label) |
| { |
| gimple_set_op (gs, 2, label); |
| } |
| |
| |
| /* Set LABEL to be the label used by conditional statement GS when its |
| predicate evaluates to false. */ |
| |
| static inline void |
| gimple_cond_set_false_label (gcond *gs, tree label) |
| { |
| gimple_set_op (gs, 3, label); |
| } |
| |
| |
| /* Return the label used by conditional statement GS when its |
| predicate evaluates to false. */ |
| |
| static inline tree |
| gimple_cond_false_label (const gcond *gs) |
| { |
| |
| return gimple_op (gs, 3); |
| } |
| |
| |
| /* Set the conditional COND_STMT to be of the form 'if (1 == 0)'. */ |
| |
| static inline void |
| gimple_cond_make_false (gcond *gs) |
| { |
| gimple_cond_set_lhs (gs, boolean_true_node); |
| gimple_cond_set_rhs (gs, boolean_false_node); |
| gs->subcode = EQ_EXPR; |
| } |
| |
| |
| /* Set the conditional COND_STMT to be of the form 'if (1 == 1)'. */ |
| |
| static inline void |
| gimple_cond_make_true (gcond *gs) |
| { |
| gimple_cond_set_lhs (gs, boolean_true_node); |
| gimple_cond_set_rhs (gs, boolean_true_node); |
| gs->subcode = EQ_EXPR; |
| } |
| |
| /* Check if conditional statemente GS is of the form 'if (1 == 1)', |
| 'if (0 == 0)', 'if (1 != 0)' or 'if (0 != 1)' */ |
| |
| static inline bool |
| gimple_cond_true_p (const gcond *gs) |
| { |
| tree lhs = gimple_cond_lhs (gs); |
| tree rhs = gimple_cond_rhs (gs); |
| enum tree_code code = gimple_cond_code (gs); |
| |
| if (lhs != boolean_true_node && lhs != boolean_false_node) |
| return false; |
| |
| if (rhs != boolean_true_node && rhs != boolean_false_node) |
| return false; |
| |
| if (code == NE_EXPR && lhs != rhs) |
| return true; |
| |
| if (code == EQ_EXPR && lhs == rhs) |
| return true; |
| |
| return false; |
| } |
| |
| /* Check if conditional statement GS is of the form 'if (1 != 1)', |
| 'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */ |
| |
| static inline bool |
| gimple_cond_false_p (const gcond *gs) |
| { |
| tree lhs = gimple_cond_lhs (gs); |
| tree rhs = gimple_cond_rhs (gs); |
| enum tree_code code = gimple_cond_code (gs); |
| |
| if (lhs != boolean_true_node && lhs != boolean_false_node) |
| return false; |
| |
| if (rhs != boolean_true_node && rhs != boolean_false_node) |
| return false; |
| |
| if (code == NE_EXPR && lhs == rhs) |
| return true; |
| |
| if (code == EQ_EXPR && lhs != rhs) |
| return true; |
| |
| return false; |
| } |
| |
| /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS. */ |
| |
| static inline void |
| gimple_cond_set_condition (gcond *stmt, enum tree_code code, tree lhs, |
| tree rhs) |
| { |
| gimple_cond_set_code (stmt, code); |
| gimple_cond_set_lhs (stmt, lhs); |
| gimple_cond_set_rhs (stmt, rhs); |
| } |
| |
| /* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS. */ |
| |
| static inline tree |
| gimple_label_label (const glabel *gs) |
| { |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Set LABEL to be the LABEL_DECL node used by GIMPLE_LABEL statement |
| GS. */ |
| |
| static inline void |
| gimple_label_set_label (glabel *gs, tree label) |
| { |
| gimple_set_op (gs, 0, label); |
| } |
| |
| |
| /* Return the destination of the unconditional jump GS. */ |
| |
| static inline tree |
| gimple_goto_dest (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_GOTO); |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Set DEST to be the destination of the unconditonal jump GS. */ |
| |
| static inline void |
| gimple_goto_set_dest (ggoto *gs, tree dest) |
| { |
| gimple_set_op (gs, 0, dest); |
| } |
| |
| |
| /* Return the variables declared in the GIMPLE_BIND statement GS. */ |
| |
| static inline tree |
| gimple_bind_vars (const gbind *bind_stmt) |
| { |
| return bind_stmt->vars; |
| } |
| |
| |
| /* Set VARS to be the set of variables declared in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_vars (gbind *bind_stmt, tree vars) |
| { |
| bind_stmt->vars = vars; |
| } |
| |
| |
| /* Append VARS to the set of variables declared in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_append_vars (gbind *bind_stmt, tree vars) |
| { |
| bind_stmt->vars = chainon (bind_stmt->vars, vars); |
| } |
| |
| |
| static inline gimple_seq * |
| gimple_bind_body_ptr (gbind *bind_stmt) |
| { |
| return &bind_stmt->body; |
| } |
| |
| /* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */ |
| |
| static inline gimple_seq |
| gimple_bind_body (gbind *gs) |
| { |
| return *gimple_bind_body_ptr (gs); |
| } |
| |
| |
| /* Set SEQ to be the GIMPLE sequence contained in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_body (gbind *bind_stmt, gimple_seq seq) |
| { |
| bind_stmt->body = seq; |
| } |
| |
| |
| /* Append a statement to the end of a GIMPLE_BIND's body. */ |
| |
| static inline void |
| gimple_bind_add_stmt (gbind *bind_stmt, gimple stmt) |
| { |
| gimple_seq_add_stmt (&bind_stmt->body, stmt); |
| } |
| |
| |
| /* Append a sequence of statements to the end of a GIMPLE_BIND's body. */ |
| |
| static inline void |
| gimple_bind_add_seq (gbind *bind_stmt, gimple_seq seq) |
| { |
| gimple_seq_add_seq (&bind_stmt->body, seq); |
| } |
| |
| |
| /* Return the TREE_BLOCK node associated with GIMPLE_BIND statement |
| GS. This is analogous to the BIND_EXPR_BLOCK field in trees. */ |
| |
| static inline tree |
| gimple_bind_block (const gbind *bind_stmt) |
| { |
| return bind_stmt->block; |
| } |
| |
| |
| /* Set BLOCK to be the TREE_BLOCK node associated with GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_block (gbind *bind_stmt, tree block) |
| { |
| gcc_gimple_checking_assert (block == NULL_TREE |
| || TREE_CODE (block) == BLOCK); |
| bind_stmt->block = block; |
| } |
| |
| |
| /* Return the number of input operands for GIMPLE_ASM ASM_STMT. */ |
| |
| static inline unsigned |
| gimple_asm_ninputs (const gasm *asm_stmt) |
| { |
| return asm_stmt->ni; |
| } |
| |
| |
| /* Return the number of output operands for GIMPLE_ASM ASM_STMT. */ |
| |
| static inline unsigned |
| gimple_asm_noutputs (const gasm *asm_stmt) |
| { |
| return asm_stmt->no; |
| } |
| |
| |
| /* Return the number of clobber operands for GIMPLE_ASM ASM_STMT. */ |
| |
| static inline unsigned |
| gimple_asm_nclobbers (const gasm *asm_stmt) |
| { |
| return asm_stmt->nc; |
| } |
| |
| /* Return the number of label operands for GIMPLE_ASM ASM_STMT. */ |
| |
| static inline unsigned |
| gimple_asm_nlabels (const gasm *asm_stmt) |
| { |
| return asm_stmt->nl; |
| } |
| |
| /* Return input operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree |
| gimple_asm_input_op (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->ni); |
| return gimple_op (asm_stmt, index + asm_stmt->no); |
| } |
| |
| /* Return a pointer to input operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree * |
| gimple_asm_input_op_ptr (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->ni); |
| return gimple_op_ptr (asm_stmt, index + asm_stmt->no); |
| } |
| |
| |
| /* Set IN_OP to be input operand INDEX in GIMPLE_ASM ASM_STMT. */ |
| |
| static inline void |
| gimple_asm_set_input_op (gasm *asm_stmt, unsigned index, tree in_op) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->ni |
| && TREE_CODE (in_op) == TREE_LIST); |
| gimple_set_op (asm_stmt, index + asm_stmt->no, in_op); |
| } |
| |
| |
| /* Return output operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree |
| gimple_asm_output_op (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->no); |
| return gimple_op (asm_stmt, index); |
| } |
| |
| /* Return a pointer to output operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree * |
| gimple_asm_output_op_ptr (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->no); |
| return gimple_op_ptr (asm_stmt, index); |
| } |
| |
| |
| /* Set OUT_OP to be output operand INDEX in GIMPLE_ASM ASM_STMT. */ |
| |
| static inline void |
| gimple_asm_set_output_op (gasm *asm_stmt, unsigned index, tree out_op) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->no |
| && TREE_CODE (out_op) == TREE_LIST); |
| gimple_set_op (asm_stmt, index, out_op); |
| } |
| |
| |
| /* Return clobber operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree |
| gimple_asm_clobber_op (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->nc); |
| return gimple_op (asm_stmt, index + asm_stmt->ni + asm_stmt->no); |
| } |
| |
| |
| /* Set CLOBBER_OP to be clobber operand INDEX in GIMPLE_ASM ASM_STMT. */ |
| |
| static inline void |
| gimple_asm_set_clobber_op (gasm *asm_stmt, unsigned index, tree clobber_op) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->nc |
| && TREE_CODE (clobber_op) == TREE_LIST); |
| gimple_set_op (asm_stmt, index + asm_stmt->ni + asm_stmt->no, clobber_op); |
| } |
| |
| /* Return label operand INDEX of GIMPLE_ASM ASM_STMT. */ |
| |
| static inline tree |
| gimple_asm_label_op (const gasm *asm_stmt, unsigned index) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->nl); |
| return gimple_op (asm_stmt, index + asm_stmt->ni + asm_stmt->nc); |
| } |
| |
| /* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM ASM_STMT. */ |
| |
| static inline void |
| gimple_asm_set_label_op (gasm *asm_stmt, unsigned index, tree label_op) |
| { |
| gcc_gimple_checking_assert (index < asm_stmt->nl |
| && TREE_CODE (label_op) == TREE_LIST); |
| gimple_set_op (asm_stmt, index + asm_stmt->ni + asm_stmt->nc, label_op); |
| } |
| |
| /* Return the string representing the assembly instruction in |
| GIMPLE_ASM ASM_STMT. */ |
| |
| static inline const char * |
| gimple_asm_string (const gasm *asm_stmt) |
| { |
| return asm_stmt->string; |
| } |
| |
| |
| /* Return true ASM_STMT ASM_STMT is an asm statement marked volatile. */ |
| |
| static inline bool |
| gimple_asm_volatile_p (const gasm *asm_stmt) |
| { |
| return (asm_stmt->subcode & GF_ASM_VOLATILE) != 0; |
| } |
| |
| |
| /* If VOLATLE_P is true, mark asm statement ASM_STMT as volatile. */ |
| |
| static inline void |
| gimple_asm_set_volatile (gasm *asm_stmt, bool volatile_p) |
| { |
| if (volatile_p) |
| asm_stmt->subcode |= GF_ASM_VOLATILE; |
| else |
| asm_stmt->subcode &= ~GF_ASM_VOLATILE; |
| } |
| |
| |
| /* If INPUT_P is true, mark asm ASM_STMT as an ASM_INPUT. */ |
| |
| static inline void |
| gimple_asm_set_input (gasm *asm_stmt, bool input_p) |
| { |
| if (input_p) |
| asm_stmt->subcode |= GF_ASM_INPUT; |
| else |
| asm_stmt->subcode &= ~GF_ASM_INPUT; |
| } |
| |
| |
| /* Return true if asm ASM_STMT is an ASM_INPUT. */ |
| |
| static inline bool |
| gimple_asm_input_p (const gasm *asm_stmt) |
| { |
| return (asm_stmt->subcode & GF_ASM_INPUT) != 0; |
| } |
| |
| |
| /* Return the types handled by GIMPLE_CATCH statement CATCH_STMT. */ |
| |
| static inline tree |
| gimple_catch_types (const gcatch *catch_stmt) |
| { |
| return catch_stmt->types; |
| } |
| |
| |
| /* Return a pointer to the types handled by GIMPLE_CATCH statement CATCH_STMT. */ |
| |
| static inline tree * |
| gimple_catch_types_ptr (gcatch *catch_stmt) |
| { |
| return &catch_stmt->types; |
| } |
| |
| |
| /* Return a pointer to the GIMPLE sequence representing the body of |
| the handler of GIMPLE_CATCH statement CATCH_STMT. */ |
| |
| static inline gimple_seq * |
| gimple_catch_handler_ptr (gcatch *catch_stmt) |
| { |
| return &catch_stmt->handler; |
| } |
| |
| |
| /* Return the GIMPLE sequence representing the body of the handler of |
| GIMPLE_CATCH statement CATCH_STMT. */ |
| |
| static inline gimple_seq |
| gimple_catch_handler (gcatch *catch_stmt) |
| |