Merge branch 'master' into devel/sphinx

This commit is contained in:
Martin Liska 2022-08-09 15:30:09 +02:00
commit 9fce2fbb1d
67 changed files with 1051 additions and 160 deletions

View File

@ -1,3 +1,29 @@
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
PR tree-optimization/106556
* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use the
type of the cond_expr operands being evaluted.
2022-08-08 Tom Honermann <tom@honermann.net>
* ginclude/stdatomic.h (atomic_char8_t,
ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro.
2022-08-08 Andrew Pinski <apinski@marvell.com>
PR middle-end/103645
* gimplify.cc (gimplify_init_constructor): Don't build/add
gimple assignment of an empty type.
2022-08-08 Richard Biener <rguenther@suse.de>
PR lto/106540
PR lto/106334
* dwarf2out.cc (dwarf2out_register_external_die): Restore
original assert.
* lto-streamer-in.cc (lto_read_tree_1): Use lto_input_tree_1
to input DECL_INITIAL, avoiding to commit drefs.
2022-08-07 Roger Sayle <roger@nextmovesoftware.com>
* config/i386/i386.md (*cmp<dwi>_doubleword): Change predicate

View File

@ -1 +1 @@
20220808
20220809

View File

@ -1,3 +1,17 @@
2022-08-08 Tom Honermann <tom@honermann.net>
PR preprocessor/106426
* c-opts.cc (c_common_post_options): Assign cpp_opts->unsigned_utf8char
subject to -fchar8_t, -fsigned-char, and/or -funsigned-char.
2022-08-08 Tom Honermann <tom@honermann.net>
* c-lex.cc (lex_string, lex_charconst): Use char8_t as the type
of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is
enabled.
* c-opts.cc (c_common_post_options): Set flag_char8_t if
targeting C2x.
2022-07-31 Lewis Hyatt <lhyatt@gmail.com>
PR c++/66290

View File

@ -1352,7 +1352,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
default:
case CPP_STRING:
case CPP_UTF8STRING:
value = build_string (1, "");
if (type == CPP_UTF8STRING && flag_char8_t)
{
value = build_string (TYPE_PRECISION (char8_type_node)
/ TYPE_PRECISION (char_type_node),
""); /* char8_t is 8 bits */
}
else
value = build_string (1, "");
break;
case CPP_STRING16:
value = build_string (TYPE_PRECISION (char16_type_node)
@ -1425,9 +1432,7 @@ lex_charconst (const cpp_token *token)
type = char16_type_node;
else if (token->type == CPP_UTF8CHAR)
{
if (!c_dialect_cxx ())
type = unsigned_char_type_node;
else if (flag_char8_t)
if (flag_char8_t)
type = char8_type_node;
else
type = char_type_node;

View File

@ -1059,9 +1059,10 @@ c_common_post_options (const char **pfilename)
if (flag_sized_deallocation == -1)
flag_sized_deallocation = (cxx_dialect >= cxx14);
/* char8_t support is new in C++20. */
/* char8_t support is implicitly enabled in C++20 and C2X. */
if (flag_char8_t == -1)
flag_char8_t = (cxx_dialect >= cxx20);
flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x;
cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char;
if (flag_extern_tls_init)
{

View File

@ -1,3 +1,11 @@
2022-08-08 Tom Honermann <tom@honermann.net>
* c-parser.cc (c_parser_string_literal): Use char8_t as the type
of CPP_UTF8STRING when char8_t support is enabled.
* c-typeck.cc (digest_init): Allow initialization of an array
of character type by a string literal with type array of
char8_t.
2022-08-01 David Malcolm <dmalcolm@redhat.com>
* c-typeck.cc (build_c_cast): Quote names of address spaces in

View File

@ -7447,7 +7447,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
default:
case CPP_STRING:
case CPP_UTF8STRING:
value = build_string (1, "");
if (type == CPP_UTF8STRING && flag_char8_t)
{
value = build_string (TYPE_PRECISION (char8_type_node)
/ TYPE_PRECISION (char_type_node),
""); /* char8_t is 8 bits */
}
else
value = build_string (1, "");
break;
case CPP_STRING16:
value = build_string (TYPE_PRECISION (char16_type_node)
@ -7472,9 +7479,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
{
default:
case CPP_STRING:
case CPP_UTF8STRING:
TREE_TYPE (value) = char_array_type_node;
break;
case CPP_UTF8STRING:
if (flag_char8_t)
TREE_TYPE (value) = char8_array_type_node;
else
TREE_TYPE (value) = char_array_type_node;
break;
case CPP_STRING16:
TREE_TYPE (value) = char16_array_type_node;
break;

View File

@ -8056,7 +8056,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
if (char_array)
{
if (typ2 != char_type_node)
if (typ2 != char_type_node && typ2 != char8_type_node)
incompat_string_cst = true;
}
else if (!comptypes (typ1, typ2))

View File

@ -2284,7 +2284,7 @@ gcn_function_value (const_tree valtype, const_tree, bool)
&& GET_MODE_SIZE (mode) < 4)
mode = SImode;
return gen_rtx_REG (mode, SGPR_REGNO (RETURN_VALUE_REG));
return gen_rtx_REG (mode, RETURN_VALUE_REG);
}
/* Implement TARGET_FUNCTION_VALUE_REGNO_P.
@ -2308,7 +2308,9 @@ num_arg_regs (const function_arg_info &arg)
return 0;
int size = arg.promoted_size_in_bytes ();
return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode)
? GET_MODE_NUNITS (arg.mode) : 1);
return (size + regsize - 1) / regsize;
}
/* Implement TARGET_STRICT_ARGUMENT_NAMING.
@ -2358,16 +2360,16 @@ gcn_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
if (targetm.calls.must_pass_in_stack (arg))
return 0;
/* Vector parameters are not supported yet. */
if (VECTOR_MODE_P (arg.mode))
return 0;
int reg_num = FIRST_PARM_REG + cum->num;
int first_reg = (VECTOR_MODE_P (arg.mode)
? FIRST_VPARM_REG : FIRST_PARM_REG);
int cum_num = (VECTOR_MODE_P (arg.mode)
? cum->vnum : cum->num);
int reg_num = first_reg + cum_num;
int num_regs = num_arg_regs (arg);
if (num_regs > 0)
while (reg_num % num_regs != 0)
reg_num++;
if (reg_num + num_regs <= FIRST_PARM_REG + NUM_PARM_REGS)
if (reg_num + num_regs <= first_reg + NUM_PARM_REGS)
return gen_rtx_REG (arg.mode, reg_num);
}
else
@ -2419,11 +2421,15 @@ gcn_function_arg_advance (cumulative_args_t cum_v,
if (!arg.named)
return;
int first_reg = (VECTOR_MODE_P (arg.mode)
? FIRST_VPARM_REG : FIRST_PARM_REG);
int *cum_num = (VECTOR_MODE_P (arg.mode)
? &cum->vnum : &cum->num);
int num_regs = num_arg_regs (arg);
if (num_regs > 0)
while ((FIRST_PARM_REG + cum->num) % num_regs != 0)
cum->num++;
cum->num += num_regs;
while ((first_reg + *cum_num) % num_regs != 0)
(*cum_num)++;
*cum_num += num_regs;
}
else
{
@ -2454,14 +2460,18 @@ gcn_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
if (targetm.calls.must_pass_in_stack (arg))
return 0;
if (cum->num >= NUM_PARM_REGS)
int cum_num = (VECTOR_MODE_P (arg.mode) ? cum->vnum : cum->num);
int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode)
? GET_MODE_NUNITS (arg.mode) : 1);
if (cum_num >= NUM_PARM_REGS)
return 0;
/* If the argument fits entirely in registers, return 0. */
if (cum->num + num_arg_regs (arg) <= NUM_PARM_REGS)
if (cum_num + num_arg_regs (arg) <= NUM_PARM_REGS)
return 0;
return (NUM_PARM_REGS - cum->num) * UNITS_PER_WORD;
return (NUM_PARM_REGS - cum_num) * regsize;
}
/* A normal function which takes a pointer argument (to a scalar) may be
@ -2549,14 +2559,11 @@ gcn_return_in_memory (const_tree type, const_tree ARG_UNUSED (fntype))
if (AGGREGATE_TYPE_P (type))
return true;
/* Vector return values are not supported yet. */
if (VECTOR_TYPE_P (type))
return true;
if (mode == BLKmode)
return true;
if (size > 2 * UNITS_PER_WORD)
if ((!VECTOR_TYPE_P (type) && size > 2 * UNITS_PER_WORD)
|| size > 2 * UNITS_PER_WORD * 64)
return true;
return false;
@ -3199,9 +3206,10 @@ gcn_expand_epilogue (void)
emit_move_insn (kernarg_reg, retptr_mem);
rtx retval_mem = gen_rtx_MEM (SImode, kernarg_reg);
rtx scalar_retval = gen_rtx_REG (SImode, FIRST_PARM_REG);
set_mem_addr_space (retval_mem, ADDR_SPACE_SCALAR_FLAT);
emit_move_insn (retval_mem,
gen_rtx_REG (SImode, SGPR_REGNO (RETURN_VALUE_REG)));
emit_move_insn (scalar_retval, gen_rtx_REG (SImode, RETURN_VALUE_REG));
emit_move_insn (retval_mem, scalar_retval);
}
emit_jump_insn (gen_gcn_return ());

View File

@ -138,7 +138,7 @@
#define LINK_REGNUM 18
#define EXEC_SAVE_REG 20
#define CC_SAVE_REG 22
#define RETURN_VALUE_REG 24 /* Must be divisible by 4. */
#define RETURN_VALUE_REG 168 /* Must be divisible by 4. */
#define STATIC_CHAIN_REGNUM 30
#define WORK_ITEM_ID_Z_REG 162
#define SOFT_ARG_REG 416
@ -146,7 +146,8 @@
#define DWARF_LINK_REGISTER 420
#define FIRST_PSEUDO_REGISTER 421
#define FIRST_PARM_REG 24
#define FIRST_PARM_REG (FIRST_SGPR_REG + 24)
#define FIRST_VPARM_REG (FIRST_VGPR_REG + 8)
#define NUM_PARM_REGS 6
/* There is no arg pointer. Just choose random fixed register that does
@ -164,7 +165,8 @@
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define CC_REGNO_P(X) ((X) == SCC_REG || (X) == VCC_REG)
#define FUNCTION_ARG_REGNO_P(N) \
((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS))
(((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS)) \
|| ((N) >= FIRST_VPARM_REG && (N) < (FIRST_VPARM_REG + NUM_PARM_REGS)))
#define FIXED_REGISTERS { \
@ -550,6 +552,7 @@ typedef struct gcn_args
tree fntype;
struct gcn_kernel_args args;
int num;
int vnum;
int offset;
int alignment;
} CUMULATIVE_ARGS;
@ -653,7 +656,7 @@ enum gcn_builtin_codes
}
/* This needs to match gcn_function_value. */
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG))
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RETURN_VALUE_REG)
/* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)

View File

@ -908,11 +908,11 @@
{})
(define_insn "gcn_call_value"
[(set (match_operand 0 "register_operand" "=Sg,Sg")
(call (mem (match_operand 1 "immediate_operand" "Y,B"))
[(set (match_operand 0 "register_operand" "=Sgv,Sgv")
(call (mem (match_operand 1 "immediate_operand" " Y, B"))
(match_operand 2 "const_int_operand")))
(clobber (reg:DI LR_REGNUM))
(clobber (match_scratch:DI 3 "=&Sg,X"))]
(clobber (match_scratch:DI 3 "=&Sg, X"))]
""
"@
s_getpc_b64\t%3\;s_add_u32\t%L3, %L3, %1@rel32@lo+4\;s_addc_u32\t%H3, %H3, %1@rel32@hi+4\;s_swappc_b64\ts[18:19], %3
@ -921,11 +921,11 @@
(set_attr "length" "24")])
(define_insn "gcn_call_value_indirect"
[(set (match_operand 0 "register_operand" "=Sg")
(call (mem (match_operand:DI 1 "register_operand" "Sg"))
[(set (match_operand 0 "register_operand" "=Sgv")
(call (mem (match_operand:DI 1 "register_operand" " Sg"))
(match_operand 2 "" "")))
(clobber (reg:DI LR_REGNUM))
(clobber (match_scratch:DI 3 "=X"))]
(clobber (match_scratch:DI 3 "= X"))]
""
"s_swappc_b64\ts[18:19], %1"
[(set_attr "type" "sop1")

View File

@ -1,3 +1,8 @@
2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/106555
* d-target.cc (Target::isReturnOnStack): Check for return type size.
2022-08-03 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd d7772a2369.

View File

@ -464,6 +464,8 @@ Target::isReturnOnStack (TypeFunction *tf, bool)
return false;
Type *tn = tf->next->toBasetype ();
if (tn->size () == SIZE_INVALID)
return false;
return (tn->ty == TY::Tstruct || tn->ty == TY::Tsarray);
}

View File

@ -828,6 +828,10 @@ public:
if (global.errors)
return;
/* Start generating code for this function. */
gcc_assert (d->semanticRun == PASS::semantic3done);
d->semanticRun = PASS::obj;
/* Duplicated FuncDeclarations map to the same symbol. Check if this
is the one declaration which will be emitted. */
tree fndecl = get_symbol_decl (d);
@ -844,10 +848,6 @@ public:
if (global.params.verbose)
message ("function %s", d->toPrettyChars ());
/* Start generating code for this function. */
gcc_assert (d->semanticRun == PASS::semantic3done);
d->semanticRun = PASS::obj;
tree old_context = start_function (d);
tree parm_decl = NULL_TREE;
@ -1020,13 +1020,103 @@ build_decl_tree (Dsymbol *d)
input_location = saved_location;
}
/* Returns true if function FD is defined or instantiated in a root module. */
static bool
function_defined_in_root_p (FuncDeclaration *fd)
{
Module *md = fd->getModule ();
if (md && md->isRoot ())
return true;
TemplateInstance *ti = fd->isInstantiated ();
if (ti && ti->minst && ti->minst->isRoot ())
return true;
return false;
}
/* Returns true if function FD always needs to be implicitly defined, such as
it was declared `pragma(inline)'. */
static bool
function_needs_inline_definition_p (FuncDeclaration *fd)
{
/* Function has already been defined. */
if (!DECL_EXTERNAL (fd->csym))
return false;
/* Non-inlineable functions are always external. */
if (DECL_UNINLINABLE (fd->csym))
return false;
/* No function body available for inlining. */
if (!fd->fbody)
return false;
/* Ignore functions that aren't decorated with `pragma(inline)'. */
if (fd->inlining != PINLINE::always)
return false;
/* These functions are tied to the module they are defined in. */
if (fd->isFuncLiteralDeclaration ()
|| fd->isUnitTestDeclaration ()
|| fd->isFuncAliasDeclaration ()
|| fd->isInvariantDeclaration ())
return false;
/* Check whether function will be regularly defined later in the current
translation unit. */
if (function_defined_in_root_p (fd))
return false;
/* Weak functions cannot be inlined. */
if (lookup_attribute ("weak", DECL_ATTRIBUTES (fd->csym)))
return false;
/* Naked functions cannot be inlined. */
if (lookup_attribute ("naked", DECL_ATTRIBUTES (fd->csym)))
return false;
return true;
}
/* If the variable or function declaration in DECL needs to be defined, call
build_decl_tree on it now before returning its back-end symbol. */
static tree
maybe_build_decl_tree (Declaration *decl)
{
gcc_assert (decl->csym != NULL_TREE);
/* Still running semantic analysis on declaration, or it has already had its
code generated. */
if (doing_semantic_analysis_p || decl->semanticRun >= PASS::obj)
return decl->csym;
if (error_operand_p (decl->csym))
return decl->csym;
if (FuncDeclaration *fd = decl->isFuncDeclaration ())
{
/* Externally defined inline functions need to be emitted. */
if (function_needs_inline_definition_p (fd))
{
DECL_EXTERNAL (fd->csym) = 0;
build_decl_tree (fd);
}
}
return decl->csym;
}
/* Return the decl for the symbol, create it if it doesn't already exist. */
tree
get_symbol_decl (Declaration *decl)
{
if (decl->csym)
return decl->csym;
return maybe_build_decl_tree (decl);
/* Deal with placeholder symbols immediately:
SymbolDeclaration is used as a shell around an initializer symbol. */
@ -1404,7 +1494,7 @@ get_symbol_decl (Declaration *decl)
TREE_USED (decl->csym) = 1;
d_keep (decl->csym);
return decl->csym;
return maybe_build_decl_tree (decl);
}
/* Returns a declaration for a VAR_DECL. Used to create compiler-generated
@ -1895,15 +1985,8 @@ start_function (FuncDeclaration *fd)
/* Function has been defined, check now whether we intend to send it to
object file, or it really is extern. Such as inlinable functions from
modules not in this compilation, or thunk aliases. */
TemplateInstance *ti = fd->isInstantiated ();
if (ti && ti->needsCodegen ())
if (function_defined_in_root_p (fd))
DECL_EXTERNAL (fndecl) = 0;
else
{
Module *md = fd->getModule ();
if (md && md->isRoot ())
DECL_EXTERNAL (fndecl) = 0;
}
DECL_INITIAL (fndecl) = error_mark_node;
@ -2422,16 +2505,16 @@ set_linkage_for_decl (tree decl)
if (!TREE_PUBLIC (decl))
return;
/* Don't need to give private or protected symbols a special linkage. */
if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl))
&& !DECL_INSTANTIATED (decl))
return;
/* Functions declared as `pragma(inline, true)' can appear in multiple
translation units. */
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return d_comdat_linkage (decl);
/* Don't need to give private or protected symbols a special linkage. */
if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl))
&& !DECL_INSTANTIATED (decl))
return;
/* If all instantiations must go in COMDAT, give them that linkage.
This also applies to other extern declarations, so that it is possible
for them to override template declarations. */

View File

@ -14717,6 +14717,13 @@ optimizing.
Maximum number of statements allowed in a block that needs to be
duplicated when threading jumps.
@item max-jump-thread-paths
The maximum number of paths to consider when searching for jump threading
opportunities. When arriving at a block incoming edges are only considered
if the number of paths to be searched sofar multiplied by the incoming
edge degree does not exhaust the specified maximum number of paths to
consider.
@item max-fields-for-field-sensitive
Maximum number of fields in a structure treated in
a field sensitive manner during pointer analysis.
@ -15218,9 +15225,6 @@ Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit().
Maximum number of instructions to copy when duplicating blocks on a
finite state automaton jump thread path.
@item max-fsm-thread-length
Maximum number of basic blocks on a jump thread path.
@item threader-debug
threader-debug=[none|all] Enables verbose dumping of the threader solver.

View File

@ -6069,12 +6069,7 @@ dwarf2out_register_external_die (tree decl, const char *sym,
if (!external_die_map)
external_die_map = hash_map<tree, sym_off_pair>::create_ggc (1000);
/* When we do tree merging during WPA or with -flto-partition=none we
can end up re-using GC memory as there's currently no way to unregister
external DIEs. Ideally we'd register them only after merging finished
but allowing override here is easiest. See PR106334. */
gcc_checking_assert (!(in_lto_p && !flag_wpa)
|| !external_die_map->get (decl));
gcc_checking_assert (!external_die_map->get (decl));
sym_off_pair p = { IDENTIFIER_POINTER (get_identifier (sym)), off };
external_die_map->put (decl, p);
}

View File

@ -1398,16 +1398,17 @@ gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
}
// Now solve for SSA1 or SSA2 if they are in the dependency chain.
Value_Range tmp (type);
if (ssa1 && in_chain_p (ssa1, cond_name))
{
if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src))
r1.intersect (tmp);
Value_Range tmp1 (TREE_TYPE (ssa1));
if (compute_operand_range (tmp1, def_stmt, cond_true, ssa1, src))
r1.intersect (tmp1);
}
if (ssa2 && in_chain_p (ssa2, cond_name))
{
if (compute_operand_range (tmp, def_stmt, cond_false, ssa2, src))
r2.intersect (tmp);
Value_Range tmp2 (TREE_TYPE (ssa2));
if (compute_operand_range (tmp2, def_stmt, cond_false, ssa2, src))
r2.intersect (tmp2);
}
if (idx)
{

View File

@ -5488,8 +5488,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
if (ret == GS_ERROR)
return GS_ERROR;
/* If we have gimplified both sides of the initializer but have
not emitted an assignment, do so now. */
if (*expr_p)
not emitted an assignment, do so now. */
if (*expr_p
/* If the type is an empty type, we don't need to emit the
assignment. */
&& !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
{
tree lhs = TREE_OPERAND (*expr_p, 0);
tree rhs = TREE_OPERAND (*expr_p, 1);

View File

@ -49,6 +49,9 @@ typedef _Atomic long atomic_long;
typedef _Atomic unsigned long atomic_ulong;
typedef _Atomic long long atomic_llong;
typedef _Atomic unsigned long long atomic_ullong;
#ifdef __CHAR8_TYPE__
typedef _Atomic __CHAR8_TYPE__ atomic_char8_t;
#endif
typedef _Atomic __CHAR16_TYPE__ atomic_char16_t;
typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
@ -97,6 +100,9 @@ extern void atomic_signal_fence (memory_order);
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#ifdef __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#endif
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE

View File

@ -1699,11 +1699,14 @@ lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr)
/* Read all the pointer fields in EXPR. */
streamer_read_tree_body (ib, data_in, expr);
/* Read any LTO-specific data not read by the tree streamer. */
/* Read any LTO-specific data not read by the tree streamer. Do not use
stream_read_tree here since that flushes the dref_queue in mids of
SCC reading. */
if (DECL_P (expr)
&& TREE_CODE (expr) != FUNCTION_DECL
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
DECL_INITIAL (expr) = stream_read_tree (ib, data_in);
DECL_INITIAL (expr)
= lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0);
/* Stream references to early generated DIEs. Keep in sync with the
trees handled in dwarf2out_register_external_die. */

View File

@ -8617,7 +8617,7 @@ expand_omp_atomic_load (basic_block load_bb, tree addr,
basic_block store_bb;
location_t loc;
gimple *stmt;
tree decl, call, type, itype;
tree decl, type, itype;
gsi = gsi_last_nondebug_bb (load_bb);
stmt = gsi_stmt (gsi);
@ -8637,23 +8637,33 @@ expand_omp_atomic_load (basic_block load_bb, tree addr,
itype = TREE_TYPE (TREE_TYPE (decl));
enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt);
tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo));
call = build_call_expr_loc (loc, decl, 2, addr, mo);
tree mo = build_int_cst (integer_type_node,
omp_memory_order_to_memmodel (omo));
gcall *call = gimple_build_call (decl, 2, addr, mo);
gimple_set_location (call, loc);
gimple_set_vuse (call, gimple_vuse (stmt));
gimple *repl;
if (!useless_type_conversion_p (type, itype))
call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
gsi_remove (&gsi, true);
{
tree lhs = make_ssa_name (itype);
gimple_call_set_lhs (call, lhs);
gsi_insert_before (&gsi, call, GSI_SAME_STMT);
repl = gimple_build_assign (loaded_val,
build1 (VIEW_CONVERT_EXPR, type, lhs));
gimple_set_location (repl, loc);
}
else
{
gimple_call_set_lhs (call, loaded_val);
repl = call;
}
gsi_replace (&gsi, repl, true);
store_bb = single_succ (load_bb);
gsi = gsi_last_nondebug_bb (store_bb);
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
gsi_remove (&gsi, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
return true;
}
@ -8669,7 +8679,7 @@ expand_omp_atomic_store (basic_block load_bb, tree addr,
basic_block store_bb = single_succ (load_bb);
location_t loc;
gimple *stmt;
tree decl, call, type, itype;
tree decl, type, itype;
machine_mode imode;
bool exchange;
@ -8710,25 +8720,36 @@ expand_omp_atomic_store (basic_block load_bb, tree addr,
if (!useless_type_conversion_p (itype, type))
stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt);
tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo));
call = build_call_expr_loc (loc, decl, 3, addr, stored_val, mo);
tree mo = build_int_cst (integer_type_node,
omp_memory_order_to_memmodel (omo));
stored_val = force_gimple_operand_gsi (&gsi, stored_val, true, NULL_TREE,
true, GSI_SAME_STMT);
gcall *call = gimple_build_call (decl, 3, addr, stored_val, mo);
gimple_set_location (call, loc);
gimple_set_vuse (call, gimple_vuse (stmt));
gimple_set_vdef (call, gimple_vdef (stmt));
gimple *repl = call;
if (exchange)
{
if (!useless_type_conversion_p (type, itype))
call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
{
tree lhs = make_ssa_name (itype);
gimple_call_set_lhs (call, lhs);
gsi_insert_before (&gsi, call, GSI_SAME_STMT);
repl = gimple_build_assign (loaded_val,
build1 (VIEW_CONVERT_EXPR, type, lhs));
gimple_set_location (repl, loc);
}
else
gimple_call_set_lhs (call, loaded_val);
}
force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
gsi_remove (&gsi, true);
gsi_replace (&gsi, repl, true);
/* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
gsi = gsi_last_nondebug_bb (load_bb);
gsi_remove (&gsi, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
return true;
}
@ -8874,10 +8895,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
gsi_remove (&gsi, true);
if (gimple_in_ssa_p (cfun))
{
release_defs (stmt);
update_ssa (TODO_update_ssa_no_phi);
}
release_defs (stmt);
return true;
}
@ -9333,16 +9351,16 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
}
/* Remove GIMPLE_OMP_ATOMIC_STORE. */
stmt = gsi_stmt (si);
gsi_remove (&si, true);
if (gimple_in_ssa_p (cfun))
release_defs (stmt);
class loop *loop = alloc_loop ();
loop->header = loop_header;
loop->latch = store_bb;
add_loop (loop, loop_header->loop_father);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
return true;
}
@ -9399,15 +9417,14 @@ expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
stmt = gimple_build_assign (unshare_expr (mem), stored_val);
gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (si)));
gimple_set_vdef (stmt, gimple_vdef (gsi_stmt (si)));
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
t = build_call_expr (t, 0);
force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
gsi_remove (&si, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
return true;
}

View File

@ -6241,10 +6241,10 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
if (POINTER_TYPE_P (TREE_TYPE (x)))
x = fold_build2 (POINTER_PLUS_EXPR,
TREE_TYPE (x), x, t);
x = fold_build_pointer_plus (x, t);
else
x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x,
fold_convert (TREE_TYPE (x), t));
}
if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR

View File

@ -498,10 +498,6 @@ The maximum number of nested indirect inlining performed by early inliner.
Common Joined UInteger Var(param_max_fields_for_field_sensitive) Param
Maximum number of fields in a structure before pointer analysis treats the structure as a single variable.
-param=max-fsm-thread-length=
Common Joined UInteger Var(param_max_fsm_thread_length) Init(10) IntegerRange(1, 999999) Param Optimization
Maximum number of basic blocks on a jump thread path.
-param=max-fsm-thread-path-insns=
Common Joined UInteger Var(param_max_fsm_thread_path_insns) Init(100) IntegerRange(1, 999999) Param Optimization
Maximum number of instructions to copy when duplicating blocks on a finite state automaton jump thread path.
@ -582,6 +578,10 @@ Bound on the number of iterations the brute force # of iterations analysis algor
Common Joined UInteger Var(param_max_jump_thread_duplication_stmts) Init(15) Param Optimization
Maximum number of statements allowed in a block that needs to be duplicated when threading jumps.
-param=max-jump-thread-paths=
Common Joined UInteger Var(param_max_jump_thread_paths) Init(64) IntegerRange(1, 65536) Param Optimization
Search space limit for the backwards jump threader.
-param=max-last-value-rtl=
Common Joined UInteger Var(param_max_last_value_rtl) Init(10000) Param Optimization
The maximum number of RTL nodes that can be recorded as combiner's last value.

View File

@ -1,3 +1,40 @@
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
PR tree-optimization/106556
* gfortran.dg/pr106556.f90: New.
2022-08-08 Tom Honermann <tom@honermann.net>
PR preprocessor/106426
* g++.dg/ext/char8_t-char-literal-1.C: Check signedness of u8 literals.
* g++.dg/ext/char8_t-char-literal-2.C: Check signedness of u8 literals.
2022-08-08 Tom Honermann <tom@honermann.net>
* gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c: New test.
* gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c: New test.
* gcc.dg/c11-utf8str-type.c: New test.
* gcc.dg/c17-utf8str-type.c: New test.
* gcc.dg/c2x-utf8str-type.c: New test.
* gcc.dg/c2x-utf8str.c: New test.
* gcc.dg/gnu2x-utf8str-type.c: New test.
* gcc.dg/gnu2x-utf8str.c: New test.
2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/106555
* gdc.dg/imports/pr106555.d: New test.
* gdc.dg/pr106555.d: New test.
2022-08-08 Andrew Pinski <apinski@marvell.com>
* gcc.dg/pr87052.c: Update d var to expect nothing.
2022-08-08 Andrew Pinski <apinski@marvell.com>
* gcc.dg/tree-ssa/pr93776.c: Moved to...
* gcc.c-torture/compile/pr93776.c: ...here.
2022-08-07 Roger Sayle <roger@nextmovesoftware.com>
* gcc.target/i386/cmpti2.c: Add -mno-stv to dg-options.

View File

@ -1,6 +1,6 @@
// Test that UTF-8 character literals have type char if -fchar8_t is not enabled.
// { dg-do compile }
// { dg-options "-std=c++17 -fno-char8_t" }
// { dg-options "-std=c++17 -fsigned-char -fno-char8_t" }
template<typename T1, typename T2>
struct is_same
@ -10,3 +10,7 @@ template<typename T>
{ static const bool value = true; };
static_assert(is_same<decltype(u8'x'), char>::value, "Error");
#if u8'\0' - 1 > 0
#error "UTF-8 character literals not signed in preprocessor"
#endif

View File

@ -10,3 +10,7 @@ template<typename T>
{ static const bool value = true; };
static_assert(is_same<decltype(u8'x'), char8_t>::value, "Error");
#if u8'\0' - 1 < 0
#error "UTF-8 character literals not unsigned in preprocessor"
#endif

View File

@ -0,0 +1,49 @@
/* PR middle-end/106492 */
template <typename T>
struct S {
T a : 12;
S () : a(0)
{
#pragma omp for simd linear(a)
for (int k = 0; k < 64; ++k)
a++;
}
};
struct U {
int a : 12;
U () : a(0)
{
#pragma omp for simd linear(a)
for (int k = 0; k < 64; ++k)
a++;
}
};
S<int> s;
U u;
template <typename T>
struct Sptr {
T a;
Sptr (T init) : a(init)
{
#pragma omp for simd linear(a)
for (int k = 0; k < 64; ++k)
a++;
}
};
struct Uptr {
int *a;
Uptr (int *init) : a(init)
{
#pragma omp for simd linear(a)
for (int k = 0; k < 64; ++k)
a++;
}
};
int i[1024];
Sptr<int *> sptr(i);
Uptr uptr(&i[100]);

View File

@ -0,0 +1,42 @@
/* Test atomic_is_lock_free for char8_t. */
/* { dg-do run } */
/* { dg-options "-std=c2x -pedantic-errors" } */
#include <stdatomic.h>
#include <stdint.h>
extern void abort (void);
_Atomic __CHAR8_TYPE__ ac8a;
atomic_char8_t ac8t;
#define CHECK_TYPE(MACRO, V1, V2) \
do \
{ \
int r1 = MACRO; \
int r2 = atomic_is_lock_free (&V1); \
int r3 = atomic_is_lock_free (&V2); \
if (r1 != 0 && r1 != 1 && r1 != 2) \
abort (); \
if (r2 != 0 && r2 != 1) \
abort (); \
if (r3 != 0 && r3 != 1) \
abort (); \
if (r1 == 2 && r2 != 1) \
abort (); \
if (r1 == 2 && r3 != 1) \
abort (); \
if (r1 == 0 && r2 != 0) \
abort (); \
if (r1 == 0 && r3 != 0) \
abort (); \
} \
while (0)
int
main ()
{
CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t);
return 0;
}

View File

@ -0,0 +1,5 @@
/* Test atomic_is_lock_free for char8_t with -std=gnu2x. */
/* { dg-do run } */
/* { dg-options "-std=gnu2x -pedantic-errors" } */
#include "c2x-stdatomic-lockfree-char8_t.c"

View File

@ -0,0 +1,6 @@
/* Test C11 UTF-8 string literal type. */
/* { dg-do compile } */
/* { dg-options "-std=c11" } */
_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");

View File

@ -0,0 +1,6 @@
/* Test C17 UTF-8 string literal type. */
/* { dg-do compile } */
/* { dg-options "-std=c17" } */
_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");

View File

@ -0,0 +1,6 @@
/* Test C2X UTF-8 string literal type. */
/* { dg-do compile } */
/* { dg-options "-std=c2x" } */
_Static_assert (_Generic (u8"text", unsigned char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type");
_Static_assert (_Generic (u8"x"[0], unsigned char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type");

View File

@ -0,0 +1,34 @@
/* Test initialization by UTF-8 string literal in C2X. */
/* { dg-do compile } */
/* { dg-require-effective-target wchar } */
/* { dg-options "-std=c2x" } */
typedef __CHAR8_TYPE__ char8_t;
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
typedef __WCHAR_TYPE__ wchar_t;
/* Test that char, signed char, unsigned char, and char8_t arrays can be
initialized by a UTF-8 string literal. */
const char cbuf1[] = u8"text";
const char cbuf2[] = { u8"text" };
const signed char scbuf1[] = u8"text";
const signed char scbuf2[] = { u8"text" };
const unsigned char ucbuf1[] = u8"text";
const unsigned char ucbuf2[] = { u8"text" };
const char8_t c8buf1[] = u8"text";
const char8_t c8buf2[] = { u8"text" };
/* Test that a diagnostic is issued for attempted initialization of
other character types by a UTF-8 string literal. */
const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
/* Test that char8_t arrays can be initialized by an ordinary string
literal. */
const char8_t c8buf3[] = "text";
const char8_t c8buf4[] = { "text" };

View File

@ -0,0 +1,5 @@
/* Test C2X UTF-8 string literal type with -std=gnu2x. */
/* { dg-do compile } */
/* { dg-options "-std=gnu2x" } */
#include "c2x-utf8str-type.c"

View File

@ -0,0 +1,34 @@
/* Test initialization by UTF-8 string literal in C2X with -std=gnu2x. */
/* { dg-do compile } */
/* { dg-require-effective-target wchar } */
/* { dg-options "-std=gnu2x" } */
typedef __CHAR8_TYPE__ char8_t;
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
typedef __WCHAR_TYPE__ wchar_t;
/* Test that char, signed char, unsigned char, and char8_t arrays can be
initialized by a UTF-8 string literal. */
const char cbuf1[] = u8"text";
const char cbuf2[] = { u8"text" };
const signed char scbuf1[] = u8"text";
const signed char scbuf2[] = { u8"text" };
const unsigned char ucbuf1[] = u8"text";
const unsigned char ucbuf2[] = { u8"text" };
const char8_t c8buf1[] = u8"text";
const char8_t c8buf2[] = { u8"text" };
/* Test that a diagnostic is issued for attempted initialization of
other character types by a UTF-8 string literal. */
const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */
const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */
/* Test that char8_t arrays can be initialized by an ordinary string
literal. */
const char8_t c8buf3[] = "text";
const char8_t c8buf4[] = { "text" };

View File

@ -23,8 +23,7 @@ void test (void)
const char d[0] = { };
/* Expect the following:
d = ""; */
/* Expect nothing. */
const char e[0] = "";
@ -36,6 +35,7 @@ void test (void)
/* { dg-final { scan-tree-dump-times "a = \"\\\\x00ab\";" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "b = \"a\\\\x00bc\";" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "c = \"\";" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "d = { *};" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "d = " 1 "gimple" } }
{ dg-final { scan-tree-dump-times "d = {CLOBBER\\(eol\\)}" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "e = " 1 "gimple" } }
{ dg-final { scan-tree-dump-times "e = {CLOBBER\\(eol\\)}" 1 "gimple" } } */

View File

@ -11,7 +11,7 @@
to change decisions in switch expansion which in turn can expose new
jump threading opportunities. Skip the later tests on aarch64. */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 9" "thread2" { target { ! aarch64*-*-* } } } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread2" { target { aarch64*-*-* } } } } */
enum STATE {

View File

@ -0,0 +1,24 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-threadfull1-details" } */
int res;
void foo (int a, int b, int c, int d, int e)
{
if (a > 100)
res = 3;
if (b != 5)
res = 5;
if (c == 29)
res = 7;
if (d < 2)
res = 9;
/* Accounting whoes makes this not catched. */
#if 0
if (e != 37)
res = 11;
#endif
if (a < 10)
res = 13;
}
/* { dg-final { scan-tree-dump "SUCCESS" "threadfull1" } } */

View File

@ -0,0 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-threadfull1-details --param max-jump-thread-paths=15" } */
#include "ssa-thread-16.c"
/* With limiting the search space we should no longer consider this path. */
/* { dg-final { scan-tree-dump-not "SUCCESS" "threadfull1" } } */

View File

@ -0,0 +1,10 @@
module imports.pr106555;
struct S106555
{
int[] f106555;
int max106555;
this(int)
{
f106555.length = max106555;
}
}

View File

@ -0,0 +1,4 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106555
// { dg-do compile }
// { dg-additional-options "-O2" }
// { dg-additional-sources "imports/pr106555.d" }

View File

@ -0,0 +1,12 @@
module imports.pr106563math;
T nextPow2(T)(const T val)
{
return powIntegralImpl(val);
}
pragma(inline, true)
T powIntegralImpl(T)(T)
{
return 1;
}

View File

@ -0,0 +1,7 @@
module imports.pr106563regex;
import imports.pr106563uni;
struct CharMatcher
{
typeof(MultiArray!().length) trie;
}

View File

@ -0,0 +1,15 @@
module imports.pr106563uni;
struct MultiArray()
{
@property length()
{
return spaceFor!0();
}
}
size_t spaceFor(size_t bits)()
{
import imports.pr106563math;
return nextPow2(bits);
}

View File

@ -0,0 +1,16 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106563
// { dg-do link }
// { dg-additional-files "imports/pr106563math.d imports/pr106563regex.d imports/pr106563uni.d" }
// { dg-additional-options "-I[srcdir] -fno-druntime" }
import imports.pr106563math;
import imports.pr106563regex;
auto requireSize()(size_t size)
{
return nextPow2(size);
}
extern(C) int main()
{
return cast(int)requireSize(0);
}

View File

@ -19,6 +19,15 @@
# Load support procs.
load_lib gdc-dg.exp
# Helper function allows adding tests that use imports/*, but don't compile
# the sources in with dg-additional-sources.
global testdir
set testdir $srcdir/$subdir
proc srcdir {} {
global testdir
return $testdir
}
# The default option list can be overridden by
# TORTURE_OPTIONS="{ { list1 } ... { listN } }"

View File

@ -0,0 +1,10 @@
! { dg-do compile }
! { dg-options "-O1 -fnon-call-exceptions -ftree-loop-if-convert" }
program p
real :: a(2)
a(:) = 1.0
if (minloc (a, dim = 1).ne.1) STOP 1
end

View File

@ -3082,7 +3082,7 @@ gen_parallel_loop (class loop *loop,
profile_probability::unlikely (),
profile_probability::likely (),
profile_probability::unlikely (), true);
update_ssa (TODO_update_ssa);
update_ssa (TODO_update_ssa_no_phi);
free_original_copy_tables ();
}

View File

@ -90,7 +90,7 @@ private:
bool debug_counter ();
edge maybe_register_path ();
void maybe_register_path_dump (edge taken_edge);
void find_paths_to_names (basic_block bb, bitmap imports);
void find_paths_to_names (basic_block bb, bitmap imports, unsigned);
edge find_taken_edge (const vec<basic_block> &path);
edge find_taken_edge_cond (const vec<basic_block> &path, gcond *);
edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *);
@ -337,9 +337,12 @@ back_threader::find_taken_edge_cond (const vec<basic_block> &path,
// INTERESTING bitmap, and register any such paths.
//
// BB is the current path being processed.
//
// OVERALL_PATHS is the search space up to this block
void
back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
back_threader::find_paths_to_names (basic_block bb, bitmap interesting,
unsigned overall_paths)
{
if (m_visited_bbs.add (bb))
return;
@ -352,8 +355,10 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
|| maybe_register_path ()))
;
// Continue looking for ways to extend the path
else
// Continue looking for ways to extend the path but limit the
// search space along a branch
else if ((overall_paths = overall_paths * EDGE_COUNT (bb->preds))
<= (unsigned)param_max_jump_thread_paths)
{
// For further greedy searching we want to remove interesting
// names defined in BB but add ones on the PHI edges for the
@ -407,7 +412,7 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
unwind.quick_push (def);
}
}
find_paths_to_names (e->src, new_interesting);
find_paths_to_names (e->src, new_interesting, overall_paths);
// Restore new_interesting. We leave m_imports alone since
// we do not prune defs in BB from it and separately keeping
// track of which bits to unwind isn't worth the trouble.
@ -417,6 +422,9 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
}
}
}
else if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " FAIL: Search space limit %d reached.\n",
param_max_jump_thread_paths);
// Reset things to their original state.
m_path.pop ();
@ -447,7 +455,7 @@ back_threader::find_paths (basic_block bb, tree name)
auto_bitmap interesting;
bitmap_copy (interesting, m_imports);
find_paths_to_names (bb, interesting);
find_paths_to_names (bb, interesting, 1);
}
}
@ -561,15 +569,6 @@ back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path,
if (m_path.length () <= 1)
return false;
if (m_path.length () > (unsigned) param_max_fsm_thread_length)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " FAIL: Jump-thread path not considered: "
"the number of basic blocks on the path "
"exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n");
return false;
}
int n_insns = 0;
gimple_stmt_iterator gsi;
loop_p loop = m_path[0]->loop_father;

View File

@ -1,3 +1,15 @@
2022-08-08 Tamar Christina <tamar.christina@arm.com>
PR target/102218
* config/arm/host-config.h (pre_seq_barrier, post_seq_barrier,
pre_post_seq_barrier): Require barrier on __ATOMIC_SEQ_CST.
2022-08-08 Tamar Christina <tamar.christina@arm.com>
PR target/102218
* config/aarch64/aarch64-config.h: New file.
* config/aarch64/host-config.h: New file.
2022-06-02 David Malcolm <dmalcolm@redhat.com>
* testsuite/lib/libatomic.exp: Add load_gcc_lib of scansarif.exp.

View File

@ -0,0 +1,23 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU Atomic Library (libatomic).
Libatomic 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 of the License, or
(at your option) any later version.
Libatomic 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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */

View File

@ -0,0 +1,46 @@
/* Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU Atomic Library (libatomic).
Libatomic 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 of the License, or
(at your option) any later version.
Libatomic 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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Avoiding the DMB (or kernel helper) can be a good thing. */
#define WANT_SPECIALCASE_RELAXED
/* Glibc, at least, uses acq_rel in its pthread mutex
implementation. If the user is asking for seq_cst,
this is insufficient. */
static inline void __attribute__((always_inline, artificial))
pre_seq_barrier(int model)
{
if (model == __ATOMIC_SEQ_CST)
__atomic_thread_fence (__ATOMIC_SEQ_CST);
}
static inline void __attribute__((always_inline, artificial))
post_seq_barrier(int model)
{
pre_seq_barrier(model);
}
#define pre_post_seq_barrier 1
#include_next <host-config.h>

View File

@ -1,4 +1,23 @@
/* Avoiding the DMB (or kernel helper) can be a good thing. */
#define WANT_SPECIALCASE_RELAXED
/* Glibc, at least, uses acq_rel in its pthread mutex
implementation. If the user is asking for seq_cst,
this is insufficient. */
static inline void __attribute__((always_inline, artificial))
pre_seq_barrier(int model)
{
if (model == __ATOMIC_SEQ_CST)
__atomic_thread_fence (__ATOMIC_SEQ_CST);
}
static inline void __attribute__((always_inline, artificial))
post_seq_barrier(int model)
{
pre_seq_barrier(model);
}
#define pre_post_seq_barrier 1
#include_next <host-config.h>

View File

@ -1,3 +1,11 @@
2022-08-08 Tom Honermann <tom@honermann.net>
PR preprocessor/106426
* charset.cc (narrow_str_to_charconst): Set signedness of CPP_UTF8CHAR
literals based on unsigned_utf8char.
* include/cpplib.h (cpp_options): Add unsigned_utf8char.
* init.cc (cpp_create_reader): Initialize unsigned_utf8char.
2022-07-15 Jonathan Wakely <jwakely@redhat.com>
* include/line-map.h (label_text::take_or_copy): Remove.

View File

@ -1960,8 +1960,8 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
/* Multichar constants are of type int and therefore signed. */
if (i > 1)
unsigned_p = 0;
else if (type == CPP_UTF8CHAR && !CPP_OPTION (pfile, cplusplus))
unsigned_p = 1;
else if (type == CPP_UTF8CHAR)
unsigned_p = CPP_OPTION (pfile, unsigned_utf8char);
else
unsigned_p = CPP_OPTION (pfile, unsigned_char);

View File

@ -581,8 +581,8 @@ struct cpp_options
ints and target wide characters, respectively. */
size_t precision, char_precision, int_precision, wchar_precision;
/* True means chars (wide chars) are unsigned. */
bool unsigned_char, unsigned_wchar;
/* True means chars (wide chars, UTF-8 chars) are unsigned. */
bool unsigned_char, unsigned_wchar, unsigned_utf8char;
/* True if the most significant byte in a word has the lowest
address in memory. */

View File

@ -231,6 +231,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
CPP_OPTION (pfile, unsigned_char) = 0;
CPP_OPTION (pfile, unsigned_wchar) = 1;
CPP_OPTION (pfile, unsigned_utf8char) = 1;
CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
/* Default to no charset conversion. */

View File

@ -1,3 +1,21 @@
2022-08-08 François Dumont <fdumont@gcc.gnu.org>
* include/debug/formatter.h (__singular_value_init): New _Iterator_state enum entry.
(_Parameter<>(const _Safe_iterator<>&, const char*, _Is_iterator)): Check if iterator
parameter is value-initialized.
(_Parameter<>(const _Safe_local_iterator<>&, const char*, _Is_iterator)): Likewise.
* include/debug/safe_iterator.h (_Safe_iterator<>::_M_value_initialized()): New. Adapt
checks.
* include/debug/safe_local_iterator.h (_Safe_local_iterator<>::_M_value_initialized()): New.
Adapt checks.
* src/c++11/debug.cc (_Safe_iterator_base::_M_reset): Do not reset _M_version.
(print_field(PrintContext&, const _Parameter&, const char*)): Adapt state_names.
* testsuite/23_containers/deque/debug/iterator1_neg.cc: New test.
* testsuite/23_containers/deque/debug/iterator2_neg.cc: New test.
* testsuite/23_containers/forward_list/debug/iterator1_neg.cc: New test.
* testsuite/23_containers/forward_list/debug/iterator2_neg.cc: New test.
* testsuite/23_containers/forward_list/debug/iterator3_neg.cc: New test.
2022-08-05 Jonathan Wakely <jwakely@redhat.com>
* include/experimental/scope (__cpp_lib_experimental_scope):

View File

@ -185,6 +185,7 @@ namespace __gnu_debug
__rbegin, // dereferenceable, and at the reverse-beginning
__rmiddle, // reverse-dereferenceable, not at the reverse-beginning
__rend, // reverse-past-the-end
__singular_value_init, // singular, value initialized
__last_state
};
@ -280,7 +281,12 @@ namespace __gnu_debug
_M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
if (__it._M_singular())
_M_variant._M_iterator._M_state = __singular;
{
if (__it._M_value_initialized())
_M_variant._M_iterator._M_state = __singular_value_init;
else
_M_variant._M_iterator._M_state = __singular;
}
else
{
if (__it._M_is_before_begin())
@ -308,7 +314,12 @@ namespace __gnu_debug
_M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
if (__it._M_singular())
_M_variant._M_iterator._M_state = __singular;
{
if (__it._M_value_initialized())
_M_variant._M_iterator._M_state = __singular_value_init;
else
_M_variant._M_iterator._M_state = __singular;
}
else
{
if (__it._M_is_end())

View File

@ -41,8 +41,8 @@
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
_GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \
|| (_Lhs.base() == _Iterator() \
&& _Rhs.base() == _Iterator()), \
|| (_Lhs._M_value_initialized() \
&& _Rhs._M_value_initialized()), \
_M_message(_BadMsgId) \
._M_iterator(_Lhs, #_Lhs) \
._M_iterator(_Rhs, #_Rhs)); \
@ -177,7 +177,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -193,7 +193,7 @@ namespace __gnu_debug
: _Iter_base()
{
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -220,7 +220,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _MutableIterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_const_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -236,7 +236,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -266,7 +266,7 @@ namespace __gnu_debug
operator=(_Safe_iterator&& __x) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -405,6 +405,11 @@ namespace __gnu_debug
_M_incrementable() const
{ return !this->_M_singular() && !_M_is_end(); }
/// Is the iterator value-initialized?
bool
_M_value_initialized() const
{ return _M_version == 0 && base() == _Iter_base(); }
// Can we advance the iterator @p __n steps (@p __n may be negative)
bool
_M_can_advance(difference_type __n, bool __strict = false) const;

View File

@ -33,8 +33,8 @@
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \
_GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \
|| (_Lhs.base() == _Iterator{} \
&& _Rhs.base() == _Iterator{}), \
|| (_Lhs._M_value_initialized() \
&& _Rhs._M_value_initialized()), \
_M_message(__msg_iter_compare_bad) \
._M_iterator(_Lhs, "lhs") \
._M_iterator(_Rhs, "rhs")); \
@ -127,7 +127,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -142,7 +142,7 @@ namespace __gnu_debug
: _Iter_base()
{
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -167,7 +167,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _MutableIterator(),
|| __x._M_value_initialized(),
_M_message(__msg_init_const_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -183,7 +183,7 @@ namespace __gnu_debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -212,7 +212,7 @@ namespace __gnu_debug
operator=(_Safe_local_iterator&& __x) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
|| __x.base() == _Iterator(),
|| __x._M_value_initialized(),
_M_message(__msg_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
@ -343,6 +343,11 @@ namespace __gnu_debug
_M_incrementable() const
{ return !this->_M_singular() && !_M_is_end(); }
/// Is the iterator value-initialized?
bool
_M_value_initialized() const
{ return _M_version == 0 && base() == _Iter_base{}; }
// Is the iterator range [*this, __rhs) valid?
bool
_M_valid_range(const _Safe_local_iterator& __rhs,

View File

@ -426,7 +426,9 @@ namespace __gnu_debug
_M_reset() throw ()
{
__atomic_store_n(&_M_sequence, (_Safe_sequence_base*)0, __ATOMIC_RELEASE);
_M_version = 0;
// Do not reset version, so that a detached iterator does not look like a
// value-initialized one.
// _M_version = 0;
_M_prior = 0;
_M_next = 0;
}
@ -767,7 +769,8 @@ namespace
"before-begin",
"dereferenceable (start-of-reverse-sequence)",
"dereferenceable (reverse)",
"past-the-reverse-end"
"past-the-reverse-end",
"singular (value-initialized)"
};
print_word(ctx, state_names[iterator._M_state]);
}

View File

@ -0,0 +1,37 @@
// Copyright (C) 2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library 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.
//
// This library 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 this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-do run { xfail *-*-* } }
// { dg-require-debug-mode "" }
#include <deque>
void test01()
{
typedef typename std::deque<int>::iterator It;
std::deque<int> dq;
dq.push_back(1);
It it = It();
(void)(dq.begin() != it);
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,40 @@
// Copyright (C) 2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library 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.
//
// This library 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 this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-do run { xfail *-*-* } }
// { dg-require-debug-mode "" }
#include <deque>
void test01()
{
typedef typename std::deque<int>::iterator It;
It it;
{
std::deque<int> dq;
it = dq.begin();
}
It value_init_it = It();
(void)(it != value_init_it);
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,37 @@
// Copyright (C) 2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library 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.
//
// This library 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 this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-do run { xfail *-*-* } }
// { dg-require-debug-mode "" }
#include <forward_list>
void test01()
{
typedef typename std::forward_list<int>::iterator It;
std::forward_list<int> fl;
fl.push_front(1);
It it = It();
(void)(fl.begin() != it);
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,40 @@
// Copyright (C) 2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library 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.
//
// This library 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 this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-do run { target c++11 xfail *-*-* } }
// { dg-require-debug-mode "" }
#include <forward_list>
void test01()
{
typedef typename std::forward_list<int>::iterator It;
It it;
{
std::forward_list<int> fl;
it = fl.begin();
}
It value_init_it{};
(void)(it != value_init_it);
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,45 @@
// Copyright (C) 2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library 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.
//
// This library 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 this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-do run { xfail *-*-* } }
// { dg-require-debug-mode "" }
#include <forward_list>
#include <testsuite_hooks.h>
void test01()
{
typedef typename std::forward_list<int>::iterator It;
It end1, end2;
{
std::forward_list<int> fl;
fl.push_front(1);
end1 = end2 = fl.end();
VERIFY( end1 == end2 );
}
(void)(end1 == end2);
}
int main()
{
test01();
return 0;
}