/* Gimple IR definitions.
- Copyright (C) 2007-2017 Free Software Foundation, Inc.
+ Copyright (C) 2007-2020 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>
This file is part of GCC.
enum gf_mask {
GF_ASM_INPUT = 1 << 0,
GF_ASM_VOLATILE = 1 << 1,
+ GF_ASM_INLINE = 1 << 2,
GF_CALL_FROM_THUNK = 1 << 0,
GF_CALL_RETURN_SLOT_OPT = 1 << 1,
GF_CALL_TAILCALL = 1 << 2,
GF_CALL_ALLOCA_FOR_VAR = 1 << 5,
GF_CALL_INTERNAL = 1 << 6,
GF_CALL_CTRL_ALTERING = 1 << 7,
- GF_CALL_WITH_BOUNDS = 1 << 8,
GF_CALL_MUST_TAIL_CALL = 1 << 9,
GF_CALL_BY_DESCRIPTOR = 1 << 10,
+ GF_CALL_NOCF_CHECK = 1 << 11,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
GF_OMP_PARALLEL_GRID_PHONY = 1 << 1,
GF_OMP_TASK_TASKLOOP = 1 << 0,
- GF_OMP_FOR_KIND_MASK = (1 << 4) - 1,
+ GF_OMP_TASK_TASKWAIT = 1 << 1,
+ GF_OMP_FOR_KIND_MASK = (1 << 3) - 1,
GF_OMP_FOR_KIND_FOR = 0,
GF_OMP_FOR_KIND_DISTRIBUTE = 1,
GF_OMP_FOR_KIND_TASKLOOP = 2,
- GF_OMP_FOR_KIND_CILKFOR = 3,
GF_OMP_FOR_KIND_OACC_LOOP = 4,
- GF_OMP_FOR_KIND_GRID_LOOP = 5,
- /* Flag for SIMD variants of OMP_FOR kinds. */
- GF_OMP_FOR_SIMD = 1 << 3,
- GF_OMP_FOR_KIND_SIMD = GF_OMP_FOR_SIMD | 0,
- GF_OMP_FOR_KIND_CILKSIMD = GF_OMP_FOR_SIMD | 1,
- GF_OMP_FOR_COMBINED = 1 << 4,
- GF_OMP_FOR_COMBINED_INTO = 1 << 5,
+ GF_OMP_FOR_KIND_GRID_LOOP = 5,
+ GF_OMP_FOR_KIND_SIMD = 6,
+ GF_OMP_FOR_COMBINED = 1 << 3,
+ GF_OMP_FOR_COMBINED_INTO = 1 << 4,
/* The following flag must not be used on GF_OMP_FOR_KIND_GRID_LOOP loop
statements. */
- GF_OMP_FOR_GRID_PHONY = 1 << 6,
+ GF_OMP_FOR_GRID_PHONY = 1 << 5,
/* The following two flags should only be set on GF_OMP_FOR_KIND_GRID_LOOP
loop statements. */
- GF_OMP_FOR_GRID_INTRA_GROUP = 1 << 6,
- GF_OMP_FOR_GRID_GROUP_ITER = 1 << 7,
+ GF_OMP_FOR_GRID_INTRA_GROUP = 1 << 5,
+ GF_OMP_FOR_GRID_GROUP_ITER = 1 << 6,
GF_OMP_TARGET_KIND_MASK = (1 << 4) - 1,
GF_OMP_TARGET_KIND_REGION = 0,
GF_OMP_TARGET_KIND_DATA = 1,
GF_OMP_TARGET_KIND_EXIT_DATA = 4,
GF_OMP_TARGET_KIND_OACC_PARALLEL = 5,
GF_OMP_TARGET_KIND_OACC_KERNELS = 6,
- GF_OMP_TARGET_KIND_OACC_DATA = 7,
- GF_OMP_TARGET_KIND_OACC_UPDATE = 8,
- GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 9,
- GF_OMP_TARGET_KIND_OACC_DECLARE = 10,
- GF_OMP_TARGET_KIND_OACC_HOST_DATA = 11,
+ GF_OMP_TARGET_KIND_OACC_SERIAL = 7,
+ GF_OMP_TARGET_KIND_OACC_DATA = 8,
+ GF_OMP_TARGET_KIND_OACC_UPDATE = 9,
+ GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 10,
+ GF_OMP_TARGET_KIND_OACC_DECLARE = 11,
+ GF_OMP_TARGET_KIND_OACC_HOST_DATA = 12,
GF_OMP_TEAMS_GRID_PHONY = 1 << 0,
+ GF_OMP_TEAMS_HOST = 1 << 1,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
a thread synchronization via some sort of barrier. The exact barrier
GF_OMP_RETURN_NOWAIT = 1 << 0,
GF_OMP_SECTION_LAST = 1 << 0,
- GF_OMP_ATOMIC_NEED_VALUE = 1 << 0,
- GF_OMP_ATOMIC_SEQ_CST = 1 << 1,
+ GF_OMP_ATOMIC_MEMORY_ORDER = (1 << 3) - 1,
+ GF_OMP_ATOMIC_NEED_VALUE = 1 << 3,
GF_PREDICT_TAKEN = 1 << 15
};
-/* Currently, there are only two types of gimple debug stmt. Others are
- envisioned, for example, to enable the generation of is_stmt notes
- in line number information, to mark sequence points, etc. This
- subcode is to be used to tell them apart. */
+/* This subcode tells apart different kinds of stmts that are not used
+ for codegen, but rather to retain debug information. */
enum gimple_debug_subcode {
GIMPLE_DEBUG_BIND = 0,
- GIMPLE_DEBUG_SOURCE_BIND = 1
+ GIMPLE_DEBUG_SOURCE_BIND = 1,
+ GIMPLE_DEBUG_BEGIN_STMT = 2,
+ GIMPLE_DEBUG_INLINE_ENTRY = 3
};
/* Masks for selecting a pass local flag (PLF) to work on. These
};
-/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET, GIMPLE_OMP_TASK */
+/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET, GIMPLE_OMP_TASK, GIMPLE_OMP_TEAMS */
struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
gimple_statement_omp_parallel_layout : public gimple_statement_omp
{
/* No extra fields; adds invariant:
stmt->code == GIMPLE_OMP_PARALLEL
- || stmt->code == GIMPLE_OMP_TASK. */
+ || stmt->code == GIMPLE_OMP_TASK
+ || stmt->code == GIMPLE_OMP_TEAMS. */
};
/* GIMPLE_OMP_PARALLEL */
tree control_use;
};
-/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS, GIMPLE_OMP_ORDERED */
+/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_ORDERED, GIMPLE_OMP_TASKGROUP,
+ GIMPLE_OMP_SCAN. */
struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
gimple_statement_omp_single_layout : public gimple_statement_omp
stmt->code == GIMPLE_OMP_SINGLE. */
};
-struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
- gomp_teams : public gimple_statement_omp_single_layout
+struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
+ gomp_teams : public gimple_statement_omp_taskreg
{
/* No extra fields; adds invariant:
stmt->code == GIMPLE_OMP_TEAMS. */
stmt->code == GIMPLE_OMP_ORDERED. */
};
+struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
+ gomp_scan : public gimple_statement_omp_single_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_SCAN. */
+};
+
/* GIMPLE_OMP_ATOMIC_LOAD.
Note: This is based on gimple, not g_s_omp, because g_s_omp
return gs->code == GIMPLE_DEBUG;
}
+template <>
+template <>
+inline bool
+is_a_helper <const gdebug *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_DEBUG;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_GOTO;
}
+template <>
+template <>
+inline bool
+is_a_helper <const ggoto *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_GOTO;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_LABEL;
}
+template <>
+template <>
+inline bool
+is_a_helper <const glabel *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_LABEL;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_EH_ELSE;
}
+template <>
+template <>
+inline bool
+is_a_helper <const geh_else *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_EH_ELSE;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_EH_MUST_NOT_THROW;
}
+template <>
+template <>
+inline bool
+is_a_helper <const geh_mnt *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_EH_MUST_NOT_THROW;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_OMP_ORDERED;
}
+template <>
+template <>
+inline bool
+is_a_helper <gomp_scan *>::test (gimple *gs)
+{
+ return gs->code == GIMPLE_OMP_SCAN;
+}
+
template <>
template <>
inline bool
inline bool
is_a_helper <gimple_statement_omp_taskreg *>::test (gimple *gs)
{
- return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK;
+ return (gs->code == GIMPLE_OMP_PARALLEL
+ || gs->code == GIMPLE_OMP_TASK
+ || gs->code == GIMPLE_OMP_TEAMS);
}
template <>
return gs->code == GIMPLE_SWITCH;
}
+template <>
+template <>
+inline bool
+is_a_helper <const gswitch *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_SWITCH;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_TRY;
}
+template <>
+template <>
+inline bool
+is_a_helper <const gtry *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_TRY;
+}
+
template <>
template <>
inline bool
return gs->code == GIMPLE_OMP_ORDERED;
}
+template <>
+template <>
+inline bool
+is_a_helper <const gomp_scan *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_OMP_SCAN;
+}
+
template <>
template <>
inline bool
inline bool
is_a_helper <const gimple_statement_omp_taskreg *>::test (const gimple *gs)
{
- return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK;
+ return (gs->code == GIMPLE_OMP_PARALLEL
+ || gs->code == GIMPLE_OMP_TASK
+ || gs->code == GIMPLE_OMP_TEAMS);
}
template <>
return gs->code == GIMPLE_PHI;
}
+template <>
+template <>
+inline bool
+is_a_helper <const greturn *>::test (const gimple *gs)
+{
+ return gs->code == GIMPLE_RETURN;
+}
+
template <>
template <>
inline bool
of comminucating the profile info to the builtin expanders. */
extern gimple *currently_expanding_gimple_stmt;
-#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
-gimple *gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
+size_t gimple_size (enum gimple_code code, unsigned num_ops = 0);
+void gimple_init (gimple *g, enum gimple_code code, unsigned num_ops);
+gimple *gimple_alloc (enum gimple_code, unsigned CXX_MEM_STAT_INFO);
greturn *gimple_build_return (tree);
void gimple_call_reset_alias_info (gcall *);
gcall *gimple_build_call_vec (tree, vec<tree> );
gcall *gimple_build_call_valist (tree, unsigned, va_list);
gcall *gimple_build_call_internal (enum internal_fn, unsigned, ...);
gcall *gimple_build_call_internal_vec (enum internal_fn, vec<tree> );
-gcall *gimple_build_call_from_tree (tree);
+gcall *gimple_build_call_from_tree (tree, tree);
gassign *gimple_build_assign (tree, tree CXX_MEM_STAT_INFO);
gassign *gimple_build_assign (tree, enum tree_code,
tree, tree, tree CXX_MEM_STAT_INFO);
gswitch *gimple_build_switch_nlabels (unsigned, tree, tree);
gswitch *gimple_build_switch (tree, tree, vec<tree> );
geh_dispatch *gimple_build_eh_dispatch (int);
-gdebug *gimple_build_debug_bind_stat (tree, tree, gimple * MEM_STAT_DECL);
-#define gimple_build_debug_bind(var,val,stmt) \
- gimple_build_debug_bind_stat ((var), (val), (stmt) MEM_STAT_INFO)
-gdebug *gimple_build_debug_source_bind_stat (tree, tree, gimple * MEM_STAT_DECL);
-#define gimple_build_debug_source_bind(var,val,stmt) \
- gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO)
+gdebug *gimple_build_debug_bind (tree, tree, gimple * CXX_MEM_STAT_INFO);
+gdebug *gimple_build_debug_source_bind (tree, tree, gimple * CXX_MEM_STAT_INFO);
+gdebug *gimple_build_debug_begin_stmt (tree, location_t CXX_MEM_STAT_INFO);
+gdebug *gimple_build_debug_inline_entry (tree, location_t CXX_MEM_STAT_INFO);
gomp_critical *gimple_build_omp_critical (gimple_seq, tree, tree);
gomp_for *gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq);
gomp_parallel *gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
gimple *gimple_build_omp_section (gimple_seq);
gimple *gimple_build_omp_master (gimple_seq);
gimple *gimple_build_omp_grid_body (gimple_seq);
-gimple *gimple_build_omp_taskgroup (gimple_seq);
+gimple *gimple_build_omp_taskgroup (gimple_seq, tree);
gomp_continue *gimple_build_omp_continue (tree, tree);
gomp_ordered *gimple_build_omp_ordered (gimple_seq, tree);
gimple *gimple_build_omp_return (bool);
+gomp_scan *gimple_build_omp_scan (gimple_seq, tree);
gomp_sections *gimple_build_omp_sections (gimple_seq, tree);
gimple *gimple_build_omp_sections_switch (void);
gomp_single *gimple_build_omp_single (gimple_seq, tree);
gomp_target *gimple_build_omp_target (gimple_seq, int, tree);
gomp_teams *gimple_build_omp_teams (gimple_seq, tree);
-gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree);
-gomp_atomic_store *gimple_build_omp_atomic_store (tree);
+gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree,
+ enum omp_memory_order);
+gomp_atomic_store *gimple_build_omp_atomic_store (tree, enum omp_memory_order);
gtransaction *gimple_build_transaction (gimple_seq);
extern void gimple_seq_add_stmt (gimple_seq *, gimple *);
extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple *);
int gimple_call_flags (const gimple *);
int gimple_call_arg_flags (const gcall *, unsigned);
int gimple_call_return_flags (const gcall *);
+bool gimple_call_nonnull_result_p (gcall *);
+tree gimple_call_nonnull_arg (gcall *);
bool gimple_assign_copy_p (gimple *);
bool gimple_assign_ssa_name_copy_p (gimple *);
bool gimple_assign_unary_nop_p (gimple *);
tree gimple_get_lhs (const gimple *);
void gimple_set_lhs (gimple *, tree);
gimple *gimple_copy (gimple *);
+void gimple_move_vops (gimple *, gimple *);
bool gimple_has_side_effects (const gimple *);
bool gimple_could_trap_p_1 (gimple *, bool, bool);
bool gimple_could_trap_p (gimple *);
extern bool gimple_ior_addresses_taken (bitmap, gimple *);
extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree);
extern combined_fn gimple_call_combined_fn (const gimple *);
+extern bool gimple_call_replaceable_operator_delete_p (const gcall *);
extern bool gimple_call_builtin_p (const gimple *);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_class);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_function);
extern void maybe_remove_unused_call_args (struct function *, gimple *);
extern bool gimple_inexpensive_call_p (gcall *);
extern bool stmt_can_terminate_bb_p (gimple *);
+extern location_t gimple_or_expr_nonartificial_location (gimple *, tree);
+
/* Formal (expression) temporary table handling: multiple occurrences of
the same scalar expression are evaluated into the same temporary. */
}
+/* Return non-artificial location information for statement G. */
+
+static inline location_t
+gimple_nonartificial_location (const gimple *g)
+{
+ location_t *ploc = NULL;
+
+ if (tree block = gimple_block (g))
+ ploc = block_nonartificial_location (block);
+
+ return ploc ? *ploc : gimple_location (g);
+}
+
+
/* Return the file name of the location of STMT. */
static inline const char *
gimple_omp_subcode (const gimple *s)
{
gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD
- && gimple_code (s) <= GIMPLE_OMP_TEAMS);
+ && gimple_code (s) <= GIMPLE_OMP_TEAMS);
return s->subcode;
}
}
-/* Return true if OMP atomic load/store statement G has the
- GF_OMP_ATOMIC_SEQ_CST flag set. */
+/* Return the memory order of the OMP atomic load/store statement G. */
-static inline bool
-gimple_omp_atomic_seq_cst_p (const gimple *g)
+static inline enum omp_memory_order
+gimple_omp_atomic_memory_order (const gimple *g)
{
if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD)
GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
- return (gimple_omp_subcode (g) & GF_OMP_ATOMIC_SEQ_CST) != 0;
+ return (enum omp_memory_order)
+ (gimple_omp_subcode (g) & GF_OMP_ATOMIC_MEMORY_ORDER);
}
-/* Set the GF_OMP_ATOMIC_SEQ_CST flag on G. */
+/* Set the memory order on G. */
static inline void
-gimple_omp_atomic_set_seq_cst (gimple *g)
+gimple_omp_atomic_set_memory_order (gimple *g, enum omp_memory_order mo)
{
if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD)
GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
- g->subcode |= GF_OMP_ATOMIC_SEQ_CST;
+ g->subcode = ((g->subcode & ~GF_OMP_ATOMIC_MEMORY_ORDER)
+ | (mo & GF_OMP_ATOMIC_MEMORY_ORDER));
}
return gimple_call_internal_p (gc);
}
-
-/* Return true if call GS is marked as instrumented by
- Pointer Bounds Checker. */
+/* Return true if call GS is marked as nocf_check. */
static inline bool
-gimple_call_with_bounds_p (const gcall *gs)
+gimple_call_nocf_check_p (const gcall *gs)
{
- return (gs->subcode & GF_CALL_WITH_BOUNDS) != 0;
+ return (gs->subcode & GF_CALL_NOCF_CHECK) != 0;
}
-static inline bool
-gimple_call_with_bounds_p (const gimple *gs)
-{
- const gcall *gc = GIMPLE_CHECK2<const gcall *> (gs);
- return gimple_call_with_bounds_p (gc);
-}
-
-
-/* If INSTRUMENTED_P is true, marm statement GS as instrumented by
- Pointer Bounds Checker. */
+/* Mark statement GS as nocf_check call. */
static inline void
-gimple_call_set_with_bounds (gcall *gs, bool with_bounds)
+gimple_call_set_nocf_check (gcall *gs, bool nocf_check)
{
- if (with_bounds)
- gs->subcode |= GF_CALL_WITH_BOUNDS;
+ if (nocf_check)
+ gs->subcode |= GF_CALL_NOCF_CHECK;
else
- gs->subcode &= ~GF_CALL_WITH_BOUNDS;
-}
-
-static inline void
-gimple_call_set_with_bounds (gimple *gs, bool with_bounds)
-{
- gcall *gc = GIMPLE_CHECK2<gcall *> (gs);
- gimple_call_set_with_bounds (gc, with_bounds);
+ gs->subcode &= ~GF_CALL_NOCF_CHECK;
}
-
/* Return the target of internal call GS. */
static inline enum internal_fn
/* Return true if GIMPLE_CALL S is marked as a tail call. */
static inline bool
-gimple_call_tail_p (gcall *s)
+gimple_call_tail_p (const gcall *s)
{
return (s->subcode & GF_CALL_TAILCALL) != 0;
}
/* Return true if S is marked for return slot optimization. */
static inline bool
-gimple_call_return_slot_opt_p (gcall *s)
+gimple_call_return_slot_opt_p (const gcall *s)
{
return (s->subcode & GF_CALL_RETURN_SLOT_OPT) != 0;
}
argument pack in its argument list. */
static inline bool
-gimple_call_va_arg_pack_p (gcall *s)
+gimple_call_va_arg_pack_p (const gcall *s)
{
return (s->subcode & GF_CALL_VA_ARG_PACK) != 0;
}
return &call_stmt->call_used;
}
+/* As above, but const. */
+
+static inline const pt_solution *
+gimple_call_use_set (const gcall *call_stmt)
+{
+ return &call_stmt->call_used;
+}
/* Return a pointer to the points-to solution for the set of call-used
variables of the call CALL_STMT. */
return &call_stmt->call_clobbered;
}
+/* As above, but const. */
+
+static inline const pt_solution *
+gimple_call_clobber_set (const gcall *call_stmt)
+{
+ return &call_stmt->call_clobbered;
+}
+
/* Returns true if this is a GIMPLE_ASSIGN or a GIMPLE_CALL with a
non-NULL lhs. */
static inline bool
-gimple_has_lhs (gimple *stmt)
+gimple_has_lhs (const gimple *stmt)
{
if (is_gimple_assign (stmt))
return true;
- if (gcall *call = dyn_cast <gcall *> (stmt))
+ if (const gcall *call = dyn_cast <const gcall *> (stmt))
return gimple_call_lhs (call) != NULL_TREE;
return false;
}
/* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */
static inline gimple_seq
-gimple_bind_body (gbind *gs)
+gimple_bind_body (const gbind *gs)
{
- return *gimple_bind_body_ptr (gs);
+ return *gimple_bind_body_ptr (const_cast <gbind *> (gs));
}
}
-/* Return true ASM_STMT ASM_STMT is an asm statement marked volatile. */
+/* Return true if ASM_STMT is marked volatile. */
static inline bool
gimple_asm_volatile_p (const gasm *asm_stmt)
}
-/* If VOLATLE_P is true, mark asm statement ASM_STMT as volatile. */
+/* If VOLATILE_P is true, mark asm statement ASM_STMT as volatile. */
static inline void
gimple_asm_set_volatile (gasm *asm_stmt, bool volatile_p)
}
+/* Return true if ASM_STMT is marked inline. */
+
+static inline bool
+gimple_asm_inline_p (const gasm *asm_stmt)
+{
+ return (asm_stmt->subcode & GF_ASM_INLINE) != 0;
+}
+
+
+/* If INLINE_P is true, mark asm statement ASM_STMT as inline. */
+
+static inline void
+gimple_asm_set_inline (gasm *asm_stmt, bool inline_p)
+{
+ if (inline_p)
+ asm_stmt->subcode |= GF_ASM_INLINE;
+ else
+ asm_stmt->subcode &= ~GF_ASM_INLINE;
+}
+
+
/* If INPUT_P is true, mark asm ASM_STMT as an ASM_INPUT. */
static inline void
GIMPLE_CATCH statement CATCH_STMT. */
static inline gimple_seq
-gimple_catch_handler (gcatch *catch_stmt)
+gimple_catch_handler (const gcatch *catch_stmt)
{
- return *gimple_catch_handler_ptr (catch_stmt);
+ return *gimple_catch_handler_ptr (const_cast <gcatch *> (catch_stmt));
}
statement fails. */
static inline gimple_seq
-gimple_eh_filter_failure (gimple *gs)
+gimple_eh_filter_failure (const gimple *gs)
{
- return *gimple_eh_filter_failure_ptr (gs);
+ return *gimple_eh_filter_failure_ptr (const_cast <gimple *> (gs));
}
/* Get the function decl to be called by the MUST_NOT_THROW region. */
static inline tree
-gimple_eh_must_not_throw_fndecl (geh_mnt *eh_mnt_stmt)
+gimple_eh_must_not_throw_fndecl (const geh_mnt *eh_mnt_stmt)
{
return eh_mnt_stmt->fndecl;
}
}
static inline gimple_seq
-gimple_eh_else_n_body (geh_else *eh_else_stmt)
+gimple_eh_else_n_body (const geh_else *eh_else_stmt)
{
- return *gimple_eh_else_n_body_ptr (eh_else_stmt);
+ return *gimple_eh_else_n_body_ptr (const_cast <geh_else *> (eh_else_stmt));
}
static inline gimple_seq *
}
static inline gimple_seq
-gimple_eh_else_e_body (geh_else *eh_else_stmt)
+gimple_eh_else_e_body (const geh_else *eh_else_stmt)
{
- return *gimple_eh_else_e_body_ptr (eh_else_stmt);
+ return *gimple_eh_else_e_body_ptr (const_cast <geh_else *> (eh_else_stmt));
}
static inline void
/* Return the sequence of statements used as the body for GIMPLE_TRY GS. */
static inline gimple_seq
-gimple_try_eval (gimple *gs)
+gimple_try_eval (const gimple *gs)
{
- return *gimple_try_eval_ptr (gs);
+ return *gimple_try_eval_ptr (const_cast <gimple *> (gs));
}
GIMPLE_TRY GS. */
static inline gimple_seq
-gimple_try_cleanup (gimple *gs)
+gimple_try_cleanup (const gimple *gs)
{
- return *gimple_try_cleanup_ptr (gs);
+ return *gimple_try_cleanup_ptr (const_cast <gimple *> (gs));
}
/* Return the SSA name created by GIMPLE_PHI GS. */
+static inline tree
+gimple_phi_result (const gphi *gs)
+{
+ return gs->result;
+}
+
static inline tree
gimple_phi_result (const gimple *gs)
{
const gphi *phi_stmt = as_a <const gphi *> (gs);
- return phi_stmt->result;
+ return gimple_phi_result (phi_stmt);
}
/* Return a pointer to the SSA name created by GIMPLE_PHI GS. */
+static inline tree *
+gimple_phi_result_ptr (gphi *gs)
+{
+ return &gs->result;
+}
+
static inline tree *
gimple_phi_result_ptr (gimple *gs)
{
gphi *phi_stmt = as_a <gphi *> (gs);
- return &phi_stmt->result;
+ return gimple_phi_result_ptr (phi_stmt);
}
/* Set RESULT to be the SSA name created by GIMPLE_PHI PHI. */
/* Return the PHI argument corresponding to incoming edge INDEX for
GIMPLE_PHI GS. */
+static inline struct phi_arg_d *
+gimple_phi_arg (gphi *gs, unsigned index)
+{
+ gcc_gimple_checking_assert (index < gs->nargs);
+ return &(gs->args[index]);
+}
+
+static inline const phi_arg_d *
+gimple_phi_arg (const gphi *gs, unsigned index)
+{
+ gcc_gimple_checking_assert (index < gs->nargs);
+ return &(gs->args[index]);
+}
+
static inline struct phi_arg_d *
gimple_phi_arg (gimple *gs, unsigned index)
{
gphi *phi_stmt = as_a <gphi *> (gs);
- gcc_gimple_checking_assert (index < phi_stmt->capacity);
- return &(phi_stmt->args[index]);
+ return gimple_phi_arg (phi_stmt, index);
}
/* Set PHIARG to be the argument corresponding to incoming edge INDEX
static inline void
gimple_phi_set_arg (gphi *phi, unsigned index, struct phi_arg_d * phiarg)
{
- gcc_gimple_checking_assert (index <= phi->nargs);
+ gcc_gimple_checking_assert (index < phi->nargs);
phi->args[index] = *phiarg;
}
/* Return the tree operand for argument I of PHI node GS. */
+static inline tree
+gimple_phi_arg_def (const gphi *gs, size_t index)
+{
+ return gimple_phi_arg (gs, index)->def;
+}
+
static inline tree
gimple_phi_arg_def (gimple *gs, size_t index)
{
/* Return the edge associated with argument I of phi node PHI. */
static inline edge
-gimple_phi_arg_edge (gphi *phi, size_t i)
+gimple_phi_arg_edge (const gphi *phi, size_t i)
{
return EDGE_PRED (gimple_bb (phi), i);
}
/* Return the source location of gimple argument I of phi node PHI. */
-static inline source_location
-gimple_phi_arg_location (gphi *phi, size_t i)
+static inline location_t
+gimple_phi_arg_location (const gphi *phi, size_t i)
{
return gimple_phi_arg (phi, i)->locus;
}
/* Return the source location of the argument on edge E of phi node PHI. */
-static inline source_location
+static inline location_t
gimple_phi_arg_location_from_edge (gphi *phi, edge e)
{
return gimple_phi_arg (phi, e->dest_idx)->locus;
/* Set the source location of gimple argument I of phi node PHI to LOC. */
static inline void
-gimple_phi_arg_set_location (gphi *phi, size_t i, source_location loc)
+gimple_phi_arg_set_location (gphi *phi, size_t i, location_t loc)
{
gimple_phi_arg (phi, i)->locus = loc;
}
/* Return TRUE if argument I of phi node PHI has a location record. */
static inline bool
-gimple_phi_arg_has_location (gphi *phi, size_t i)
+gimple_phi_arg_has_location (const gphi *phi, size_t i)
{
return gimple_phi_arg_location (phi, i) != UNKNOWN_LOCATION;
}
return gimple_code (gs) == GIMPLE_DEBUG;
}
+
+/* Return the first nondebug statement in GIMPLE sequence S. */
+
+static inline gimple *
+gimple_seq_first_nondebug_stmt (gimple_seq s)
+{
+ gimple_seq_node n = gimple_seq_first (s);
+ while (n && is_gimple_debug (n))
+ n = n->next;
+ return n;
+}
+
+
+/* Return the last nondebug statement in GIMPLE sequence S. */
+
+static inline gimple *
+gimple_seq_last_nondebug_stmt (gimple_seq s)
+{
+ gimple_seq_node n;
+ for (n = gimple_seq_last (s);
+ n && is_gimple_debug (n);
+ n = n->prev)
+ if (n == s)
+ return NULL;
+ return n;
+}
+
+
/* Return true if S is a GIMPLE_DEBUG BIND statement. */
static inline bool
/* Return the variable bound in a GIMPLE_DEBUG bind statement. */
static inline tree
-gimple_debug_bind_get_var (gimple *dbg)
+gimple_debug_bind_get_var (const gimple *dbg)
{
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
gcc_gimple_checking_assert (gimple_debug_bind_p (dbg));
statement. */
static inline tree
-gimple_debug_bind_get_value (gimple *dbg)
+gimple_debug_bind_get_value (const gimple *dbg)
{
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
gcc_gimple_checking_assert (gimple_debug_bind_p (dbg));
/* Return the variable bound in a GIMPLE_DEBUG source bind statement. */
static inline tree
-gimple_debug_source_bind_get_var (gimple *dbg)
+gimple_debug_source_bind_get_var (const gimple *dbg)
{
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
statement. */
static inline tree
-gimple_debug_source_bind_get_value (gimple *dbg)
+gimple_debug_source_bind_get_value (const gimple *dbg)
{
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
gimple_set_op (dbg, 1, value);
}
+/* Return true if S is a GIMPLE_DEBUG BEGIN_STMT statement. */
+
+static inline bool
+gimple_debug_begin_stmt_p (const gimple *s)
+{
+ if (is_gimple_debug (s))
+ return s->subcode == GIMPLE_DEBUG_BEGIN_STMT;
+
+ return false;
+}
+
+/* Return true if S is a GIMPLE_DEBUG INLINE_ENTRY statement. */
+
+static inline bool
+gimple_debug_inline_entry_p (const gimple *s)
+{
+ if (is_gimple_debug (s))
+ return s->subcode == GIMPLE_DEBUG_INLINE_ENTRY;
+
+ return false;
+}
+
+/* Return true if S is a GIMPLE_DEBUG non-binding marker statement. */
+
+static inline bool
+gimple_debug_nonbind_marker_p (const gimple *s)
+{
+ if (is_gimple_debug (s))
+ return s->subcode == GIMPLE_DEBUG_BEGIN_STMT
+ || s->subcode == GIMPLE_DEBUG_INLINE_ENTRY;
+
+ return false;
+}
+
/* Return the line number for EXPR, or return -1 if we have no line
number information for it. */
static inline int
/* Return the body for the OMP statement GS. */
static inline gimple_seq
-gimple_omp_body (gimple *gs)
+gimple_omp_body (const gimple *gs)
{
- return *gimple_omp_body_ptr (gs);
+ return *gimple_omp_body_ptr (const_cast <gimple *> (gs));
}
/* Set BODY to be the body for the OMP statement GS. */
}
+/* Return the clauses associated with OMP_SCAN statement SCAN_STMT. */
+
+static inline tree
+gimple_omp_scan_clauses (const gomp_scan *scan_stmt)
+{
+ return scan_stmt->clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP scan statement
+ ORD_STMT. */
+
+static inline tree *
+gimple_omp_scan_clauses_ptr (gomp_scan *scan_stmt)
+{
+ return &scan_stmt->clauses;
+}
+
+
+/* Set CLAUSES to be the clauses associated with OMP scan statement
+ ORD_STMT. */
+
+static inline void
+gimple_omp_scan_set_clauses (gomp_scan *scan_stmt, tree clauses)
+{
+ scan_stmt->clauses = clauses;
+}
+
+
+/* Return the clauses associated with OMP_TASKGROUP statement GS. */
+
+static inline tree
+gimple_omp_taskgroup_clauses (const gimple *gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP);
+ return
+ static_cast <const gimple_statement_omp_single_layout *> (gs)->clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP taskgroup statement
+ GS. */
+
+static inline tree *
+gimple_omp_taskgroup_clauses_ptr (gimple *gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP);
+ return &static_cast <gimple_statement_omp_single_layout *> (gs)->clauses;
+}
+
+
+/* Set CLAUSES to be the clauses associated with OMP taskgroup statement
+ GS. */
+
+static inline void
+gimple_omp_taskgroup_set_clauses (gimple *gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP);
+ static_cast <gimple_statement_omp_single_layout *> (gs)->clauses
+ = clauses;
+}
+
+
/* Return the kind of the OMP_FOR statemement G. */
static inline int
/* Get the collapse count of the OMP_FOR statement GS. */
static inline size_t
-gimple_omp_for_collapse (gimple *gs)
+gimple_omp_for_collapse (const gimple *gs)
{
- gomp_for *omp_for_stmt = as_a <gomp_for *> (gs);
+ const gomp_for *omp_for_stmt = as_a <const gomp_for *> (gs);
return omp_for_stmt->collapse;
}
statement GS starts. */
static inline gimple_seq
-gimple_omp_for_pre_body (gimple *gs)
+gimple_omp_for_pre_body (const gimple *gs)
{
- return *gimple_omp_for_pre_body_ptr (gs);
+ return *gimple_omp_for_pre_body_ptr (const_cast <gimple *> (gs));
}
}
+/* Return true if OMP task statement G has the
+ GF_OMP_TASK_TASKWAIT flag set. */
+
+static inline bool
+gimple_omp_task_taskwait_p (const gimple *g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_TASK);
+ return (gimple_omp_subcode (g) & GF_OMP_TASK_TASKWAIT) != 0;
+}
+
+
+/* Set the GF_OMP_TASK_TASKWAIT field in G depending on the boolean
+ value of TASKWAIT_P. */
+
+static inline void
+gimple_omp_task_set_taskwait_p (gimple *g, bool taskwait_p)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_TASK);
+ if (taskwait_p)
+ g->subcode |= GF_OMP_TASK_TASKWAIT;
+ else
+ g->subcode &= ~GF_OMP_TASK_TASKWAIT;
+}
+
+
/* Return the child function used to hold the body of OMP_TASK GS. */
static inline tree
omp_teams_stmt->clauses = clauses;
}
+/* Return the child function used to hold the body of OMP_TEAMS_STMT. */
+
+static inline tree
+gimple_omp_teams_child_fn (const gomp_teams *omp_teams_stmt)
+{
+ return omp_teams_stmt->child_fn;
+}
+
+/* Return a pointer to the child function used to hold the body of
+ OMP_TEAMS_STMT. */
+
+static inline tree *
+gimple_omp_teams_child_fn_ptr (gomp_teams *omp_teams_stmt)
+{
+ return &omp_teams_stmt->child_fn;
+}
+
+
+/* Set CHILD_FN to be the child function for OMP_TEAMS_STMT. */
+
+static inline void
+gimple_omp_teams_set_child_fn (gomp_teams *omp_teams_stmt, tree child_fn)
+{
+ omp_teams_stmt->child_fn = child_fn;
+}
+
+
+/* Return the artificial argument used to send variables and values
+ from the parent to the children threads in OMP_TEAMS_STMT. */
+
+static inline tree
+gimple_omp_teams_data_arg (const gomp_teams *omp_teams_stmt)
+{
+ return omp_teams_stmt->data_arg;
+}
+
+
+/* Return a pointer to the data argument for OMP_TEAMS_STMT. */
+
+static inline tree *
+gimple_omp_teams_data_arg_ptr (gomp_teams *omp_teams_stmt)
+{
+ return &omp_teams_stmt->data_arg;
+}
+
+
+/* Set DATA_ARG to be the data argument for OMP_TEAMS_STMT. */
+
+static inline void
+gimple_omp_teams_set_data_arg (gomp_teams *omp_teams_stmt, tree data_arg)
+{
+ omp_teams_stmt->data_arg = data_arg;
+}
+
/* Return the kernel_phony flag of an OMP_TEAMS_STMT. */
static inline bool
omp_teams_stmt->subcode &= ~GF_OMP_TEAMS_GRID_PHONY;
}
+/* Return the host flag of an OMP_TEAMS_STMT. */
+
+static inline bool
+gimple_omp_teams_host (const gomp_teams *omp_teams_stmt)
+{
+ return (gimple_omp_subcode (omp_teams_stmt) & GF_OMP_TEAMS_HOST) != 0;
+}
+
+/* Set host flag of an OMP_TEAMS_STMT to VALUE. */
+
+static inline void
+gimple_omp_teams_set_host (gomp_teams *omp_teams_stmt, bool value)
+{
+ if (value)
+ omp_teams_stmt->subcode |= GF_OMP_TEAMS_HOST;
+ else
+ omp_teams_stmt->subcode &= ~GF_OMP_TEAMS_HOST;
+}
+
/* Return the clauses associated with OMP_SECTIONS GS. */
static inline tree
/* Return the body for the GIMPLE_TRANSACTION statement TRANSACTION_STMT. */
static inline gimple_seq
-gimple_transaction_body (gtransaction *transaction_stmt)
+gimple_transaction_body (const gtransaction *transaction_stmt)
{
return transaction_stmt->body;
}
}
-/* Return the return bounds for GIMPLE_RETURN GS. */
-
-static inline tree
-gimple_return_retbnd (const gimple *gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_RETURN);
- return gimple_op (gs, 1);
-}
-
-
-/* Set RETVAL to be the return bounds for GIMPLE_RETURN GS. */
-
-static inline void
-gimple_return_set_retbnd (gimple *gs, tree retval)
-{
- GIMPLE_CHECK (gs, GIMPLE_RETURN);
- gimple_set_op (gs, 1, retval);
-}
-
-
/* Returns true when the gimple statement STMT is any of the OMP types. */
#define CASE_GIMPLE_OMP \
case GIMPLE_OMP_TASKGROUP: \
case GIMPLE_OMP_ORDERED: \
case GIMPLE_OMP_CRITICAL: \
+ case GIMPLE_OMP_SCAN: \
case GIMPLE_OMP_RETURN: \
case GIMPLE_OMP_ATOMIC_LOAD: \
case GIMPLE_OMP_ATOMIC_STORE: \
{
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
+ case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
case GF_OMP_TARGET_KIND_REGION:
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
+ case GF_OMP_TARGET_KIND_OACC_SERIAL:
return true;
default:
return false;
if (code == GIMPLE_CALL)
{
const gcall *call_stmt = as_a <const gcall *> (stmt);
- if (gimple_call_internal_p (call_stmt)
- && gimple_call_internal_fn (call_stmt) == IFN_MASK_STORE)
- return TREE_TYPE (gimple_call_arg (call_stmt, 3));
- else
- return gimple_call_return_type (call_stmt);
+ if (gimple_call_internal_p (call_stmt))
+ switch (gimple_call_internal_fn (call_stmt))
+ {
+ case IFN_MASK_STORE:
+ case IFN_SCATTER_STORE:
+ return TREE_TYPE (gimple_call_arg (call_stmt, 3));
+ case IFN_MASK_SCATTER_STORE:
+ return TREE_TYPE (gimple_call_arg (call_stmt, 4));
+ default:
+ break;
+ }
+ return gimple_call_return_type (call_stmt);
}
else if (code == GIMPLE_ASSIGN)
{
gimple_alloc_kind_all
};
-extern int gimple_alloc_counts[];
-extern int gimple_alloc_sizes[];
+extern uint64_t gimple_alloc_counts[];
+extern uint64_t gimple_alloc_sizes[];
/* Return the allocation kind for a given stmt CODE. */
static inline enum gimple_alloc_kind
gimple_set_plf (g, GF_PLF_1, true);
}
-
-/* Macros for showing usage statistics. */
-#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
- ? (x) \
- : ((x) < 1024*1024*10 \
- ? (x) / 1024 \
- : (x) / (1024*1024))))
-
-#define LABEL(x) ((x) < 1024*10 ? 'b' : ((x) < 1024*1024*10 ? 'k' : 'M'))
-
#endif /* GCC_GIMPLE_H */