| /* Gimple IR definitions. |
| |
| Copyright 2007, 2008, 2009, 2010 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 |
| |
| #include "pointer-set.h" |
| #include "vec.h" |
| #include "vecprim.h" |
| #include "vecir.h" |
| #include "ggc.h" |
| #include "basic-block.h" |
| #include "tree-ssa-operands.h" |
| #include "tree-ssa-alias.h" |
| |
| struct gimple_seq_node_d; |
| typedef struct gimple_seq_node_d *gimple_seq_node; |
| typedef const struct gimple_seq_node_d *const_gimple_seq_node; |
| |
| /* For each block, the PHI nodes that need to be rewritten are stored into |
| these vectors. */ |
| typedef VEC(gimple, heap) *gimple_vec; |
| DEF_VEC_P (gimple_vec); |
| DEF_VEC_ALLOC_P (gimple_vec, heap); |
| |
| 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 sub-codes. |
| |
| 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_CANNOT_INLINE = 1 << 0, |
| GF_CALL_FROM_THUNK = 1 << 1, |
| GF_CALL_RETURN_SLOT_OPT = 1 << 2, |
| GF_CALL_TAILCALL = 1 << 3, |
| GF_CALL_VA_ARG_PACK = 1 << 4, |
| GF_CALL_NOTHROW = 1 << 5, |
| GF_OMP_PARALLEL_COMBINED = 1 << 0, |
| |
| /* 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_PREDICT_TAKEN = 1 << 15 |
| }; |
| |
| /* Currently, there's only one type 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 |
| }; |
| |
| /* 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 |
| }; |
| |
| /* A node in a gimple_seq_d. */ |
| struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) gimple_seq_node_d { |
| gimple stmt; |
| struct gimple_seq_node_d *prev; |
| struct gimple_seq_node_d *next; |
| }; |
| |
| /* A double-linked sequence of gimple statements. */ |
| struct GTY ((chain_next ("%h.next_free"))) gimple_seq_d { |
| /* First and last statements in the sequence. */ |
| gimple_seq_node first; |
| gimple_seq_node last; |
| |
| /* Sequences are created/destroyed frequently. To minimize |
| allocation activity, deallocated sequences are kept in a pool of |
| available sequences. This is the pointer to the next free |
| sequence in the pool. */ |
| gimple_seq next_free; |
| }; |
| |
| |
| /* Return the first node in GIMPLE sequence S. */ |
| |
| static inline gimple_seq_node |
| gimple_seq_first (const_gimple_seq s) |
| { |
| return s ? s->first : NULL; |
| } |
| |
| |
| /* Return the first statement in GIMPLE sequence S. */ |
| |
| static inline gimple |
| gimple_seq_first_stmt (const_gimple_seq s) |
| { |
| gimple_seq_node n = gimple_seq_first (s); |
| return (n) ? n->stmt : NULL; |
| } |
| |
| |
| /* Return the last node in GIMPLE sequence S. */ |
| |
| static inline gimple_seq_node |
| gimple_seq_last (const_gimple_seq s) |
| { |
| return s ? s->last : NULL; |
| } |
| |
| |
| /* Return the last statement in GIMPLE sequence S. */ |
| |
| static inline gimple |
| gimple_seq_last_stmt (const_gimple_seq s) |
| { |
| gimple_seq_node n = gimple_seq_last (s); |
| return (n) ? n->stmt : NULL; |
| } |
| |
| |
| /* Set the last node in GIMPLE sequence S to LAST. */ |
| |
| static inline void |
| gimple_seq_set_last (gimple_seq s, gimple_seq_node last) |
| { |
| s->last = last; |
| } |
| |
| |
| /* Set the first node in GIMPLE sequence S to FIRST. */ |
| |
| static inline void |
| gimple_seq_set_first (gimple_seq s, gimple_seq_node first) |
| { |
| s->first = first; |
| } |
| |
| |
| /* Return true if GIMPLE sequence S is empty. */ |
| |
| static inline bool |
| gimple_seq_empty_p (const_gimple_seq s) |
| { |
| return s == NULL || s->first == NULL; |
| } |
| |
| |
| void gimple_seq_add_stmt (gimple_seq *, gimple); |
| |
| /* Link gimple statement GS to the end of the sequence *SEQ_P. If |
| *SEQ_P is NULL, a new sequence is allocated. This function is |
| similar to gimple_seq_add_stmt, but does not scan the operands. |
| During gimplification, we need to manipulate statement sequences |
| before the def/use vectors have been constructed. */ |
| void gimplify_seq_add_stmt (gimple_seq *, gimple); |
| |
| /* 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) ? 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; |
| } |
| |
| /* Iterator object for GIMPLE statement sequences. */ |
| |
| typedef struct |
| { |
| /* Sequence node holding the current statement. */ |
| gimple_seq_node ptr; |
| |
| /* Sequence and basic block holding the statement. These fields |
| are necessary to handle edge cases such as when statement is |
| added to an empty basic block or when the last statement of a |
| block/sequence is removed. */ |
| gimple_seq seq; |
| basic_block bb; |
| } gimple_stmt_iterator; |
| |
| |
| /* Data structure definitions for GIMPLE tuples. NOTE: word markers |
| are for 64 bit hosts. */ |
| |
| struct GTY(()) 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. */ |
| struct basic_block_def *bb; |
| |
| /* [ WORD 4 ] |
| Lexical block holding this statement. */ |
| tree block; |
| }; |
| |
| |
| /* Base structure for tuples with operands. */ |
| |
| struct GTY(()) gimple_statement_with_ops_base |
| { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5-6 ] |
| 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 def_optype_d GTY((skip (""))) *def_ops; |
| struct use_optype_d GTY((skip (""))) *use_ops; |
| }; |
| |
| |
| /* Statements that take register operands. */ |
| |
| struct GTY(()) gimple_statement_with_ops |
| { |
| /* [ WORD 1-6 ] */ |
| struct gimple_statement_with_ops_base opbase; |
| |
| /* [ WORD 7 ] |
| 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.opbase.gsbase.num_ops"))) op[1]; |
| }; |
| |
| |
| /* Base for statements that take both memory and register operands. */ |
| |
| struct GTY(()) gimple_statement_with_memory_ops_base |
| { |
| /* [ WORD 1-6 ] */ |
| struct gimple_statement_with_ops_base opbase; |
| |
| /* [ WORD 7-8 ] |
| 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(()) gimple_statement_with_memory_ops |
| { |
| /* [ WORD 1-8 ] */ |
| struct gimple_statement_with_memory_ops_base membase; |
| |
| /* [ WORD 9 ] |
| 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.membase.opbase.gsbase.num_ops"))) op[1]; |
| }; |
| |
| |
| /* Call statements that take both memory and register operands. */ |
| |
| struct GTY(()) gimple_statement_call |
| { |
| /* [ WORD 1-8 ] */ |
| struct gimple_statement_with_memory_ops_base membase; |
| |
| /* [ WORD 9-12 ] */ |
| struct pt_solution call_used; |
| struct pt_solution call_clobbered; |
| |
| /* [ WORD 13 ] |
| 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.membase.opbase.gsbase.num_ops"))) op[1]; |
| }; |
| |
| |
| /* OpenMP statements (#pragma omp). */ |
| |
| struct GTY(()) gimple_statement_omp { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] */ |
| gimple_seq body; |
| }; |
| |
| |
| /* GIMPLE_BIND */ |
| |
| struct GTY(()) gimple_statement_bind { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] |
| Variables declared in this scope. */ |
| tree vars; |
| |
| /* [ WORD 6 ] |
| 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 7 ] */ |
| gimple_seq body; |
| }; |
| |
| |
| /* GIMPLE_CATCH */ |
| |
| struct GTY(()) gimple_statement_catch { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] */ |
| tree types; |
| |
| /* [ WORD 6 ] */ |
| gimple_seq handler; |
| }; |
| |
| |
| /* GIMPLE_EH_FILTER */ |
| |
| struct GTY(()) gimple_statement_eh_filter { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] |
| Filter types. */ |
| tree types; |
| |
| /* [ WORD 6 ] |
| Failure actions. */ |
| gimple_seq failure; |
| }; |
| |
| |
| /* GIMPLE_EH_MUST_NOT_THROW */ |
| |
| struct GTY(()) gimple_statement_eh_mnt { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] Abort function decl. */ |
| tree fndecl; |
| }; |
| |
| /* GIMPLE_PHI */ |
| |
| struct GTY(()) gimple_statement_phi { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] */ |
| unsigned capacity; |
| unsigned nargs; |
| |
| /* [ WORD 6 ] */ |
| tree result; |
| |
| /* [ WORD 7 ] */ |
| struct phi_arg_d GTY ((length ("%h.nargs"))) args[1]; |
| }; |
| |
| |
| /* GIMPLE_RESX, GIMPLE_EH_DISPATCH */ |
| |
| struct GTY(()) gimple_statement_eh_ctrl |
| { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] |
| Exception region number. */ |
| int region; |
| }; |
| |
| |
| /* GIMPLE_TRY */ |
| |
| struct GTY(()) gimple_statement_try { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] |
| Expression to evaluate. */ |
| gimple_seq eval; |
| |
| /* [ WORD 6 ] |
| 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(()) gimple_statement_wce { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* 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 5 ] |
| Cleanup expression. */ |
| gimple_seq cleanup; |
| }; |
| |
| |
| /* GIMPLE_ASM */ |
| |
| struct GTY(()) gimple_statement_asm |
| { |
| /* [ WORD 1-8 ] */ |
| struct gimple_statement_with_memory_ops_base membase; |
| |
| /* [ WORD 9 ] |
| __asm__ statement. */ |
| const char *string; |
| |
| /* [ WORD 10 ] |
| Number of inputs, outputs, clobbers, labels. */ |
| unsigned char ni; |
| unsigned char no; |
| unsigned char nc; |
| unsigned char nl; |
| |
| /* [ WORD 11 ] |
| 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.membase.opbase.gsbase.num_ops"))) op[1]; |
| }; |
| |
| /* GIMPLE_OMP_CRITICAL */ |
| |
| struct GTY(()) gimple_statement_omp_critical { |
| /* [ WORD 1-5 ] */ |
| struct gimple_statement_omp omp; |
| |
| /* [ WORD 6 ] |
| 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(()) gimple_statement_omp_for { |
| /* [ WORD 1-5 ] */ |
| struct gimple_statement_omp omp; |
| |
| /* [ WORD 6 ] */ |
| tree clauses; |
| |
| /* [ WORD 7 ] |
| Number of elements in iter array. */ |
| size_t collapse; |
| |
| /* [ WORD 8 ] */ |
| struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter; |
| |
| /* [ WORD 9 ] |
| Pre-body evaluated before the loop body begins. */ |
| gimple_seq pre_body; |
| }; |
| |
| |
| /* GIMPLE_OMP_PARALLEL */ |
| |
| struct GTY(()) gimple_statement_omp_parallel { |
| /* [ WORD 1-5 ] */ |
| struct gimple_statement_omp omp; |
| |
| /* [ WORD 6 ] |
| Clauses. */ |
| tree clauses; |
| |
| /* [ WORD 7 ] |
| Child function holding the body of the parallel region. */ |
| tree child_fn; |
| |
| /* [ WORD 8 ] |
| Shared data argument. */ |
| tree data_arg; |
| }; |
| |
| |
| /* GIMPLE_OMP_TASK */ |
| |
| struct GTY(()) gimple_statement_omp_task { |
| /* [ WORD 1-8 ] */ |
| struct gimple_statement_omp_parallel par; |
| |
| /* [ WORD 9 ] |
| Child function holding firstprivate initialization if needed. */ |
| tree copy_fn; |
| |
| /* [ WORD 10-11 ] |
| 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(()) gimple_statement_omp_sections { |
| /* [ WORD 1-5 ] */ |
| struct gimple_statement_omp omp; |
| |
| /* [ WORD 6 ] */ |
| tree clauses; |
| |
| /* [ WORD 7 ] |
| 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(()) gimple_statement_omp_continue { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] */ |
| tree control_def; |
| |
| /* [ WORD 6 ] */ |
| tree control_use; |
| }; |
| |
| /* GIMPLE_OMP_SINGLE */ |
| |
| struct GTY(()) gimple_statement_omp_single { |
| /* [ WORD 1-5 ] */ |
| struct gimple_statement_omp omp; |
| |
| /* [ WORD 6 ] */ |
| tree clauses; |
| }; |
| |
| |
| /* 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(()) gimple_statement_omp_atomic_load { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5-6 ] */ |
| tree rhs, lhs; |
| }; |
| |
| /* GIMPLE_OMP_ATOMIC_STORE. |
| See note on GIMPLE_OMP_ATOMIC_LOAD. */ |
| |
| struct GTY(()) gimple_statement_omp_atomic_store { |
| /* [ WORD 1-4 ] */ |
| struct gimple_statement_base gsbase; |
| |
| /* [ WORD 5 ] */ |
| tree val; |
| }; |
| |
| #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM, |
| enum gimple_statement_structure_enum { |
| #include "gsstruct.def" |
| LAST_GSS_ENUM |
| }; |
| #undef DEFGSSTRUCT |
| |
| |
| /* Define the overall contents of a gimple tuple. It may be any of the |
| structures declared above for various types of tuples. */ |
| |
| union GTY ((desc ("gimple_statement_structure (&%h)"), variable_size)) gimple_statement_d { |
| struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase; |
| struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops; |
| struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase; |
| struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) gsmem; |
| struct gimple_statement_call GTY ((tag ("GSS_CALL"))) gimple_call; |
| struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp; |
| struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind; |
| struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch; |
| struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter; |
| struct gimple_statement_eh_mnt GTY ((tag ("GSS_EH_MNT"))) gimple_eh_mnt; |
| struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi; |
| struct gimple_statement_eh_ctrl GTY ((tag ("GSS_EH_CTRL"))) gimple_eh_ctrl; |
| struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try; |
| struct gimple_statement_wce GTY ((tag ("GSS_WCE"))) gimple_wce; |
| struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm; |
| struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL"))) gimple_omp_critical; |
| struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gimple_omp_for; |
| struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL"))) gimple_omp_parallel; |
| struct gimple_statement_omp_task GTY ((tag ("GSS_OMP_TASK"))) gimple_omp_task; |
| struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS"))) gimple_omp_sections; |
| struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gimple_omp_single; |
| struct gimple_statement_omp_continue GTY ((tag ("GSS_OMP_CONTINUE"))) gimple_omp_continue; |
| struct gimple_statement_omp_atomic_load GTY ((tag ("GSS_OMP_ATOMIC_LOAD"))) gimple_omp_atomic_load; |
| struct gimple_statement_omp_atomic_store GTY ((tag ("GSS_OMP_ATOMIC_STORE"))) gimple_omp_atomic_store; |
| }; |
| |
| /* In gimple.c. */ |
| |
| /* 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; |
| |
| gimple gimple_build_return (tree); |
| |
| gimple gimple_build_assign_stat (tree, tree MEM_STAT_DECL); |
| #define gimple_build_assign(l,r) gimple_build_assign_stat (l, r MEM_STAT_INFO) |
| |
| void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, tree *); |
| |
| gimple gimple_build_assign_with_ops_stat (enum tree_code, tree, tree, |
| tree, tree MEM_STAT_DECL); |
| #define gimple_build_assign_with_ops(c,o1,o2,o3) \ |
| gimple_build_assign_with_ops_stat (c, o1, o2, o3, NULL_TREE MEM_STAT_INFO) |
| #define gimple_build_assign_with_ops3(c,o1,o2,o3,o4) \ |
| gimple_build_assign_with_ops_stat (c, o1, o2, o3, o4 MEM_STAT_INFO) |
| |
| gimple 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) |
| |
| gimple gimple_build_call_vec (tree, VEC(tree, heap) *); |
| gimple gimple_build_call (tree, unsigned, ...); |
| gimple gimple_build_call_from_tree (tree); |
| gimple gimplify_assign (tree, tree, gimple_seq *); |
| gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree); |
| gimple gimple_build_label (tree label); |
| gimple gimple_build_goto (tree dest); |
| gimple gimple_build_nop (void); |
| gimple gimple_build_bind (tree, gimple_seq, tree); |
| gimple gimple_build_asm_vec (const char *, VEC(tree,gc) *, VEC(tree,gc) *, |
| VEC(tree,gc) *, VEC(tree,gc) *); |
| gimple gimple_build_catch (tree, gimple_seq); |
| gimple gimple_build_eh_filter (tree, gimple_seq); |
| gimple gimple_build_eh_must_not_throw (tree); |
| gimple gimple_build_try (gimple_seq, gimple_seq, enum gimple_try_flags); |
| gimple gimple_build_wce (gimple_seq); |
| gimple gimple_build_resx (int); |
| gimple gimple_build_eh_dispatch (int); |
| gimple gimple_build_switch_nlabels (unsigned, tree, tree); |
| gimple gimple_build_switch (unsigned, tree, tree, ...); |
| gimple gimple_build_switch_vec (tree, tree, VEC(tree,heap) *); |
| gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree); |
| gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree); |
| gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq); |
| gimple gimple_build_omp_critical (gimple_seq, tree); |
| gimple gimple_build_omp_section (gimple_seq); |
| gimple gimple_build_omp_continue (tree, tree); |
| gimple gimple_build_omp_master (gimple_seq); |
| gimple gimple_build_omp_return (bool); |
| gimple gimple_build_omp_ordered (gimple_seq); |
| gimple gimple_build_omp_sections (gimple_seq, tree); |
| gimple gimple_build_omp_sections_switch (void); |
| gimple gimple_build_omp_single (gimple_seq, tree); |
| gimple gimple_build_cdt (tree, tree); |
| gimple gimple_build_omp_atomic_load (tree, tree); |
| gimple gimple_build_omp_atomic_store (tree); |
| gimple gimple_build_predict (enum br_predictor, enum prediction); |
| enum gimple_statement_structure_enum gss_for_assign (enum tree_code); |
| void sort_case_labels (VEC(tree,heap) *); |
| void gimple_set_body (tree, gimple_seq); |
| gimple_seq gimple_body (tree); |
| bool gimple_has_body_p (tree); |
| gimple_seq gimple_seq_alloc (void); |
| void gimple_seq_free (gimple_seq); |
| void gimple_seq_add_seq (gimple_seq *, gimple_seq); |
| gimple_seq gimple_seq_copy (gimple_seq); |
| int gimple_call_flags (const_gimple); |
| int gimple_call_return_flags (const_gimple); |
| int gimple_call_arg_flags (const_gimple, unsigned); |
| void gimple_call_reset_alias_info (gimple); |
| 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, struct basic_block_def *); |
| void gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *, tree); |
| void gimple_assign_set_rhs_with_ops_1 (gimple_stmt_iterator *, enum tree_code, |
| tree, tree, tree); |
| tree gimple_get_lhs (const_gimple); |
| void gimple_set_lhs (gimple, tree); |
| void gimple_replace_lhs (gimple, tree); |
| gimple gimple_copy (gimple); |
| void gimple_set_modified (gimple, bool); |
| void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *); |
| gimple gimple_build_cond_from_tree (tree, tree, tree); |
| void gimple_cond_set_condition_from_tree (gimple, tree); |
| bool gimple_has_side_effects (const_gimple); |
| bool gimple_rhs_has_side_effects (const_gimple); |
| bool gimple_could_trap_p (gimple); |
| bool gimple_could_trap_p_1 (gimple, bool, bool); |
| bool gimple_assign_rhs_could_trap_p (gimple); |
| void gimple_regimplify_operands (gimple, gimple_stmt_iterator *); |
| bool empty_body_p (gimple_seq); |
| unsigned get_gimple_rhs_num_ops (enum tree_code); |
| #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO) |
| gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL); |
| const char *gimple_decl_printable_name (tree, int); |
| bool gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace); |
| tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree, tree *, bool); |
| void gimple_adjust_this_by_delta (gimple_stmt_iterator *, tree); |
| /* Returns true iff T is a valid GIMPLE statement. */ |
| extern bool is_gimple_stmt (tree); |
| |
| /* Returns true iff TYPE is a valid type for a scalar register variable. */ |
| extern bool is_gimple_reg_type (tree); |
| /* Returns true iff T is a scalar register variable. */ |
| extern bool is_gimple_reg (tree); |
| /* Returns true iff T is any sort of variable. */ |
| extern bool is_gimple_variable (tree); |
| /* Returns true iff T is any sort of symbol. */ |
| extern bool is_gimple_id (tree); |
| /* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */ |
| extern bool is_gimple_min_lval (tree); |
| /* Returns true iff T is something whose address can be taken. */ |
| extern bool is_gimple_addressable (tree); |
| /* Returns true iff T is any valid GIMPLE lvalue. */ |
| extern bool is_gimple_lvalue (tree); |
| |
| /* Returns true iff T is a GIMPLE address. */ |
| bool is_gimple_address (const_tree); |
| /* Returns true iff T is a GIMPLE invariant address. */ |
| bool is_gimple_invariant_address (const_tree); |
| /* Returns true iff T is a GIMPLE invariant address at interprocedural |
| level. */ |
| bool is_gimple_ip_invariant_address (const_tree); |
| /* Returns true iff T is a valid GIMPLE constant. */ |
| bool is_gimple_constant (const_tree); |
| /* Returns true iff T is a GIMPLE restricted function invariant. */ |
| extern bool is_gimple_min_invariant (const_tree); |
| /* Returns true iff T is a GIMPLE restricted interprecodural invariant. */ |
| extern bool is_gimple_ip_invariant (const_tree); |
| /* Returns true iff T is a GIMPLE rvalue. */ |
| extern bool is_gimple_val (tree); |
| /* Returns true iff T is a GIMPLE asm statement input. */ |
| extern bool is_gimple_asm_val (tree); |
| /* Returns true iff T is a valid address operand of a MEM_REF. */ |
| bool is_gimple_mem_ref_addr (tree); |
| /* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a |
| GIMPLE temporary, a renamed user variable, or something else, |
| respectively. */ |
| extern bool is_gimple_reg_rhs (tree); |
| extern bool is_gimple_mem_rhs (tree); |
| |
| /* Returns true iff T is a valid if-statement condition. */ |
| extern bool is_gimple_condexpr (tree); |
| |
| /* Returns true iff T is a variable that does not need to live in memory. */ |
| extern bool is_gimple_non_addressable (tree t); |
| |
| /* Returns true iff T is a valid call address expression. */ |
| extern bool is_gimple_call_addr (tree); |
| /* If T makes a function call, returns the CALL_EXPR operand. */ |
| extern tree get_call_expr_in (tree t); |
| |
| extern void recalculate_side_effects (tree); |
| extern bool gimple_compare_field_offset (tree, tree); |
| extern tree gimple_register_type (tree); |
| extern tree gimple_register_canonical_type (tree); |
| enum gtc_mode { GTC_MERGE = 0, GTC_DIAG = 1 }; |
| extern bool gimple_types_compatible_p (tree, tree, enum gtc_mode); |
| extern void print_gimple_types_stats (void); |
| extern void free_gimple_type_tables (void); |
| extern tree gimple_unsigned_type (tree); |
| extern tree gimple_signed_type (tree); |
| extern alias_set_type gimple_get_alias_set (tree); |
| extern void count_uses_and_derefs (tree, gimple, unsigned *, unsigned *, |
| unsigned *); |
| extern bool walk_stmt_load_store_addr_ops (gimple, void *, |
| bool (*)(gimple, tree, void *), |
| bool (*)(gimple, tree, void *), |
| bool (*)(gimple, tree, void *)); |
| extern bool walk_stmt_load_store_ops (gimple, void *, |
| bool (*)(gimple, tree, void *), |
| bool (*)(gimple, tree, void *)); |
| extern bool gimple_ior_addresses_taken (bitmap, gimple); |
| extern bool gimple_call_builtin_p (gimple, enum built_in_function); |
| |
| /* In gimplify.c */ |
| extern tree create_tmp_var_raw (tree, const char *); |
| extern tree create_tmp_var_name (const char *); |
| extern tree create_tmp_var (tree, const char *); |
| extern tree create_tmp_reg (tree, const char *); |
| extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); |
| extern tree get_formal_tmp_var (tree, gimple_seq *); |
| extern void declare_vars (tree, gimple, bool); |
| extern void annotate_all_with_location (gimple_seq, location_t); |
| |
| /* Validation of GIMPLE expressions. Note that these predicates only check |
| the basic form of the expression, they don't recurse to make sure that |
| underlying nodes are also of the right form. */ |
| typedef bool (*gimple_predicate)(tree); |
| |
| |
| /* FIXME we should deduce this from the predicate. */ |
| enum fallback { |
| fb_none = 0, /* Do not generate a temporary. */ |
| |
| fb_rvalue = 1, /* Generate an rvalue to hold the result of a |
| gimplified expression. */ |
| |
| fb_lvalue = 2, /* Generate an lvalue to hold the result of a |
| gimplified expression. */ |
| |
| fb_mayfail = 4, /* Gimplification may fail. Error issued |
| afterwards. */ |
| fb_either= fb_rvalue | fb_lvalue |
| }; |
| |
| typedef int fallback_t; |
| |
| enum gimplify_status { |
| GS_ERROR = -2, /* Something Bad Seen. */ |
| GS_UNHANDLED = -1, /* A langhook result for "I dunno". */ |
| GS_OK = 0, /* We did something, maybe more to do. */ |
| GS_ALL_DONE = 1 /* The expression is fully gimplified. */ |
| }; |
| |
| struct gimplify_ctx |
| { |
| struct gimplify_ctx *prev_context; |
| |
| VEC(gimple,heap) *bind_expr_stack; |
| tree temps; |
| gimple_seq conditional_cleanups; |
| tree exit_label; |
| tree return_temp; |
| |
| VEC(tree,heap) *case_labels; |
| /* The formal temporary table. Should this be persistent? */ |
| htab_t temp_htab; |
| |
| int conditions; |
| bool save_stack; |
| bool into_ssa; |
| bool allow_rhs_cond_expr; |
| }; |
| |
| extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *, |
| bool (*) (tree), fallback_t); |
| extern void gimplify_type_sizes (tree, gimple_seq *); |
| extern void gimplify_one_sizepos (tree *, gimple_seq *); |
| extern bool gimplify_stmt (tree *, gimple_seq *); |
| extern gimple gimplify_body (tree *, tree, bool); |
| extern void push_gimplify_context (struct gimplify_ctx *); |
| extern void pop_gimplify_context (gimple); |
| extern void gimplify_and_add (tree, gimple_seq *); |
| |
| /* Miscellaneous helpers. */ |
| extern void gimple_add_tmp_var (tree); |
| extern gimple gimple_current_bind_expr (void); |
| extern VEC(gimple, heap) *gimple_bind_expr_stack (void); |
| extern tree voidify_wrapper_expr (tree, tree); |
| extern tree build_and_jump (tree *); |
| extern tree force_labels_r (tree *, int *, void *); |
| extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *, |
| gimple_seq *); |
| struct gimplify_omp_ctx; |
| extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree); |
| extern tree gimple_boolify (tree); |
| extern gimple_predicate rhs_predicate_for (tree); |
| extern tree canonicalize_cond_expr_cond (tree); |
| |
| /* In omp-low.c. */ |
| extern tree omp_reduction_init (tree, tree); |
| |
| /* In tree-nested.c. */ |
| extern void lower_nested_functions (tree); |
| extern void insert_field_into_struct (tree, tree); |
| |
| /* In gimplify.c. */ |
| extern void gimplify_function_tree (tree); |
| |
| /* In cfgexpand.c. */ |
| extern tree gimple_assign_rhs_to_tree (gimple); |
| |
| /* In builtins.c */ |
| extern bool validate_gimple_arglist (const_gimple, ...); |
| |
| /* In tree-ssa.c */ |
| extern bool tree_ssa_useless_type_conversion (tree); |
| extern tree tree_ssa_strip_useless_type_conversions (tree); |
| extern bool useless_type_conversion_p (tree, tree); |
| extern bool types_compatible_p (tree, tree); |
| |
| /* Return the code for GIMPLE statement G. */ |
| |
| static inline enum gimple_code |
| gimple_code (const_gimple g) |
| { |
| return g->gsbase.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_TRY: |
| case GIMPLE_OMP_FOR: |
| case GIMPLE_OMP_MASTER: |
| 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_CRITICAL: |
| case GIMPLE_WITH_CLEANUP_EXPR: |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| |
| /* Return the basic block holding statement G. */ |
| |
| static inline struct basic_block_def * |
| gimple_bb (const_gimple g) |
| { |
| return g->gsbase.bb; |
| } |
| |
| |
| /* Return the lexical scope block holding statement G. */ |
| |
| static inline tree |
| gimple_block (const_gimple g) |
| { |
| return g->gsbase.block; |
| } |
| |
| |
| /* Set BLOCK to be the lexical scope block holding statement G. */ |
| |
| static inline void |
| gimple_set_block (gimple g, tree block) |
| { |
| g->gsbase.block = block; |
| } |
| |
| |
| /* Return location information for statement G. */ |
| |
| static inline location_t |
| gimple_location (const_gimple g) |
| { |
| return g->gsbase.location; |
| } |
| |
| /* Return pointer to location information for statement G. */ |
| |
| static inline const location_t * |
| gimple_location_ptr (const_gimple g) |
| { |
| return &g->gsbase.location; |
| } |
| |
| |
| /* Set location information for statement G. */ |
| |
| static inline void |
| gimple_set_location (gimple g, location_t location) |
| { |
| g->gsbase.location = location; |
| } |
| |
| |
| /* Return true if G contains location information. */ |
| |
| static inline bool |
| gimple_has_location (const_gimple g) |
| { |
| return 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->gsbase.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->gsbase.no_warning = (unsigned) no_warning; |
| } |
| |
| /* Set the visited status on statement STMT to VISITED_P. */ |
| |
| static inline void |
| gimple_set_visited (gimple stmt, bool visited_p) |
| { |
| stmt->gsbase.visited = (unsigned) visited_p; |
| } |
| |
| |
| /* Return the visited status for statement STMT. */ |
| |
| static inline bool |
| gimple_visited_p (gimple stmt) |
| { |
| return stmt->gsbase.visited; |
| } |
| |
| |
| /* Set pass local flag PLF on statement STMT to VAL_P. */ |
| |
| static inline void |
| gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) |
| { |
| if (val_p) |
| stmt->gsbase.plf |= (unsigned int) plf; |
| else |
| stmt->gsbase.plf &= ~((unsigned int) plf); |
| } |
| |
| |
| /* Return the value of pass local flag PLF on statement STMT. */ |
| |
| static inline unsigned int |
| gimple_plf (gimple stmt, enum plf_mask plf) |
| { |
| return stmt->gsbase.plf & ((unsigned int) plf); |
| } |
| |
| |
| /* Set the UID of statement. */ |
| |
| static inline void |
| gimple_set_uid (gimple g, unsigned uid) |
| { |
| g->gsbase.uid = uid; |
| } |
| |
| |
| /* Return the UID of statement. */ |
| |
| static inline unsigned |
| gimple_uid (const_gimple g) |
| { |
| return g->gsbase.uid; |
| } |
| |
| |
| /* 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; |
| } |
| |
| |
| /* 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; |
| } |
| |
| |
| /* Return the set of DEF operands for statement G. */ |
| |
| static inline struct def_optype_d * |
| gimple_def_ops (const_gimple g) |
| { |
| if (!gimple_has_ops (g)) |
| return NULL; |
| return g->gsops.opbase.def_ops; |
| } |
| |
| |
| /* Set DEF to be the set of DEF operands for statement G. */ |
| |
| static inline void |
| gimple_set_def_ops (gimple g, struct def_optype_d *def) |
| { |
| gcc_gimple_checking_assert (gimple_has_ops (g)); |
| g->gsops.opbase.def_ops = def; |
| } |
| |
| |
| /* Return the set of USE operands for statement G. */ |
| |
| static inline struct use_optype_d * |
| gimple_use_ops (const_gimple g) |
| { |
| if (!gimple_has_ops (g)) |
| return NULL; |
| return g->gsops.opbase.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) |
| { |
| gcc_gimple_checking_assert (gimple_has_ops (g)); |
| g->gsops.opbase.use_ops = use; |
| } |
| |
| |
| /* Return the set of VUSE operand for statement G. */ |
| |
| static inline use_operand_p |
| gimple_vuse_op (const_gimple g) |
| { |
| struct use_optype_d *ops; |
| if (!gimple_has_mem_ops (g)) |
| return NULL_USE_OPERAND_P; |
| ops = g->gsops.opbase.use_ops; |
| if (ops |
| && USE_OP_PTR (ops)->use == &g->gsmembase.vuse) |
| return USE_OP_PTR (ops); |
| return NULL_USE_OPERAND_P; |
| } |
| |
| /* Return the set of VDEF operand for statement G. */ |
| |
| static inline def_operand_p |
| gimple_vdef_op (const_gimple g) |
| { |
| struct def_optype_d *ops; |
| if (!gimple_has_mem_ops (g)) |
| return NULL_DEF_OPERAND_P; |
| ops = g->gsops.opbase.def_ops; |
| if (ops |
| && DEF_OP_PTR (ops) == &g->gsmembase.vdef) |
| return DEF_OP_PTR (ops); |
| return NULL_DEF_OPERAND_P; |
| } |
| |
| |
| /* Return the single VUSE operand of the statement G. */ |
| |
| static inline tree |
| gimple_vuse (const_gimple g) |
| { |
| if (!gimple_has_mem_ops (g)) |
| return NULL_TREE; |
| return g->gsmembase.vuse; |
| } |
| |
| /* Return the single VDEF operand of the statement G. */ |
| |
| static inline tree |
| gimple_vdef (const_gimple g) |
| { |
| if (!gimple_has_mem_ops (g)) |
| return NULL_TREE; |
| return g->gsmembase.vdef; |
| } |
| |
| /* Return the single VUSE operand of the statement G. */ |
| |
| static inline tree * |
| gimple_vuse_ptr (gimple g) |
| { |
| if (!gimple_has_mem_ops (g)) |
| return NULL; |
| return &g->gsmembase.vuse; |
| } |
| |
| /* Return the single VDEF operand of the statement G. */ |
| |
| static inline tree * |
| gimple_vdef_ptr (gimple g) |
| { |
| if (!gimple_has_mem_ops (g)) |
| return NULL; |
| return &g->gsmembase.vdef; |
| } |
| |
| /* Set the single VUSE operand of the statement G. */ |
| |
| static inline void |
| gimple_set_vuse (gimple g, tree vuse) |
| { |
| gcc_gimple_checking_assert (gimple_has_mem_ops (g)); |
| g->gsmembase.vuse = vuse; |
| } |
| |
| /* Set the single VDEF operand of the statement G. */ |
| |
| static inline void |
| gimple_set_vdef (gimple g, tree vdef) |
| { |
| gcc_gimple_checking_assert (gimple_has_mem_ops (g)); |
| g->gsmembase.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->gsbase.modified : false; |
| } |
| |
| |
| /* 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->gsbase.subcode; |
| else |
| { |
| gcc_gimple_checking_assert (code == GIMPLE_CALL); |
| return CALL_EXPR; |
| } |
| } |
| |
| |
| /* Mark statement S as modified, and update it. */ |
| |
| static inline void |
| update_stmt (gimple s) |
| { |
| if (gimple_has_ops (s)) |
| { |
| gimple_set_modified (s, true); |
| update_stmt_operands (s); |
| } |
| } |
| |
| /* Update statement S if it has been optimized. */ |
| |
| static inline void |
| update_stmt_if_modified (gimple s) |
| { |
| if (gimple_modified_p (s)) |
| update_stmt_operands (s); |
| } |
| |
| /* 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->gsbase.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->gsbase.has_volatile_ops = (unsigned) volatilep; |
| } |
| |
| |
| /* 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_SINGLE); |
| return s->gsbase.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->gsbase.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->gsbase.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; |
| } |
| |
| |
| /* 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->gsbase.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->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED; |
| else |
| g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED; |
| } |
| |
| |
| /* Return the number of operands for statement GS. */ |
| |
| static inline unsigned |
| gimple_num_ops (const_gimple gs) |
| { |
| return gs->gsbase.num_ops; |
| } |
| |
| |
| /* Set the number of operands for statement GS. */ |
| |
| static inline void |
| gimple_set_num_ops (gimple gs, unsigned num_ops) |
| { |
| gs->gsbase.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 gimple_assign_set_rhs_with_ops_1, for callers which expect |
| to see only a maximum of 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_1 (gsi, code, op1, op2, NULL); |
| } |
| |
| /* A wrapper around extract_ops_from_tree_1, for callers which expect |
| to see only a maximum of two operands. */ |
| |
| static inline void |
| extract_ops_from_tree (tree expr, enum tree_code *code, tree *op0, |
| tree *op1) |
| { |
| tree op2; |
| extract_ops_from_tree_1 (expr, code, op0, op1, &op2); |
| gcc_assert (op2 == NULL_TREE); |
| } |
| |
| /* Returns true if GS is a nontemporal move. */ |
| |
| static inline bool |
| gimple_assign_nontemporal_move_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASSIGN); |
| return gs->gsbase.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->gsbase.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->gsbase.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->gsbase.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 (gimple gs) |
| { |
| return (is_gimple_assign (gs) |
| && gimple_assign_rhs_class (gs) == GIMPLE_SINGLE_RHS); |
| } |
| |
| |
| /* Return true if S is a type-cast assignment. */ |
| |
| static inline bool |
| gimple_assign_cast_p (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 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 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 (gimple gs, tree fn) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| 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); |
| gimple_set_op (gs, 1, build_fold_addr_expr_loc (gimple_location (gs), decl)); |
| } |
| |
| |
| /* 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) |
| { |
| tree addr = gimple_call_fn (gs); |
| if (TREE_CODE (addr) == ADDR_EXPR) |
| { |
| tree fndecl = TREE_OPERAND (addr, 0); |
| if (TREE_CODE (fndecl) == MEM_REF) |
| { |
| if (TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR |
| && integer_zerop (TREE_OPERAND (fndecl, 1))) |
| return TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0); |
| else |
| return NULL_TREE; |
| } |
| return TREE_OPERAND (addr, 0); |
| } |
| return NULL_TREE; |
| } |
| |
| |
| /* Return the type returned by call statement GS. */ |
| |
| static inline tree |
| gimple_call_return_type (const_gimple gs) |
| { |
| tree fn = gimple_call_fn (gs); |
| tree type = TREE_TYPE (fn); |
| |
| /* See through the pointer. */ |
| type = TREE_TYPE (type); |
| |
| /* The type returned by a FUNCTION_DECL 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 GS. */ |
| |
| static inline tree * |
| gimple_call_chain_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| return gimple_op_ptr (gs, 2); |
| } |
| |
| /* Set CHAIN to be the static chain for call statement GS. */ |
| |
| static inline void |
| gimple_call_set_chain (gimple gs, tree chain) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CALL); |
| |
| gimple_set_op (gs, 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 (gimple s, bool tail_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (tail_p) |
| s->gsbase.subcode |= GF_CALL_TAILCALL; |
| else |
| s->gsbase.subcode &= ~GF_CALL_TAILCALL; |
| } |
| |
| |
| /* Return true if GIMPLE_CALL S is marked as a tail call. */ |
| |
| static inline bool |
| gimple_call_tail_p (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (s->gsbase.subcode & GF_CALL_TAILCALL) != 0; |
| } |
| |
| |
| /* Set the inlinable status of GIMPLE_CALL S to INLINABLE_P. */ |
| |
| static inline void |
| gimple_call_set_cannot_inline (gimple s, bool inlinable_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (inlinable_p) |
| s->gsbase.subcode |= GF_CALL_CANNOT_INLINE; |
| else |
| s->gsbase.subcode &= ~GF_CALL_CANNOT_INLINE; |
| } |
| |
| |
| /* Return true if GIMPLE_CALL S cannot be inlined. */ |
| |
| static inline bool |
| gimple_call_cannot_inline_p (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (s->gsbase.subcode & GF_CALL_CANNOT_INLINE) != 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 (gimple s, bool return_slot_opt_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (return_slot_opt_p) |
| s->gsbase.subcode |= GF_CALL_RETURN_SLOT_OPT; |
| else |
| s->gsbase.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 (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (s->gsbase.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 (gimple s, bool from_thunk_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (from_thunk_p) |
| s->gsbase.subcode |= GF_CALL_FROM_THUNK; |
| else |
| s->gsbase.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 (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (s->gsbase.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 (gimple s, bool pass_arg_pack_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (pass_arg_pack_p) |
| s->gsbase.subcode |= GF_CALL_VA_ARG_PACK; |
| else |
| s->gsbase.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 (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (s->gsbase.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 (gimple s, bool nothrow_p) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| if (nothrow_p) |
| s->gsbase.subcode |= GF_CALL_NOTHROW; |
| else |
| s->gsbase.subcode &= ~GF_CALL_NOTHROW; |
| } |
| |
| /* Return true if S is a nothrow call. */ |
| |
| static inline bool |
| gimple_call_nothrow_p (gimple s) |
| { |
| GIMPLE_CHECK (s, GIMPLE_CALL); |
| return (gimple_call_flags (s) & ECF_NOTHROW) != 0; |
| } |
| |
| |
| /* Copy all the GF_CALL_* flags from ORIG_CALL to DEST_CALL. */ |
| |
| static inline void |
| gimple_call_copy_flags (gimple dest_call, gimple orig_call) |
| { |
| GIMPLE_CHECK (dest_call, GIMPLE_CALL); |
| GIMPLE_CHECK (orig_call, GIMPLE_CALL); |
| dest_call->gsbase.subcode = orig_call->gsbase.subcode; |
| } |
| |
| |
| /* Return a pointer to the points-to solution for the set of call-used |
| variables of the call CALL. */ |
| |
| static inline struct pt_solution * |
| gimple_call_use_set (gimple call) |
| { |
| GIMPLE_CHECK (call, GIMPLE_CALL); |
| return &call->gimple_call.call_used; |
| } |
| |
| |
| /* Return a pointer to the points-to solution for the set of call-used |
| variables of the call CALL. */ |
| |
| static inline struct pt_solution * |
| gimple_call_clobber_set (gimple call) |
| { |
| GIMPLE_CHECK (call, GIMPLE_CALL); |
| return &call->gimple_call.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->gsbase.subcode; |
| } |
| |
| |
| /* Set CODE to be the predicate code for the conditional statement GS. */ |
| |
| static inline void |
| gimple_cond_set_code (gimple gs, enum tree_code code) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| gs->gsbase.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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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 (gimple gs, tree lhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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 (gimple gs, tree rhs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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 (gimple gs, tree label) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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 (gimple gs, tree label) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_COND); |
| 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 (gimple gs) |
| { |
| gimple_cond_set_lhs (gs, boolean_true_node); |
| gimple_cond_set_rhs (gs, boolean_false_node); |
| gs->gsbase.subcode = EQ_EXPR; |
| } |
| |
| |
| /* Set the conditional COND_STMT to be of the form 'if (1 == 1)'. */ |
| |
| static inline void |
| gimple_cond_make_true (gimple gs) |
| { |
| gimple_cond_set_lhs (gs, boolean_true_node); |
| gimple_cond_set_rhs (gs, boolean_true_node); |
| gs->gsbase.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_gimple 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_gimple 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 (var != 0)' or |
| 'if (var == 1)' */ |
| |
| static inline bool |
| gimple_cond_single_var_p (gimple gs) |
| { |
| if (gimple_cond_code (gs) == NE_EXPR |
| && gimple_cond_rhs (gs) == boolean_false_node) |
| return true; |
| |
| if (gimple_cond_code (gs) == EQ_EXPR |
| && gimple_cond_rhs (gs) == boolean_true_node) |
| 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 (gimple 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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_LABEL); |
| 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 (gimple gs, tree label) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_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 (gimple gs, tree dest) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_GOTO); |
| gimple_set_op (gs, 0, dest); |
| } |
| |
| |
| /* Return the variables declared in the GIMPLE_BIND statement GS. */ |
| |
| static inline tree |
| gimple_bind_vars (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| return gs->gimple_bind.vars; |
| } |
| |
| |
| /* Set VARS to be the set of variables declared in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_vars (gimple gs, tree vars) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gs->gimple_bind.vars = vars; |
| } |
| |
| |
| /* Append VARS to the set of variables declared in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_append_vars (gimple gs, tree vars) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gs->gimple_bind.vars = chainon (gs->gimple_bind.vars, vars); |
| } |
| |
| |
| /* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */ |
| |
| static inline gimple_seq |
| gimple_bind_body (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| return gs->gimple_bind.body; |
| } |
| |
| |
| /* Set SEQ to be the GIMPLE sequence contained in the GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_body (gimple gs, gimple_seq seq) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gs->gimple_bind.body = seq; |
| } |
| |
| |
| /* Append a statement to the end of a GIMPLE_BIND's body. */ |
| |
| static inline void |
| gimple_bind_add_stmt (gimple gs, gimple stmt) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gimple_seq_add_stmt (&gs->gimple_bind.body, stmt); |
| } |
| |
| |
| /* Append a sequence of statements to the end of a GIMPLE_BIND's body. */ |
| |
| static inline void |
| gimple_bind_add_seq (gimple gs, gimple_seq seq) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gimple_seq_add_seq (&gs->gimple_bind.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_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| return gs->gimple_bind.block; |
| } |
| |
| |
| /* Set BLOCK to be the TREE_BLOCK node associated with GIMPLE_BIND |
| statement GS. */ |
| |
| static inline void |
| gimple_bind_set_block (gimple gs, tree block) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_BIND); |
| gcc_gimple_checking_assert (block == NULL_TREE |
| || TREE_CODE (block) == BLOCK); |
| gs->gimple_bind.block = block; |
| } |
| |
| |
| /* Return the number of input operands for GIMPLE_ASM GS. */ |
| |
| static inline unsigned |
| gimple_asm_ninputs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return gs->gimple_asm.ni; |
| } |
| |
| |
| /* Return the number of output operands for GIMPLE_ASM GS. */ |
| |
| static inline unsigned |
| gimple_asm_noutputs (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return gs->gimple_asm.no; |
| } |
| |
| |
| /* Return the number of clobber operands for GIMPLE_ASM GS. */ |
| |
| static inline unsigned |
| gimple_asm_nclobbers (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return gs->gimple_asm.nc; |
| } |
| |
| /* Return the number of label operands for GIMPLE_ASM GS. */ |
| |
| static inline unsigned |
| gimple_asm_nlabels (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return gs->gimple_asm.nl; |
| } |
| |
| /* Return input operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree |
| gimple_asm_input_op (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); |
| return gimple_op (gs, index); |
| } |
| |
| /* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree * |
| gimple_asm_input_op_ptr (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); |
| return gimple_op_ptr (gs, index); |
| } |
| |
| |
| /* Set IN_OP to be input operand INDEX in GIMPLE_ASM GS. */ |
| |
| static inline void |
| gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.ni |
| && TREE_CODE (in_op) == TREE_LIST); |
| gimple_set_op (gs, index, in_op); |
| } |
| |
| |
| /* Return output operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree |
| gimple_asm_output_op (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.no); |
| return gimple_op (gs, index + gs->gimple_asm.ni); |
| } |
| |
| /* Return a pointer to output operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree * |
| gimple_asm_output_op_ptr (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.no); |
| return gimple_op_ptr (gs, index + gs->gimple_asm.ni); |
| } |
| |
| |
| /* Set OUT_OP to be output operand INDEX in GIMPLE_ASM GS. */ |
| |
| static inline void |
| gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.no |
| && TREE_CODE (out_op) == TREE_LIST); |
| gimple_set_op (gs, index + gs->gimple_asm.ni, out_op); |
| } |
| |
| |
| /* Return clobber operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree |
| gimple_asm_clobber_op (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.nc); |
| return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no); |
| } |
| |
| |
| /* Set CLOBBER_OP to be clobber operand INDEX in GIMPLE_ASM GS. */ |
| |
| static inline void |
| gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.nc |
| && TREE_CODE (clobber_op) == TREE_LIST); |
| gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op); |
| } |
| |
| /* Return label operand INDEX of GIMPLE_ASM GS. */ |
| |
| static inline tree |
| gimple_asm_label_op (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.nl); |
| return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc); |
| } |
| |
| /* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM GS. */ |
| |
| static inline void |
| gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| gcc_gimple_checking_assert (index <= gs->gimple_asm.nl |
| && TREE_CODE (label_op) == TREE_LIST); |
| gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, label_op); |
| } |
| |
| /* Return the string representing the assembly instruction in |
| GIMPLE_ASM GS. */ |
| |
| static inline const char * |
| gimple_asm_string (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return gs->gimple_asm.string; |
| } |
| |
| |
| /* Return true if GS is an asm statement marked volatile. */ |
| |
| static inline bool |
| gimple_asm_volatile_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return (gs->gsbase.subcode & GF_ASM_VOLATILE) != 0; |
| } |
| |
| |
| /* If VOLATLE_P is true, mark asm statement GS as volatile. */ |
| |
| static inline void |
| gimple_asm_set_volatile (gimple gs, bool volatile_p) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| if (volatile_p) |
| gs->gsbase.subcode |= GF_ASM_VOLATILE; |
| else |
| gs->gsbase.subcode &= ~GF_ASM_VOLATILE; |
| } |
| |
| |
| /* If INPUT_P is true, mark asm GS as an ASM_INPUT. */ |
| |
| static inline void |
| gimple_asm_set_input (gimple gs, bool input_p) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| if (input_p) |
| gs->gsbase.subcode |= GF_ASM_INPUT; |
| else |
| gs->gsbase.subcode &= ~GF_ASM_INPUT; |
| } |
| |
| |
| /* Return true if asm GS is an ASM_INPUT. */ |
| |
| static inline bool |
| gimple_asm_input_p (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_ASM); |
| return (gs->gsbase.subcode & GF_ASM_INPUT) != 0; |
| } |
| |
| |
| /* Return the types handled by GIMPLE_CATCH statement GS. */ |
| |
| static inline tree |
| gimple_catch_types (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| return gs->gimple_catch.types; |
| } |
| |
| |
| /* Return a pointer to the types handled by GIMPLE_CATCH statement GS. */ |
| |
| static inline tree * |
| gimple_catch_types_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| return &gs->gimple_catch.types; |
| } |
| |
| |
| /* Return the GIMPLE sequence representing the body of the handler of |
| GIMPLE_CATCH statement GS. */ |
| |
| static inline gimple_seq |
| gimple_catch_handler (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| return gs->gimple_catch.handler; |
| } |
| |
| |
| /* Return a pointer to the GIMPLE sequence representing the body of |
| the handler of GIMPLE_CATCH statement GS. */ |
| |
| static inline gimple_seq * |
| gimple_catch_handler_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| return &gs->gimple_catch.handler; |
| } |
| |
| |
| /* Set T to be the set of types handled by GIMPLE_CATCH GS. */ |
| |
| static inline void |
| gimple_catch_set_types (gimple gs, tree t) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| gs->gimple_catch.types = t; |
| } |
| |
| |
| /* Set HANDLER to be the body of GIMPLE_CATCH GS. */ |
| |
| static inline void |
| gimple_catch_set_handler (gimple gs, gimple_seq handler) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_CATCH); |
| gs->gimple_catch.handler = handler; |
| } |
| |
| |
| /* Return the types handled by GIMPLE_EH_FILTER statement GS. */ |
| |
| static inline tree |
| gimple_eh_filter_types (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); |
| return gs->gimple_eh_filter.types; |
| } |
| |
| |
| /* Return a pointer to the types handled by GIMPLE_EH_FILTER statement |
| GS. */ |
| |
| static inline tree * |
| gimple_eh_filter_types_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); |
| return &gs->gimple_eh_filter.types; |
| } |
| |
| |
| /* Return the sequence of statement to execute when GIMPLE_EH_FILTER |
| statement fails. */ |
| |
| static inline gimple_seq |
| gimple_eh_filter_failure (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); |
| return gs->gimple_eh_filter.failure; |
| } |
| |
| |
| /* Set TYPES to be the set of types handled by GIMPLE_EH_FILTER GS. */ |
| |
| static inline void |
| gimple_eh_filter_set_types (gimple gs, tree types) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); |
| gs->gimple_eh_filter.types = types; |
| } |
| |
| |
| /* Set FAILURE to be the sequence of statements to execute on failure |
| for GIMPLE_EH_FILTER GS. */ |
| |
| static inline void |
| gimple_eh_filter_set_failure (gimple gs, gimple_seq failure) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); |
| gs->gimple_eh_filter.failure = failure; |
| } |
| |
| /* Get the function decl to be called by the MUST_NOT_THROW region. */ |
| |
| static inline tree |
| gimple_eh_must_not_throw_fndecl (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); |
| return gs->gimple_eh_mnt.fndecl; |
| } |
| |
| /* Set the function decl to be called by GS to DECL. */ |
| |
| static inline void |
| gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); |
| gs->gimple_eh_mnt.fndecl = decl; |
| } |
| |
| |
| /* GIMPLE_TRY accessors. */ |
| |
| /* Return the kind of try block represented by GIMPLE_TRY GS. This is |
| either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY. */ |
| |
| static inline enum gimple_try_flags |
| gimple_try_kind (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| return (enum gimple_try_flags) (gs->gsbase.subcode & GIMPLE_TRY_KIND); |
| } |
| |
| |
| /* Set the kind of try block represented by GIMPLE_TRY GS. */ |
| |
| static inline void |
| gimple_try_set_kind (gimple gs, enum gimple_try_flags kind) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| gcc_gimple_checking_assert (kind == GIMPLE_TRY_CATCH |
| || kind == GIMPLE_TRY_FINALLY); |
| if (gimple_try_kind (gs) != kind) |
| gs->gsbase.subcode = (unsigned int) kind; |
| } |
| |
| |
| /* Return the GIMPLE_TRY_CATCH_IS_CLEANUP flag. */ |
| |
| static inline bool |
| gimple_try_catch_is_cleanup (const_gimple gs) |
| { |
| gcc_gimple_checking_assert (gimple_try_kind (gs) == GIMPLE_TRY_CATCH); |
| return (gs->gsbase.subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0; |
| } |
| |
| |
| /* Return the sequence of statements used as the body for GIMPLE_TRY GS. */ |
| |
| static inline gimple_seq |
| gimple_try_eval (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| return gs->gimple_try.eval; |
| } |
| |
| |
| /* Return the sequence of statements used as the cleanup body for |
| GIMPLE_TRY GS. */ |
| |
| static inline gimple_seq |
| gimple_try_cleanup (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| return gs->gimple_try.cleanup; |
| } |
| |
| |
| /* Set the GIMPLE_TRY_CATCH_IS_CLEANUP flag. */ |
| |
| static inline void |
| gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup) |
| { |
| gcc_gimple_checking_assert (gimple_try_kind (g) == GIMPLE_TRY_CATCH); |
| if (catch_is_cleanup) |
| g->gsbase.subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP; |
| else |
| g->gsbase.subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP; |
| } |
| |
| |
| /* Set EVAL to be the sequence of statements to use as the body for |
| GIMPLE_TRY GS. */ |
| |
| static inline void |
| gimple_try_set_eval (gimple gs, gimple_seq eval) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| gs->gimple_try.eval = eval; |
| } |
| |
| |
| /* Set CLEANUP to be the sequence of statements to use as the cleanup |
| body for GIMPLE_TRY GS. */ |
| |
| static inline void |
| gimple_try_set_cleanup (gimple gs, gimple_seq cleanup) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_TRY); |
| gs->gimple_try.cleanup = cleanup; |
| } |
| |
| |
| /* Return the cleanup sequence for cleanup statement GS. */ |
| |
| static inline gimple_seq |
| gimple_wce_cleanup (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); |
| return gs->gimple_wce.cleanup; |
| } |
| |
| |
| /* Set CLEANUP to be the cleanup sequence for GS. */ |
| |
| static inline void |
| gimple_wce_set_cleanup (gimple gs, gimple_seq cleanup) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); |
| gs->gimple_wce.cleanup = cleanup; |
| } |
| |
| |
| /* Return the CLEANUP_EH_ONLY flag for a WCE tuple. */ |
| |
| static inline bool |
| gimple_wce_cleanup_eh_only (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); |
| return gs->gsbase.subcode != 0; |
| } |
| |
| |
| /* Set the CLEANUP_EH_ONLY flag for a WCE tuple. */ |
| |
| static inline void |
| gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); |
| gs->gsbase.subcode = (unsigned int) eh_only_p; |
| } |
| |
| |
| /* Return the maximum number of arguments supported by GIMPLE_PHI GS. */ |
| |
| static inline unsigned |
| gimple_phi_capacity (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| return gs->gimple_phi.capacity; |
| } |
| |
| |
| /* Return the number of arguments in GIMPLE_PHI GS. This must always |
| be exactly the number of incoming edges for the basic block holding |
| GS. */ |
| |
| static inline unsigned |
| gimple_phi_num_args (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| return gs->gimple_phi.nargs; |
| } |
| |
| |
| /* Return the SSA name created by GIMPLE_PHI GS. */ |
| |
| static inline tree |
| gimple_phi_result (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| return gs->gimple_phi.result; |
| } |
| |
| /* Return a pointer to the SSA name created by GIMPLE_PHI GS. */ |
| |
| static inline tree * |
| gimple_phi_result_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| return &gs->gimple_phi.result; |
| } |
| |
| /* Set RESULT to be the SSA name created by GIMPLE_PHI GS. */ |
| |
| static inline void |
| gimple_phi_set_result (gimple gs, tree result) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| gs->gimple_phi.result = result; |
| } |
| |
| |
| /* Return the PHI argument corresponding to incoming edge INDEX for |
| GIMPLE_PHI GS. */ |
| |
| static inline struct phi_arg_d * |
| gimple_phi_arg (gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| gcc_gimple_checking_assert (index <= gs->gimple_phi.capacity); |
| return &(gs->gimple_phi.args[index]); |
| } |
| |
| /* Set PHIARG to be the argument corresponding to incoming edge INDEX |
| for GIMPLE_PHI GS. */ |
| |
| static inline void |
| gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PHI); |
| gcc_gimple_checking_assert (index <= gs->gimple_phi.nargs); |
| gs->gimple_phi.args[index] = *phiarg; |
| } |
| |
| /* Return the region number for GIMPLE_RESX GS. */ |
| |
| static inline int |
| gimple_resx_region (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_RESX); |
| return gs->gimple_eh_ctrl.region; |
| } |
| |
| /* Set REGION to be the region number for GIMPLE_RESX GS. */ |
| |
| static inline void |
| gimple_resx_set_region (gimple gs, int region) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_RESX); |
| gs->gimple_eh_ctrl.region = region; |
| } |
| |
| /* Return the region number for GIMPLE_EH_DISPATCH GS. */ |
| |
| static inline int |
| gimple_eh_dispatch_region (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); |
| return gs->gimple_eh_ctrl.region; |
| } |
| |
| /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ |
| |
| static inline void |
| gimple_eh_dispatch_set_region (gimple gs, int region) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); |
| gs->gimple_eh_ctrl.region = region; |
| } |
| |
| /* Return the number of labels associated with the switch statement GS. */ |
| |
| static inline unsigned |
| gimple_switch_num_labels (const_gimple gs) |
| { |
| unsigned num_ops; |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| num_ops = gimple_num_ops (gs); |
| gcc_gimple_checking_assert (num_ops > 1); |
| return num_ops - 1; |
| } |
| |
| |
| /* Set NLABELS to be the number of labels for the switch statement GS. */ |
| |
| static inline void |
| gimple_switch_set_num_labels (gimple g, unsigned nlabels) |
| { |
| GIMPLE_CHECK (g, GIMPLE_SWITCH); |
| gimple_set_num_ops (g, nlabels + 1); |
| } |
| |
| |
| /* Return the index variable used by the switch statement GS. */ |
| |
| static inline tree |
| gimple_switch_index (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Return a pointer to the index variable for the switch statement GS. */ |
| |
| static inline tree * |
| gimple_switch_index_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| return gimple_op_ptr (gs, 0); |
| } |
| |
| |
| /* Set INDEX to be the index variable for switch statement GS. */ |
| |
| static inline void |
| gimple_switch_set_index (gimple gs, tree index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| gcc_gimple_checking_assert (SSA_VAR_P (index) || CONSTANT_CLASS_P (index)); |
| gimple_set_op (gs, 0, index); |
| } |
| |
| |
| /* Return the label numbered INDEX. The default label is 0, followed by any |
| labels in a switch statement. */ |
| |
| static inline tree |
| gimple_switch_label (const_gimple gs, unsigned index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| gcc_gimple_checking_assert (gimple_num_ops (gs) > index + 1); |
| return gimple_op (gs, index + 1); |
| } |
| |
| /* Set the label number INDEX to LABEL. 0 is always the default label. */ |
| |
| static inline void |
| gimple_switch_set_label (gimple gs, unsigned index, tree label) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_SWITCH); |
| gcc_gimple_checking_assert (gimple_num_ops (gs) > index + 1 |
| && (label == NULL_TREE |
| || TREE_CODE (label) == CASE_LABEL_EXPR)); |
| gimple_set_op (gs, index + 1, label); |
| } |
| |
| /* Return the default label for a switch statement. */ |
| |
| static inline tree |
| gimple_switch_default_label (const_gimple gs) |
| { |
| return gimple_switch_label (gs, 0); |
| } |
| |
| /* Set the default label for a switch statement. */ |
| |
| static inline void |
| gimple_switch_set_default_label (gimple gs, tree label) |
| { |
| gimple_switch_set_label (gs, 0, label); |
| } |
| |
| /* Return true if GS is a GIMPLE_DEBUG statement. */ |
| |
| static inline bool |
| is_gimple_debug (const_gimple gs) |
| { |
| return gimple_code (gs) == GIMPLE_DEBUG; |
| } |
| |
| /* Return true if S is a GIMPLE_DEBUG BIND statement. */ |
| |
| static inline bool |
| gimple_debug_bind_p (const_gimple s) |
| { |
| if (is_gimple_debug (s)) |
| return s->gsbase.subcode == GIMPLE_DEBUG_BIND; |
| |
| return false; |
| } |
| |
| /* Return the variable bound in a GIMPLE_DEBUG bind statement. */ |
| |
| static inline tree |
| gimple_debug_bind_get_var (gimple dbg) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| return gimple_op (dbg, 0); |
| } |
| |
| /* Return the value bound to the variable in a GIMPLE_DEBUG bind |
| statement. */ |
| |
| static inline tree |
| gimple_debug_bind_get_value (gimple dbg) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| return gimple_op (dbg, 1); |
| } |
| |
| /* Return a pointer to the value bound to the variable in a |
| GIMPLE_DEBUG bind statement. */ |
| |
| static inline tree * |
| gimple_debug_bind_get_value_ptr (gimple dbg) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| return gimple_op_ptr (dbg, 1); |
| } |
| |
| /* Set the variable bound in a GIMPLE_DEBUG bind statement. */ |
| |
| static inline void |
| gimple_debug_bind_set_var (gimple dbg, tree var) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| gimple_set_op (dbg, 0, var); |
| } |
| |
| /* Set the value bound to the variable in a GIMPLE_DEBUG bind |
| statement. */ |
| |
| static inline void |
| gimple_debug_bind_set_value (gimple dbg, tree value) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| gimple_set_op (dbg, 1, value); |
| } |
| |
| /* The second operand of a GIMPLE_DEBUG_BIND, when the value was |
| optimized away. */ |
| #define GIMPLE_DEBUG_BIND_NOVALUE NULL_TREE /* error_mark_node */ |
| |
| /* Remove the value bound to the variable in a GIMPLE_DEBUG bind |
| statement. */ |
| |
| static inline void |
| gimple_debug_bind_reset_value (gimple dbg) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| gimple_set_op (dbg, 1, GIMPLE_DEBUG_BIND_NOVALUE); |
| } |
| |
| /* Return true if the GIMPLE_DEBUG bind statement is bound to a |
| value. */ |
| |
| static inline bool |
| gimple_debug_bind_has_value_p (gimple dbg) |
| { |
| GIMPLE_CHECK (dbg, GIMPLE_DEBUG); |
| gcc_gimple_checking_assert (gimple_debug_bind_p (dbg)); |
| return gimple_op (dbg, 1) != GIMPLE_DEBUG_BIND_NOVALUE; |
| } |
| |
| #undef GIMPLE_DEBUG_BIND_NOVALUE |
| |
| /* Return the body for the OMP statement GS. */ |
| |
| static inline gimple_seq |
| gimple_omp_body (gimple gs) |
| { |
| return gs->omp.body; |
| } |
| |
| /* Set BODY to be the body for the OMP statement GS. */ |
| |
| static inline void |
| gimple_omp_set_body (gimple gs, gimple_seq body) |
| { |
| gs->omp.body = body; |
| } |
| |
| |
| /* Return the name associated with OMP_CRITICAL statement GS. */ |
| |
| static inline tree |
| gimple_omp_critical_name (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); |
| return gs->gimple_omp_critical.name; |
| } |
| |
| |
| /* Return a pointer to the name associated with OMP critical statement GS. */ |
| |
| static inline tree * |
| gimple_omp_critical_name_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); |
| return &gs->gimple_omp_critical.name; |
| } |
| |
| |
| /* Set NAME to be the name associated with OMP critical statement GS. */ |
| |
| static inline void |
| gimple_omp_critical_set_name (gimple gs, tree name) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); |
| gs->gimple_omp_critical.name = name; |
| } |
| |
| |
| /* Return the clauses associated with OMP_FOR GS. */ |
| |
| static inline tree |
| gimple_omp_for_clauses (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| return gs->gimple_omp_for.clauses; |
| } |
| |
| |
| /* Return a pointer to the OMP_FOR GS. */ |
| |
| static inline tree * |
| gimple_omp_for_clauses_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| return &gs->gimple_omp_for.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the list of clauses associated with OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_clauses (gimple gs, tree clauses) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gs->gimple_omp_for.clauses = clauses; |
| } |
| |
| |
| /* Get the collapse count of OMP_FOR GS. */ |
| |
| static inline size_t |
| gimple_omp_for_collapse (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| return gs->gimple_omp_for.collapse; |
| } |
| |
| |
| /* Return the index variable for OMP_FOR GS. */ |
| |
| static inline tree |
| gimple_omp_for_index (const_gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return gs->gimple_omp_for.iter[i].index; |
| } |
| |
| |
| /* Return a pointer to the index variable for OMP_FOR GS. */ |
| |
| static inline tree * |
| gimple_omp_for_index_ptr (gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return &gs->gimple_omp_for.iter[i].index; |
| } |
| |
| |
| /* Set INDEX to be the index variable for OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_index (gimple gs, size_t i, tree index) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| gs->gimple_omp_for.iter[i].index = index; |
| } |
| |
| |
| /* Return the initial value for OMP_FOR GS. */ |
| |
| static inline tree |
| gimple_omp_for_initial (const_gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return gs->gimple_omp_for.iter[i].initial; |
| } |
| |
| |
| /* Return a pointer to the initial value for OMP_FOR GS. */ |
| |
| static inline tree * |
| gimple_omp_for_initial_ptr (gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return &gs->gimple_omp_for.iter[i].initial; |
| } |
| |
| |
| /* Set INITIAL to be the initial value for OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_initial (gimple gs, size_t i, tree initial) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| gs->gimple_omp_for.iter[i].initial = initial; |
| } |
| |
| |
| /* Return the final value for OMP_FOR GS. */ |
| |
| static inline tree |
| gimple_omp_for_final (const_gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return gs->gimple_omp_for.iter[i].final; |
| } |
| |
| |
| /* Return a pointer to the final value for OMP_FOR GS. */ |
| |
| static inline tree * |
| gimple_omp_for_final_ptr (gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return &gs->gimple_omp_for.iter[i].final; |
| } |
| |
| |
| /* Set FINAL to be the final value for OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_final (gimple gs, size_t i, tree final) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| gs->gimple_omp_for.iter[i].final = final; |
| } |
| |
| |
| /* Return the increment value for OMP_FOR GS. */ |
| |
| static inline tree |
| gimple_omp_for_incr (const_gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return gs->gimple_omp_for.iter[i].incr; |
| } |
| |
| |
| /* Return a pointer to the increment value for OMP_FOR GS. */ |
| |
| static inline tree * |
| gimple_omp_for_incr_ptr (gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return &gs->gimple_omp_for.iter[i].incr; |
| } |
| |
| |
| /* Set INCR to be the increment value for OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_incr (gimple gs, size_t i, tree incr) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| gs->gimple_omp_for.iter[i].incr = incr; |
| } |
| |
| |
| /* Return the sequence of statements to execute before the OMP_FOR |
| statement GS starts. */ |
| |
| static inline gimple_seq |
| gimple_omp_for_pre_body (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| return gs->gimple_omp_for.pre_body; |
| } |
| |
| |
| /* Set PRE_BODY to be the sequence of statements to execute before the |
| OMP_FOR statement GS starts. */ |
| |
| static inline void |
| gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gs->gimple_omp_for.pre_body = pre_body; |
| } |
| |
| |
| /* Return the clauses associated with OMP_PARALLEL GS. */ |
| |
| static inline tree |
| gimple_omp_parallel_clauses (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with OMP_PARALLEL GS. */ |
| |
| static inline tree * |
| gimple_omp_parallel_clauses_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return &gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the list of clauses associated with OMP_PARALLEL |
| GS. */ |
| |
| static inline void |
| gimple_omp_parallel_set_clauses (gimple gs, tree clauses) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| gs->gimple_omp_parallel.clauses = clauses; |
| } |
| |
| |
| /* Return the child function used to hold the body of OMP_PARALLEL GS. */ |
| |
| static inline tree |
| gimple_omp_parallel_child_fn (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return gs->gimple_omp_parallel.child_fn; |
| } |
| |
| /* Return a pointer to the child function used to hold the body of |
| OMP_PARALLEL GS. */ |
| |
| static inline tree * |
| gimple_omp_parallel_child_fn_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return &gs->gimple_omp_parallel.child_fn; |
| } |
| |
| |
| /* Set CHILD_FN to be the child function for OMP_PARALLEL GS. */ |
| |
| static inline void |
| gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| gs->gimple_omp_parallel.child_fn = child_fn; |
| } |
| |
| |
| /* Return the artificial argument used to send variables and values |
| from the parent to the children threads in OMP_PARALLEL GS. */ |
| |
| static inline tree |
| gimple_omp_parallel_data_arg (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Return a pointer to the data argument for OMP_PARALLEL GS. */ |
| |
| static inline tree * |
| gimple_omp_parallel_data_arg_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| return &gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Set DATA_ARG to be the data argument for OMP_PARALLEL GS. */ |
| |
| static inline void |
| gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); |
| gs->gimple_omp_parallel.data_arg = data_arg; |
| } |
| |
| |
| /* Return the clauses associated with OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_clauses (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_clauses_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the list of clauses associated with OMP_TASK |
| GS. */ |
| |
| static inline void |
| gimple_omp_task_set_clauses (gimple gs, tree clauses) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.clauses = clauses; |
| } |
| |
| |
| /* Return the child function used to hold the body of OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_child_fn (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.child_fn; |
| } |
| |
| /* Return a pointer to the child function used to hold the body of |
| OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_child_fn_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.child_fn; |
| } |
| |
| |
| /* Set CHILD_FN to be the child function for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_task_set_child_fn (gimple gs, tree child_fn) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.child_fn = child_fn; |
| } |
| |
| |
| /* Return the artificial argument used to send variables and values |
| from the parent to the children threads in OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_data_arg (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Return a pointer to the data argument for OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_data_arg_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Set DATA_ARG to be the data argument for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_task_set_data_arg (gimple gs, tree data_arg) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.data_arg = data_arg; |
| } |
| |
| |
| /* Return the clauses associated with OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_taskreg_clauses (const_gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_taskreg_clauses_ptr (gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the list of clauses associated with OMP_TASK |
| GS. */ |
| |
| static inline void |
| gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.clauses = clauses; |
| } |
| |
| |
| /* Return the child function used to hold the body of OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_taskreg_child_fn (const_gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.child_fn; |
| } |
| |
| /* Return a pointer to the child function used to hold the body of |
| OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_taskreg_child_fn_ptr (gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.child_fn; |
| } |
| |
| |
| /* Set CHILD_FN to be the child function for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.child_fn = child_fn; |
| } |
| |
| |
| /* Return the artificial argument used to send variables and values |
| from the parent to the children threads in OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_taskreg_data_arg (const_gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Return a pointer to the data argument for OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_taskreg_data_arg_ptr (gimple gs) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_parallel.data_arg; |
| } |
| |
| |
| /* Set DATA_ARG to be the data argument for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) |
| { |
| if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_parallel.data_arg = data_arg; |
| } |
| |
| |
| /* Return the copy function used to hold the body of OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_copy_fn (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_task.copy_fn; |
| } |
| |
| /* Return a pointer to the copy function used to hold the body of |
| OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_copy_fn_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_task.copy_fn; |
| } |
| |
| |
| /* Set CHILD_FN to be the copy function for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_task.copy_fn = copy_fn; |
| } |
| |
| |
| /* Return size of the data block in bytes in OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_arg_size (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_task.arg_size; |
| } |
| |
| |
| /* Return a pointer to the data block size for OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_arg_size_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_task.arg_size; |
| } |
| |
| |
| /* Set ARG_SIZE to be the data block size for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_task_set_arg_size (gimple gs, tree arg_size) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_task.arg_size = arg_size; |
| } |
| |
| |
| /* Return align of the data block in bytes in OMP_TASK GS. */ |
| |
| static inline tree |
| gimple_omp_task_arg_align (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return gs->gimple_omp_task.arg_align; |
| } |
| |
| |
| /* Return a pointer to the data block align for OMP_TASK GS. */ |
| |
| static inline tree * |
| gimple_omp_task_arg_align_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| return &gs->gimple_omp_task.arg_align; |
| } |
| |
| |
| /* Set ARG_SIZE to be the data block align for OMP_TASK GS. */ |
| |
| static inline void |
| gimple_omp_task_set_arg_align (gimple gs, tree arg_align) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); |
| gs->gimple_omp_task.arg_align = arg_align; |
| } |
| |
| |
| /* Return the clauses associated with OMP_SINGLE GS. */ |
| |
| static inline tree |
| gimple_omp_single_clauses (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); |
| return gs->gimple_omp_single.clauses; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with OMP_SINGLE GS. */ |
| |
| static inline tree * |
| gimple_omp_single_clauses_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); |
| return &gs->gimple_omp_single.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the clauses associated with OMP_SINGLE GS. */ |
| |
| static inline void |
| gimple_omp_single_set_clauses (gimple gs, tree clauses) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); |
| gs->gimple_omp_single.clauses = clauses; |
| } |
| |
| |
| /* Return the clauses associated with OMP_SECTIONS GS. */ |
| |
| static inline tree |
| gimple_omp_sections_clauses (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| return gs->gimple_omp_sections.clauses; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with OMP_SECTIONS GS. */ |
| |
| static inline tree * |
| gimple_omp_sections_clauses_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| return &gs->gimple_omp_sections.clauses; |
| } |
| |
| |
| /* Set CLAUSES to be the set of clauses associated with OMP_SECTIONS |
| GS. */ |
| |
| static inline void |
| gimple_omp_sections_set_clauses (gimple gs, tree clauses) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| gs->gimple_omp_sections.clauses = clauses; |
| } |
| |
| |
| /* Return the control variable associated with the GIMPLE_OMP_SECTIONS |
| in GS. */ |
| |
| static inline tree |
| gimple_omp_sections_control (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| return gs->gimple_omp_sections.control; |
| } |
| |
| |
| /* Return a pointer to the clauses associated with the GIMPLE_OMP_SECTIONS |
| GS. */ |
| |
| static inline tree * |
| gimple_omp_sections_control_ptr (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| return &gs->gimple_omp_sections.control; |
| } |
| |
| |
| /* Set CONTROL to be the set of clauses associated with the |
| GIMPLE_OMP_SECTIONS in GS. */ |
| |
| static inline void |
| gimple_omp_sections_set_control (gimple gs, tree control) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); |
| gs->gimple_omp_sections.control = control; |
| } |
| |
| |
| /* Set COND to be the condition code for OMP_FOR GS. */ |
| |
| static inline void |
| gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (TREE_CODE_CLASS (cond) == tcc_comparison |
| && i < gs->gimple_omp_for.collapse); |
| gs->gimple_omp_for.iter[i].cond = cond; |
| } |
| |
| |
| /* Return the condition code associated with OMP_FOR GS. */ |
| |
| static inline enum tree_code |
| gimple_omp_for_cond (const_gimple gs, size_t i) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); |
| gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); |
| return gs->gimple_omp_for.iter[i].cond; |
| } |
| |
| |
| /* Set the value being stored in an atomic store. */ |
| |
| static inline void |
| gimple_omp_atomic_store_set_val (gimple g, tree val) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| g->gimple_omp_atomic_store.val = val; |
| } |
| |
| |
| /* Return the value being stored in an atomic store. */ |
| |
| static inline tree |
| gimple_omp_atomic_store_val (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| return g->gimple_omp_atomic_store.val; |
| } |
| |
| |
| /* Return a pointer to the value being stored in an atomic store. */ |
| |
| static inline tree * |
| gimple_omp_atomic_store_val_ptr (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); |
| return &g->gimple_omp_atomic_store.val; |
| } |
| |
| |
| /* Set the LHS of an atomic load. */ |
| |
| static inline void |
| gimple_omp_atomic_load_set_lhs (gimple g, tree lhs) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| g->gimple_omp_atomic_load.lhs = lhs; |
| } |
| |
| |
| /* Get the LHS of an atomic load. */ |
| |
| static inline tree |
| gimple_omp_atomic_load_lhs (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| return g->gimple_omp_atomic_load.lhs; |
| } |
| |
| |
| /* Return a pointer to the LHS of an atomic load. */ |
| |
| static inline tree * |
| gimple_omp_atomic_load_lhs_ptr (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| return &g->gimple_omp_atomic_load.lhs; |
| } |
| |
| |
| /* Set the RHS of an atomic load. */ |
| |
| static inline void |
| gimple_omp_atomic_load_set_rhs (gimple g, tree rhs) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| g->gimple_omp_atomic_load.rhs = rhs; |
| } |
| |
| |
| /* Get the RHS of an atomic load. */ |
| |
| static inline tree |
| gimple_omp_atomic_load_rhs (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| return g->gimple_omp_atomic_load.rhs; |
| } |
| |
| |
| /* Return a pointer to the RHS of an atomic load. */ |
| |
| static inline tree * |
| gimple_omp_atomic_load_rhs_ptr (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); |
| return &g->gimple_omp_atomic_load.rhs; |
| } |
| |
| |
| /* Get the definition of the control variable in a GIMPLE_OMP_CONTINUE. */ |
| |
| static inline tree |
| gimple_omp_continue_control_def (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| return g->gimple_omp_continue.control_def; |
| } |
| |
| /* The same as above, but return the address. */ |
| |
| static inline tree * |
| gimple_omp_continue_control_def_ptr (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| return &g->gimple_omp_continue.control_def; |
| } |
| |
| /* Set the definition of the control variable in a GIMPLE_OMP_CONTINUE. */ |
| |
| static inline void |
| gimple_omp_continue_set_control_def (gimple g, tree def) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| g->gimple_omp_continue.control_def = def; |
| } |
| |
| |
| /* Get the use of the control variable in a GIMPLE_OMP_CONTINUE. */ |
| |
| static inline tree |
| gimple_omp_continue_control_use (const_gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| return g->gimple_omp_continue.control_use; |
| } |
| |
| |
| /* The same as above, but return the address. */ |
| |
| static inline tree * |
| gimple_omp_continue_control_use_ptr (gimple g) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| return &g->gimple_omp_continue.control_use; |
| } |
| |
| |
| /* Set the use of the control variable in a GIMPLE_OMP_CONTINUE. */ |
| |
| static inline void |
| gimple_omp_continue_set_control_use (gimple g, tree use) |
| { |
| GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); |
| g->gimple_omp_continue.control_use = use; |
| } |
| |
| |
| /* Return a pointer to the return value for GIMPLE_RETURN GS. */ |
| |
| static inline tree * |
| gimple_return_retval_ptr (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_RETURN); |
| return gimple_op_ptr (gs, 0); |
| } |
| |
| /* Return the return value for GIMPLE_RETURN GS. */ |
| |
| static inline tree |
| gimple_return_retval (const_gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_RETURN); |
| return gimple_op (gs, 0); |
| } |
| |
| |
| /* Set RETVAL to be the return value for GIMPLE_RETURN GS. */ |
| |
| static inline void |
| gimple_return_set_retval (gimple gs, tree retval) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_RETURN); |
| gimple_set_op (gs, 0, retval); |
| } |
| |
| |
| /* Returns true when the gimple statment STMT is any of the OpenMP types. */ |
| |
| #define CASE_GIMPLE_OMP \ |
| case GIMPLE_OMP_PARALLEL: \ |
| case GIMPLE_OMP_TASK: \ |
| case GIMPLE_OMP_FOR: \ |
| case GIMPLE_OMP_SECTIONS: \ |
| case GIMPLE_OMP_SECTIONS_SWITCH: \ |
| case GIMPLE_OMP_SINGLE: \ |
| case GIMPLE_OMP_SECTION: \ |
| case GIMPLE_OMP_MASTER: \ |
| case GIMPLE_OMP_ORDERED: \ |
| case GIMPLE_OMP_CRITICAL: \ |
| case GIMPLE_OMP_RETURN: \ |
| case GIMPLE_OMP_ATOMIC_LOAD: \ |
| case GIMPLE_OMP_ATOMIC_STORE: \ |
| case GIMPLE_OMP_CONTINUE |
| |
| static inline bool |
| is_gimple_omp (const_gimple stmt) |
| { |
| switch (gimple_code (stmt)) |
| { |
| CASE_GIMPLE_OMP: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| |
| /* Returns TRUE if statement G is a GIMPLE_NOP. */ |
| |
| static inline bool |
| gimple_nop_p (const_gimple g) |
| { |
| return gimple_code (g) == GIMPLE_NOP; |
| } |
| |
| |
| /* Return true if GS is a GIMPLE_RESX. */ |
| |
| static inline bool |
| is_gimple_resx (const_gimple gs) |
| { |
| return gimple_code (gs) == GIMPLE_RESX; |
| } |
| |
| /* Return the predictor of GIMPLE_PREDICT statement GS. */ |
| |
| static inline enum br_predictor |
| gimple_predict_predictor (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PREDICT); |
| return (enum br_predictor) (gs->gsbase.subcode & ~GF_PREDICT_TAKEN); |
| } |
| |
| |
| /* Set the predictor of GIMPLE_PREDICT statement GS to PREDICT. */ |
| |
| static inline void |
| gimple_predict_set_predictor (gimple gs, enum br_predictor predictor) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PREDICT); |
| gs->gsbase.subcode = (gs->gsbase.subcode & GF_PREDICT_TAKEN) |
| | (unsigned) predictor; |
| } |
| |
| |
| /* Return the outcome of GIMPLE_PREDICT statement GS. */ |
| |
| static inline enum prediction |
| gimple_predict_outcome (gimple gs) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PREDICT); |
| return (gs->gsbase.subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN; |
| } |
| |
| |
| /* Set the outcome of GIMPLE_PREDICT statement GS to OUTCOME. */ |
| |
| static inline void |
| gimple_predict_set_outcome (gimple gs, enum prediction outcome) |
| { |
| GIMPLE_CHECK (gs, GIMPLE_PREDICT); |
| if (outcome == TAKEN) |
| gs->gsbase.subcode |= GF_PREDICT_TAKEN; |
| else |
| gs->gsbase.subcode &= ~GF_PREDICT_TAKEN; |
| } |
| |
| |
| /* Return the type of the main expression computed by STMT. Return |
| void_type_node if the statement computes nothing. */ |
| |
| static inline tree |
| gimple_expr_type (const_gimple stmt) |
| { |
| enum gimple_code code = gimple_code (stmt); |
| |
| if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL) |
| { |
| tree type; |
| /* In general we want to pass out a type that can be substituted |
| for both the RHS and the LHS types if there is a possibly |
| useless conversion involved. That means returning the |
| original RHS type as far as we can reconstruct it. */ |
| if (code == GIMPLE_CALL) |
| type = gimple_call_return_type (stmt); |
| else |
| switch (gimple_assign_rhs_code (stmt)) |
| { |
| case POINTER_PLUS_EXPR: |
| type = TREE_TYPE (gimple_assign_rhs1 (stmt)); |
| break; |
| |
| default: |
| /* As fallback use the type of the LHS. */ |
| type = TREE_TYPE (gimple_get_lhs (stmt)); |
| break; |
| } |
| return type; |
| } |
| else if (code == GIMPLE_COND) |
| return boolean_type_node; |
| else |
| return void_type_node; |
| } |
| |
| |
| /* Return a new iterator pointing to GIMPLE_SEQ's first statement. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_start (gimple_seq seq) |
| { |
| gimple_stmt_iterator i; |
| |
| i.ptr = gimple_seq_first (seq); |
| i.seq = seq; |
| i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL; |
| |
| return i; |
| } |
| |
| |
| /* Return a new iterator pointing to the first statement in basic block BB. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_start_bb (basic_block bb) |
| { |
| gimple_stmt_iterator i; |
| gimple_seq seq; |
| |
| seq = bb_seq (bb); |
| i.ptr = gimple_seq_first (seq); |
| i.seq = seq; |
| i.bb = bb; |
| |
| return i; |
| } |
| |
| |
| /* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_last (gimple_seq seq) |
| { |
| gimple_stmt_iterator i; |
| |
| i.ptr = gimple_seq_last (seq); |
| i.seq = seq; |
| i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL; |
| |
| return i; |
| } |
| |
| |
| /* Return a new iterator pointing to the last statement in basic block BB. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_last_bb (basic_block bb) |
| { |
| gimple_stmt_iterator i; |
| gimple_seq seq; |
| |
| seq = bb_seq (bb); |
| i.ptr = gimple_seq_last (seq); |
| i.seq = seq; |
| i.bb = bb; |
| |
| return i; |
| } |
| |
| |
| /* Return true if I is at the end of its sequence. */ |
| |
| static inline bool |
| gsi_end_p (gimple_stmt_iterator i) |
| { |
| return i.ptr == NULL; |
| } |
| |
| |
| /* Return true if I is one statement before the end of its sequence. */ |
| |
| static inline bool |
| gsi_one_before_end_p (gimple_stmt_iterator i) |
| { |
| return i.ptr != NULL && i.ptr->next == NULL; |
| } |
| |
| |
| /* Advance the iterator to the next gimple statement. */ |
| |
| static inline void |
| gsi_next (gimple_stmt_iterator *i) |
| { |
| i->ptr = i->ptr->next; |
| } |
| |
| /* Advance the iterator to the previous gimple statement. */ |
| |
| static inline void |
| gsi_prev (gimple_stmt_iterator *i) |
| { |
| i->ptr = i->ptr->prev; |
| } |
| |
| /* Return the current stmt. */ |
| |
| static inline gimple |
| gsi_stmt (gimple_stmt_iterator i) |
| { |
| return i.ptr->stmt; |
| } |
| |
| /* Return a block statement iterator that points to the first non-label |
| statement in block BB. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_after_labels (basic_block bb) |
| { |
| gimple_stmt_iterator gsi = gsi_start_bb (bb); |
| |
| while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL) |
| gsi_next (&gsi); |
| |
| return gsi; |
| } |
| |
| /* Advance the iterator to the next non-debug gimple statement. */ |
| |
| static inline void |
| gsi_next_nondebug (gimple_stmt_iterator *i) |
| { |
| do |
| { |
| gsi_next (i); |
| } |
| while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i))); |
| } |
| |
| /* Advance the iterator to the next non-debug gimple statement. */ |
| |
| static inline void |
| gsi_prev_nondebug (gimple_stmt_iterator *i) |
| { |
| do |
| { |
| gsi_prev (i); |
| } |
| while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i))); |
| } |
| |
| /* Return a new iterator pointing to the first non-debug statement in |
| basic block BB. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_start_nondebug_bb (basic_block bb) |
| { |
| gimple_stmt_iterator i = gsi_start_bb (bb); |
| |
| if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i))) |
| gsi_next_nondebug (&i); |
| |
| return i; |
| } |
| |
| /* Return a new iterator pointing to the last non-debug statement in |
| basic block BB. */ |
| |
| static inline gimple_stmt_iterator |
| gsi_last_nondebug_bb (basic_block bb) |
| { |
| gimple_stmt_iterator i = gsi_last_bb (bb); |
| |
| if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i))) |
| gsi_prev_nondebug (&i); |
| |
| return i; |
| } |
| |
| /* Return a pointer to the current stmt. |
| |
| NOTE: You may want to use gsi_replace on the iterator itself, |
| as this performs additional bookkeeping that will not be done |
| if you simply assign through a pointer returned by gsi_stmt_ptr. */ |
| |
| static inline gimple * |
| gsi_stmt_ptr (gimple_stmt_iterator *i) |
| { |
| return &i->ptr->stmt; |
| } |
| |
| |
| /* Return the basic block associated with this iterator. */ |
| |
| static inline basic_block |
| gsi_bb (gimple_stmt_iterator i) |
| { |
| return i.bb; |
| } |
| |
| |
| /* Return the sequence associated with this iterator. */ |
| |
| static inline gimple_seq |
| gsi_seq (gimple_stmt_iterator i) |
| { |
| return i.seq; |
| } |
| |
| |
| enum gsi_iterator_update |
| { |
| GSI_NEW_STMT, /* Only valid when single statement is added, move |
| iterator to it. */ |
| GSI_SAME_STMT, /* Leave the iterator at the same statement. */ |
| GSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable |
| for linking other statements in the same |
| direction. */ |
| }; |
| |
| /* In gimple-iterator.c */ |
| gimple_stmt_iterator gsi_start_phis (basic_block); |
| gimple_seq gsi_split_seq_after (gimple_stmt_iterator); |
| gimple_seq gsi_split_seq_before (gimple_stmt_iterator *); |
| void gsi_replace (gimple_stmt_iterator *, gimple, bool); |
| void gsi_insert_before (gimple_stmt_iterator *, gimple, |
| enum gsi_iterator_update); |
| void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple, |
| enum gsi_iterator_update); |
| void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq, |
| enum gsi_iterator_update); |
| void gsi_insert_seq_before_without_update (gimple_stmt_iterator *, gimple_seq, |
| enum gsi_iterator_update); |
| void gsi_insert_after (gimple_stmt_iterator *, gimple, |
| enum gsi_iterator_update); |
| void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple, |
| enum gsi_iterator_update); |
| void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq, |
| enum gsi_iterator_update); |
| void gsi_insert_seq_after_without_update (gimple_stmt_iterator *, gimple_seq, |
| enum gsi_iterator_update); |
| void gsi_remove (gimple_stmt_iterator *, bool); |
| gimple_stmt_iterator gsi_for_stmt (gimple); |
| void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *); |
| void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *); |
| void gsi_move_to_bb_end (gimple_stmt_iterator *, struct basic_block_def *); |
| void gsi_insert_on_edge (edge, gimple); |
| void gsi_insert_seq_on_edge (edge, gimple_seq); |
| basic_block gsi_insert_on_edge_immediate (edge, gimple); |
| basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq); |
| void gsi_commit_one_edge_insert (edge, basic_block *); |
| void gsi_commit_edge_inserts (void); |
| gimple gimple_call_copy_skip_args (gimple, bitmap); |
| |
| |
| /* Convenience routines to walk all statements of a gimple function. |
| Note that this is useful exclusively before the code is converted |
| into SSA form. Once the program is in SSA form, the standard |
| operand interface should be used to analyze/modify statements. */ |
| struct walk_stmt_info |
| { |
| /* Points to the current statement being walked. */ |
| gimple_stmt_iterator gsi; |
| |
| /* Additional data that the callback functions may want to carry |
| through the recursion. */ |
| void *info; |
| |
| /* Pointer map used to mark visited tree nodes when calling |
| walk_tree on each operand. If set to NULL, duplicate tree nodes |
| will be visited more than once. */ |
| struct pointer_set_t *pset; |
| |
| /* Indicates whether the operand being examined may be replaced |
| with something that matches is_gimple_val (if true) or something |
| slightly more complicated (if false). "Something" technically |
| means the common subset of is_gimple_lvalue and is_gimple_rhs, |
| but we never try to form anything more complicated than that, so |
| we don't bother checking. |
| |
| Also note that CALLBACK should update this flag while walking the |
| sub-expressions of a statement. For instance, when walking the |
| statement 'foo (&var)', the flag VAL_ONLY will initially be set |
| to true, however, when walking &var, the operand of that |
| ADDR_EXPR does not need to be a GIMPLE value. */ |
| bool val_only; |
| |
| /* True if we are currently walking the LHS of an assignment. */ |
| bool is_lhs; |
| |
| /* Optional. Set to true by the callback functions if they made any |
| changes. */ |
| bool changed; |
| |
| /* True if we're interested in location information. */ |
| bool want_locations; |
| |
| /* Operand returned by the callbacks. This is set when calling |
| walk_gimple_seq. If the walk_stmt_fn or walk_tree_fn callback |
| returns non-NULL, this field will contain the tree returned by |
| the last callback. */ |
| tree callback_result; |
| }; |
| |
| /* Callback for walk_gimple_stmt. Called for every statement found |
| during traversal. The first argument points to the statement to |
| walk. The second argument is a flag that the callback sets to |
| 'true' if it the callback handled all the operands and |
| sub-statements of the statement (the default value of this flag is |
| 'false'). The third argument is an anonymous pointer to data |
| to be used by the callback. */ |
| typedef tree (*walk_stmt_fn) (gimple_stmt_iterator *, bool *, |
| struct walk_stmt_info *); |
| |
| gimple walk_gimple_seq (gimple_seq, walk_stmt_fn, walk_tree_fn, |
| struct walk_stmt_info *); |
| tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn, walk_tree_fn, |
| struct walk_stmt_info *); |
| tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *); |
| |
| #ifdef GATHER_STATISTICS |
| /* Enum and arrays used for allocation stats. Keep in sync with |
| gimple.c:gimple_alloc_kind_names. */ |
| enum gimple_alloc_kind |
| { |
| gimple_alloc_kind_assign, /* Assignments. */ |
| gimple_alloc_kind_phi, /* PHI nodes. */ |
| gimple_alloc_kind_cond, /* Conditionals. */ |
| gimple_alloc_kind_seq, /* Sequences. */ |
| gimple_alloc_kind_rest, /* Everything else. */ |
| gimple_alloc_kind_all |
| }; |
| |
| extern int gimple_alloc_counts[]; |
| extern int gimple_alloc_sizes[]; |
| |
| /* Return the allocation kind for a given stmt CODE. */ |
| static inline enum gimple_alloc_kind |
| gimple_alloc_kind (enum gimple_code code) |
| { |
| switch (code) |
| { |
| case GIMPLE_ASSIGN: |
| return gimple_alloc_kind_assign; |
| case GIMPLE_PHI: |
| return gimple_alloc_kind_phi; |
| case GIMPLE_COND: |
| return gimple_alloc_kind_cond; |
| default: |
| return gimple_alloc_kind_rest; |
| } |
| } |
| #endif /* GATHER_STATISTICS */ |
| |
| extern void dump_gimple_statistics (void); |
| |
| /* In gimple-fold.c. */ |
| void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree); |
| tree gimple_fold_builtin (gimple); |
| bool fold_stmt (gimple_stmt_iterator *); |
| bool fold_stmt_inplace (gimple); |
| tree maybe_fold_offset_to_address (location_t, tree, tree, tree); |
| tree maybe_fold_offset_to_reference (location_t, tree, tree, tree); |
| tree maybe_fold_stmt_addition (location_t, tree, tree, tree); |
| tree get_symbol_constant_value (tree); |
| tree canonicalize_constructor_val (tree); |
| bool may_propagate_address_into_dereference (tree, tree); |
| extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, |
| enum tree_code, tree, tree); |
| extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree, |
| enum tree_code, tree, tree); |
| |
| #endif /* GCC_GIMPLE_H */ |