svn merge -r265930:265934 svn+ssh://gcc.gnu.org/svn/gcc/trunk

From-SVN: r265937
This commit is contained in:
Jakub Jelinek 2018-11-08 22:07:23 +01:00
parent 306e92f648
commit f2ee7edfe3
18 changed files with 1376 additions and 410 deletions

View File

@ -1,3 +1,401 @@
2018-11-08 Paul Koning <ni1d@arrl.net>
* config/pdp11/constraints.md: Add "Z" series constraints for use
with pre-dec and post-inc addressing.
* config/pdp11/pdp11-protos.m (expand_block_move): Delete.
(pdp11_expand_operands): Add int argument (word count).
(pdp11_sp_frame_offset): Delete.
(pdp11_cmp_length): New function.
(pushpop_regeq): New function.
* config/pdp11/pdp11.c (TARGET_STACK_PROTECT_RUNTIME_ENABLED_P):
Add hook.
(pdp11_expand_prologue, pdp11_expand_epilogue): Rewrite for new
frame layout.
(pdp11_initial_elimination_offset): Ditto.
(pdp11_expand_operands): Add word count argument. Bugfixes.
(output_move_multiple): Change how pointer adjustment is done.
(pdp11_gen_int_label): Correct format.
(output_ascii): Ditto.
(pdp11_asm_output_var): Add code for DEC assembler case.
(pdp11_asm_print_operand): Bugfix for CONST_DOUBLE holding integer
value.
(legitimate_const_double_p): Ditto.
(pdp11_register_move_cost): Adjust for new register classes.
(pdp11_regno_reg_class): Ditto.
(expand_block_move): Delete.
(pushpop_regeq): New function.
(pdp11_legitimate_address_p): Bugfix in check for constant
offset.
(pdp11_sp_frame_offset): Delete.
(pdp11_reg_save_size): New helper function for new frame layout.
(output_addr_const_pdp11): Remove CONST_DOUBLE case.
(pdp11_expand_shift): Bugfix in check for constant shift count.
(pdp11_shift_length): Ditto.
(pdp11_assemble_shift): Copy input to pdp11_expand_operands.
(pdp11_cmp_length): New function.
* config/pdp11/pdp11.h (TARGET_CPU_CPP_BUILTINS): Add macros for
some compile options.
(FIXED_REGISTERS): Remove HARD_FRAME_POINTER_REGNUM.
(CALL_USED_REGISTERS): Ditto.
(ELIMINABLE_REGS): Ditto.
(REGISTER_NAMES): Ditto.
(reg_class): Add classes NOTR0_REG through NOTSP_REG for use by Z
constraints.
(REG_CLASS_NAMES): Ditto.
(REG_CLASS_CONTENTS): Ditto. Also remove
HARD_FRAME_POINTER_REGNUM.
(CPU_REG_CLASS): New macro.
(CLASS_MAX_NREGS): Adjust for new register classes.
(FUNCTION_PROFILER): Make no-op.
(may_call_alloca): Remove unused declaration.
(ASM_OUTPUT_ALIGN): Add workaround for PR87795.
(ASM_OUTPUT_SKIP): Fix format.
* config/pdp11/pdp11.md (unspecv): Add UNSPECV_MOVMEM.
(HARD_FRAME_POINTER_REGNUM): Remove.
(return): Delete.
(*rts): Rename. Remove epilogue related checks.
(cmpsi, cmpdi): New insn.
(cbranch<mode>4): Change to apply to SI and DI modes as well.
(mov<mode>): Change constraints to enforce that push/pop
destination cannot use the same register as source.
(*mov<mode><cc_cc>): Ditto.
(movmemhi, movmemhi1, movmemhi_nocc): Change to expand block move
at assembly output rather than as RTL expander.
(zero_extendqihi2): Bugfix in check for same registers.
(adddi3_nocc): Bugfix in check for constant operand.
(addsi3_nocc): Ditto.
(subdi3_nocc): Ditto.
(subsi3_nocc): Ditto.
(negdi2_nocc): Copy input to pdp11_expand_operands.
(negsi2_nocc): Ditto.
(bswap2_nocc): Ditto.
* config/pdp11/pdp11.opt (mlra): Fix documentation.
* config/pdp11/t-pdp11: Use -Os.
2018-11-08 Richard Earnshaw <rearnsha@arm.com>
* config/arm/parsecpu.awk (/alias/): New parsing rule.
(/begin cpu/): Check that the cpu name hasn't been previously defined.
(gen_comm_data): Print out CPU alias tables.
(check_cpu): Match aliases when checking the CPU name.
* config/arm/arm-protos.h (cpu_alias): New structure.
(cpu_option): Add entry for aliases.
* config/arm/arm-cpus.in (strongarm): Add aliases for strongarm110
strongarm1100 and strongarm1110.
(strongarm110, strongarm1100, strongarm1110): Delete CPU entries.
(config/arm/arm-generic.md): Remove redundant references to
strongarm110, strongarm1100 and strongarm1110.
* common/config/arm/arm-common.c (arm_print_hint_for_cpu_option):
Scan aliases for additional hints.
(arm_parse_cpu_option_name): Also match a cpu name against the list
of aliases.
* config/arm/arm-tables.opt: Regenerated.
* config/arm/arm-tune.md: Regenerated.
2018-11-08 Jakub Jelinek <jakub@redhat.com>
* builtin-types.def (BT_FN_VOID_BOOL, BT_FN_VOID_SIZE_SIZE_PTR,
BT_FN_UINT_UINT_PTR_PTR, BT_FN_UINT_OMPFN_PTR_UINT_UINT,
BT_FN_BOOL_UINT_LONGPTR_LONG_LONG_LONGPTR_LONGPTR_PTR_PTR,
BT_FN_BOOL_UINT_ULLPTR_LONG_ULL_ULLPTR_ULLPTR_PTR_PTR,
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR_PTR_PTR,
BT_FN_BOOL_BOOL_ULL_ULL_ULL_LONG_ULL_ULLPTR_ULLPTR_PTR_PTR): New.
* gengtype.c (open_base_files): Add omp-general.h.
* gimple.c (gimple_build_omp_critical):
(gimple_build_omp_taskgroup): Add CLAUSES argument. Call
gimple_omp_taskgroup_set_clauses.
(gimple_build_omp_atomic_load): Add mo argument, call
gimple_omp_atomic_set_memory_order.
(gimple_build_omp_atomic_store): Likewise.
(gimple_copy): Adjust handling of GIMPLE_OMP_TASKGROUP.
* gimple.def (GIMPLE_OMP_TASKGROUP): Use GSS_OMP_SINGLE_LAYOUT
instead of GSS_OMP.
(GIMPLE_OMP_TEAMS): Use GSS_OMP_PARALLEL_LAYOUT instead
of GSS_OMP_SINGLE_LAYOUT, adjust comments.
* gimple.h (enum gf_mask): Add GF_OMP_TEAMS_HOST, GF_OMP_TASK_TASKWAIT
and GF_OMP_ATOMIC_MEMORY_ORDER. Remove GF_OMP_ATOMIC_SEQ_CST, use
different value for GF_OMP_ATOMIC_NEED_VALUE.
(struct gimple_statement_omp_taskreg): Add GIMPLE_OMP_TEAMS to
comments.
(struct gimple_statement_omp_single_layout): And remove here.
(struct gomp_teams): Inherit from gimple_statement_omp_taskreg rather
than gimple_statement_omp_single_layout.
(is_a_helper <gimple_statement_omp_taskreg *>::test): Allow
GIMPLE_OMP_TEAMS.
(is_a_helper <const gimple_statement_omp_taskreg *>::test): Likewise.
(gimple_omp_subcode): Formatting fix.
(gimple_omp_teams_child_fn, gimple_omp_teams_child_fn_ptr,
gimple_omp_teams_set_child_fn, gimple_omp_teams_data_arg,
gimple_omp_teams_data_arg_ptr, gimple_omp_teams_set_data_arg,
gimple_omp_teams_host, gimple_omp_teams_set_host,
gimple_omp_task_taskwait_p, gimple_omp_task_set_taskwait_p,
gimple_omp_taskgroup_clauses, gimple_omp_taskgroup_clauses_ptr,
gimple_omp_taskgroup_set_clauses): New inline functions.
(gimple_build_omp_atomic_load): Add enum omp_memory_order argument.
(gimple_build_omp_atomic_store): Likewise.
(gimple_omp_atomic_seq_cst_p): Remove.
(gimple_omp_atomic_memory_order): New function.
(gimple_omp_atomic_set_seq_cst): Remove.
(gimple_omp_atomic_set_memory_order): New function.
(gimple_build_omp_taskgroup): Add clauses argument.
* gimple-pretty-print.c (dump_gimple_omp_taskgroup): New function.
(dump_gimple_omp_task): Print taskwait with depend clauses.
(dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Use
dump_omp_atomic_memory_order.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP.
* gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP_ALLOC_ONLY,
GOVD_MAP_FROM_ONLY and GOVD_NONTEMPORAL.
(enum omp_region_type): Reserve bits 1 and 2 for auxiliary flags,
renumber values of most of ORT_* enumerators, add ORT_HOST_TEAMS,
ORT_COMBINED_HOST_TEAMS, ORT_TASKGROUP, ORT_TASKLOOP and
ORT_UNTIED_TASKLOOP enumerators.
(enum gimplify_defaultmap_kind): New.
(struct gimplify_omp_ctx): Remove target_map_scalars_firstprivate and
target_map_pointers_as_0len_arrays members, add defaultmap.
(new_omp_context): Initialize defaultmap member.
(gimple_add_tmp_var): Handle ORT_TASKGROUP like ORT_WORKSHARE.
(maybe_fold_stmt): Don't fold even in host teams regions.
(omp_firstprivatize_variable): Handle ORT_TASKGROUP like
ORT_WORKSHARE. Test ctx->defaultmap[GDMK_SCALAR] instead of
ctx->omp_firstprivatize_variable.
(omp_add_variable): Don't add private/firstprivate for VLAs in
ORT_TASKGROUP.
(omp_default_clause): Print "taskloop" rather than "task" if
ORT_*TASKLOOP.
(omp_notice_variable): Handle ORT_TASKGROUP like ORT_WORKSHARE.
Handle new defaultmap clause kinds.
(omp_is_private): Handle ORT_TASKGROUP like ORT_WORKSHARE. Allow simd
iterator to be lastprivate or private. Fix up diagnostics if linear
is used on collapse>1 simd iterator.
(omp_check_private): Handle ORT_TASKGROUP like ORT_WORKSHARE.
(gimplify_omp_depend): New function.
(gimplify_scan_omp_clauses): Add shared clause on parallel for
combined parallel master taskloop{, simd} if taskloop has
firstprivate, lastprivate or reduction clause. Handle
OMP_CLAUSE_REDUCTION_TASK diagnostics. Adjust tests for
ORT_COMBINED_TEAMS. Gimplify depend clauses with iterators. Handle
cancel and simd OMP_CLAUSE_IF_MODIFIERs. Handle
OMP_CLAUSE_NONTEMPORAL. Handle new defaultmap clause kinds. Handle
OMP_CLAUSE_{TASK,IN}_REDUCTION. Diagnose invalid conditional
lastprivate.
(gimplify_adjust_omp_clauses_1): Ignore GOVD_NONTEMPORAL. Handle
GOVD_MAP_ALLOC_ONLY and GOVD_MAP_FROM_ONLY.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NONTEMPORAL. Handle
OMP_CLAUSE_{TASK,IN}_REDUCTION.
(gimplify_omp_task): Handle taskwait with depend clauses.
(gimplify_omp_for): Add shared clause on parallel for combined
parallel master taskloop{, simd} if taskloop has firstprivate,
lastprivate or reduction clause. Use ORT_TASKLOOP or
ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK. Adjust
tests for ORT_COMBINED_TEAMS. Handle C++ range for loops with
NULL TREE_PURPOSE in OMP_FOR_ORIG_DECLS. Firstprivatize
__for_end and __for_range temporaries on OMP_PARALLEL for
distribute parallel for{, simd}. Move OMP_CLAUSE_REDUCTION
and OMP_CLAUSE_IN_REDUCTION from taskloop to the task construct
sandwiched in between two taskloops.
(computable_teams_clause): Test ctx->defaultmap[GDMK_SCALAR]
instead of ctx->omp_firstprivatize_variable.
(gimplify_omp_workshare): Set ort to ORT_HOST_TEAMS or
ORT_COMBINED_HOST_TEAMS if not inside of target construct. If
host teams, use gimplify_and_return_first etc. for body like
for target or target data constructs, and at the end call
gimple_omp_teams_set_host on the GIMPLE_OMP_TEAMS object.
(gimplify_omp_atomic): Use OMP_ATOMIC_MEMORY_ORDER instead
of OMP_ATOMIC_SEQ_CST, pass it as new argument to
gimple_build_omp_atomic_load and gimple_build_omp_atomic_store, remove
gimple_omp_atomic_set_seq_cst calls.
(gimplify_expr) <case OMP_TASKGROUP>: Move handling into a separate
case, handle taskgroup clauses.
* lto-streamer-out.c (hash_tree): Handle
OMP_CLAUSE_{TASK,IN}_REDUCTION.
* Makefile.in (GTFILES): Add omp-general.h.
* omp-builtins.def (BUILT_IN_GOMP_TASKWAIT_DEPEND,
BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_START,
BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START,
BUILT_IN_GOMP_LOOP_START, BUILT_IN_GOMP_LOOP_ORDERED_START,
BUILT_IN_GOMP_LOOP_DOACROSS_START,
BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT,
BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START,
BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
BUILT_IN_GOMP_LOOP_ULL_START, BUILT_IN_GOMP_LOOP_ULL_ORDERED_START,
BUILT_IN_GOMP_LOOP_ULL_DOACROSS_START,
BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT,
BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME,
BUILT_IN_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME,
BUILT_IN_GOMP_PARALLEL_REDUCTIONS, BUILT_IN_GOMP_SECTIONS2_START,
BUILT_IN_GOMP_TEAMS_REG, BUILT_IN_GOMP_TASKGROUP_REDUCTION_REGISTER,
BUILT_IN_GOMP_TASKGROUP_REDUCTION_UNREGISTER,
BUILT_IN_GOMP_TASK_REDUCTION_REMAP,
BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER): New builtins.
* omp-expand.c (workshare_safe_to_combine_p): Return false for
non-worksharing loops.
(omp_adjust_chunk_size): Don't adjust anything if chunk_size is zero.
(determine_parallel_type): Don't combine parallel with worksharing
which has _reductemp_ clause.
(expand_parallel_call): Emit the GOMP_*nonmonotonic_runtime* or
GOMP_*maybe_nonmonotonic_runtime* builtins instead of GOMP_*runtime*
if there is nonmonotonic modifier or if there is no modifier and no
ordered clause. For dynamic and guided schedule without monotonic
and nonmonotonic modifier, default to nonmonotonic.
(expand_omp_for): Likewise. Adjust expand_omp_for_generic caller, use
GOMP_loop{,_ull}{,_ordered,_doacross}_start builtins if there are
task reductions.
(expand_task_call): Add GOMP_TASK_FLAG_REDUCTION flag to flags if
there are any reduction clauses.
(expand_taskwait_call): New function.
(expand_teams_call): New function.
(expand_omp_taskreg): Allow GIMPLE_OMP_TEAMS and call
expand_teams_call for it. Formatting fix. Handle taskwait with
depend clauses.
(expand_omp_for_generic): Add SCHED_ARG argument. Handle expansion
of worksharing loops with task reductions.
(expand_omp_for_static_nochunk, expand_omp_for_static_chunk): Handle
expansion of worksharing loops with task reductions.
(expand_omp_sections): Handle expansion of sections with task
reductions.
(expand_omp_synch): For host teams call expand_omp_taskreg.
(omp_memory_order_to_memmodel): New function.
(expand_omp_atomic_load, expand_omp_atomic_store,
expand_omp_atomic_fetch_op): Use it and gimple_omp_atomic_memory_order
instead of gimple_omp_atomic_seq_cst_p.
(build_omp_regions_1, omp_make_gimple_edges): Treat taskwait with
depend clauses as a standalone directive.
* omp-general.c (enum omp_requires): New variable.
(omp_extract_for_data): Initialize have_reductemp member. Allow
NE_EXPR even in OpenMP loops, transform them into LT_EXPR or
GT_EXPR loops depending on incr sign. Formatting fixes.
* omp-general.h (struct omp_for_data): Add have_reductemp member.
(enum omp_requires): New enum.
(omp_requires_mask): Declare.
* omp-grid.c (grid_eliminate_combined_simd_part): Formatting fix.
Fix comment typos.
* omp-low.c (struct omp_context): Add task_reductions and
task_reduction_map fields.
(is_host_teams_ctx): New function.
(is_taskreg_ctx): Return true also if is_host_teams_ctx.
(use_pointer_for_field): Use is_global_var instead of
TREE_STATIC || DECL_EXTERNAL, and apply only if not privatized
in outer contexts.
(build_outer_var_ref): Ignore taskgroup outer contexts.
(delete_omp_context): Release task_reductions and task_reduction_map.
(scan_sharing_clauses): Don't add any fields for reduction clause on
taskloop. Handle OMP_CLAUSE__REDUCTEMP_. Handle
OMP_CLAUSE_{IN,TASK}_REDUCTION and OMP_CLAUSE_REDUCTION with task
modifier. Don't ignore shared clauses in is_host_teams_ctx contexts.
Handle OMP_CLAUSE_NONTEMPORAL.
(add_taskreg_looptemp_clauses): Add OMP_CLAUSE__REDUCTEMP_ clause if
needed.
(scan_omp_parallel): Add _reductemp_ clause if there are any reduction
clauses with task modifier.
(scan_omp_task): Handle taskwait with depend clauses.
(finish_taskreg_scan): Move field corresponding to _reductemp_ clause
first. Move also OMP_CLAUSE__REDUCTEMP_ clause in front if present.
Handle GIMPLE_OMP_TEAMS like GIMPLE_OMP_PARALLEL.
(scan_omp_for): Fix comment formatting.
(scan_omp_teams): Handle host teams constructs.
(check_omp_nesting_restrictions): Allow teams with no outer
OpenMP context. Adjust diagnostics for teams strictly nested into
some explicit OpenMP construct other than target. Allow OpenMP atomics
inside of simd regions.
(scan_omp_1_stmt): Call scan_sharing_clauses for taskgroups.
(scan_omp_1_stmt) <case GIMPLE_OMP_TEAMS>: Temporarily bump
taskreg_nesting_level while scanning host teams construct.
(task_reduction_read): New function.
(lower_rec_input_clauses): Handle OMP_CLAUSE_REDUCTION on taskloop
construct. Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE__REDUCTEMP_
clauses. Handle OMP_CLAUSE_REDUCTION with task modifier. Remove
second argument create_tmp_var if it is NULL. Don't ignore shared
clauses in is_host_teams_ctx contexts. Handle
OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE on OMP_CLAUSE_FIRSTPRIVATE
clauses.
(lower_reduction_clauses): Ignore reduction clauses with task
modifier. Remove second argument create_tmp_var if it is NULL.
Initialize OMP_ATOMIC_MEMORY_ORDER to relaxed.
(lower_send_clauses): Ignore reduction clauses with task modifier.
Handle OMP_CLAUSE__REDUCTEMP_. Don't send anything for
OMP_CLAUSE_REDUCTION on taskloop. Handle OMP_CLAUSE_IN_REDUCTION.
(maybe_add_implicit_barrier_cancel): Add OMP_RETURN argument, don't
rely that it is the last stmt in body so far. Ignore outer taskgroup
contexts.
(omp_task_reductions_find_first, omp_task_reduction_iterate,
lower_omp_task_reductions): New functions.
(lower_omp_sections): Handle reduction clauses with taskgroup
modifiers. Adjust maybe_add_implicit_barrier_cancel caller.
(lower_omp_single): Adjust maybe_add_implicit_barrier_cancel caller.
(lower_omp_for): Likewise. Handle reduction clauses with taskgroup
modifiers.
(lower_omp_taskgroup): Handle taskgroup reductions.
(create_task_copyfn): Copy over OMP_CLAUSE__REDUCTEMP_ pointer.
Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_REDUCTION clauses.
(lower_depend_clauses): If there are any
OMP_CLAUSE_DEPEND_DEPOBJ or OMP_CLAUSE_DEPEND_MUTEXINOUTSET
depend clauses, use a new array format. If OMP_CLAUSE_DEPEND_LAST is
seen, assume lowering is done already and return early. Set kind
on artificial depend clause to OMP_CLAUSE_DEPEND_LAST.
(lower_omp_taskreg): Handle reduction clauses with task modifier on
parallel construct. Handle reduction clause on taskloop construct.
Handle taskwait with depend clauses.
(lower_omp_1): Use lower_omp_taskreg instead of lower_omp_teams
for host teams constructs.
* tree.c (omp_clause_num_ops): Add in_reduction, task_reduction,
nontemporal and _reductemp_ clause entries.
(omp_clause_code_name): Likewise.
(walk_tree_1): Handle OMP_CLAUSE_{IN,TASK}_REDUCTION,
OMP_CLAUSE_NONTEMPORAL and OMP_CLAUSE__REDUCTEMP_.
* tree-core.h (enum omp_clause_code): Add
OMP_CLAUSE_{{IN,TASK}_REDUCTION,NONTEMPORAL,_REDUCTEMP_}.
(enum omp_clause_defaultmap_kind, enum omp_memory_order): New.
(struct tree_base): Add omp_atomic_memory_order field into union.
Remove OMP_ATOMIC_SEQ_CST comment.
(enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_MUTEXINOUTSET
and OMP_CLAUSE_DEPEND_DEPOBJ.
(struct tree_omp_clause): Add subcode.defaultmap_kind.
* tree.def (OMP_TASKGROUP): Add another operand, move next to other
OpenMP constructs with body and clauses operands.
* tree.h (OMP_BODY): Use OMP_MASTER instead of OMP_TASKGROUP.
(OMP_CLAUSES): Use OMP_TASKGROUP instead of OMP_SINGLE.
(OMP_TASKGROUP_CLAUSES): Define.
(OMP_CLAUSE_DECL): Use OMP_CLAUSE__REDUCTEMP_ instead of
OMP_CLAUSE__LOOPTEMP_.
(OMP_ATOMIC_SEQ_CST): Remove.
(OMP_ATOMIC_MEMORY_ORDER, OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE,
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL): Define.
(OMP_CLAUSE_REDUCTION_CODE, OMP_CLAUSE_REDUCTION_INIT,
OMP_CLAUSE_REDUCTION_MERGE, OMP_CLAUSE_REDUCTION_PLACEHOLDER,
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER,
OMP_CLAUSE_REDUCTION_OMP_ORIG_REF): Handle
OMP_CLAUSE_{,IN_,TASK_}REDUCTION.
(OMP_CLAUSE_REDUCTION_TASK, OMP_CLAUSE_REDUCTION_INSCAN,
OMP_CLAUSE_DEFAULTMAP_KIND, OMP_CLAUSE_DEFAULTMAP_CATEGORY,
OMP_CLAUSE_DEFAULTMAP_BEHAVIOR, OMP_CLAUSE_DEFAULTMAP_SET_KIND):
Define.
* tree-inline.c (remap_gimple_stmt): Remap taskgroup clauses.
* tree-nested.c (convert_nonlocal_omp_clauses): Handle
OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_NONTEMPORAL.
(convert_local_omp_clauses): Likewise. Remove useless test.
* tree-parloops.c (create_call_for_reduction_1): Pass
OMP_MEMORY_ORDER_RELAXED as new argument to
dump_gimple_omp_atomic_load and dump_gimple_omp_atomic_store.
* tree-pretty-print.c (dump_omp_iterators): New function.
(dump_omp_clause): Handle OMP_CLAUSE__REDUCTEMP_,
OMP_CLAUSE_NONTEMPORAL, OMP_CLAUSE_{TASK,IN}_REDUCTION. Print
reduction modifiers. Handle OMP_CLAUSE_DEPEND_DEPOBJ and
OMP_CLAUSE_DEPEND_MUTEXINOUTSET. Print iterators in depend clauses.
Print __internal__ for OMP_CLAUSE_DEPEND_LAST. Handle cancel and
simd OMP_CLAUSE_IF_MODIFIERs. Handle new kinds of
OMP_CLAUSE_DEFAULTMAP. Print conditional: for
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL.
(dump_omp_atomic_memory_order): New function.
(dump_generic_node): Use it. Print taskgroup clauses. Print
taskwait with depend clauses.
* tree-pretty-print.h (dump_omp_atomic_memory_order): Declare.
* tree-streamer-in.c (unpack_ts_omp_clause_value_fields):
Handle OMP_CLAUSE_{TASK,IN}_REDUCTION.
* tree-streamer-out.c (pack_ts_omp_clause_value_fields,
write_ts_omp_clause_tree_pointers): Likewise.
2018-11-08 David Malcolm <dmalcolm@redhat.com>
PR ipa/86395

View File

@ -309,7 +309,16 @@ arm_print_hint_for_cpu_option (const char *target,
{
auto_vec<const char*> candidates;
for (; list->common.name != NULL; list++)
candidates.safe_push (list->common.name);
{
candidates.safe_push (list->common.name);
if (list->aliases)
{
for (const cpu_alias *alias = list->aliases; alias->name != NULL;
alias++)
if (alias->visible)
candidates.safe_push (alias->name);
}
}
#ifdef HAVE_LOCAL_CPU_DETECT
/* Add also "native" as possible value. */
@ -345,6 +354,16 @@ arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
if (strncmp (entry->common.name, target, len) == 0
&& entry->common.name[len] == '\0')
return entry;
/* Match against any legal alias for this CPU candidate. */
if (entry->aliases)
{
for (const cpu_alias *alias = entry->aliases; alias->name != NULL;
alias++)
if (strncmp (alias->name, target, len) == 0
&& alias->name[len] == '\0')
return entry;
}
}
if (complain)

View File

@ -617,6 +617,7 @@ end arch iwmmxt2
# format:
# begin cpu <name>
# [cname <c-compatible-name>]
# [alias <name>+]
# [tune for <cpu-name>]
# [tune flags <list>]
# architecture <name>
@ -630,6 +631,9 @@ end arch iwmmxt2
#
# If omitted, cname is formed from transforming the cpuname to convert
# non-valid punctuation characters to '_'.
# Any number of alias names may be specified for a CPU. If the name starts
# with a '!' then it will be recognized as a valid name, but will not
# be printed in any help text listing permitted CPUs.
# If specified, tune for specifies a CPU target to use for tuning this core.
# isa flags are appended to those defined by the architecture.
# Each add option must have a distinct feature set and each remove
@ -658,29 +662,12 @@ begin cpu arm810
end cpu arm810
begin cpu strongarm
alias strongarm110 !strongarm1100 !strongarm1110
tune flags LDSCHED STRONG
architecture armv4
costs strongarm
end cpu strongarm
begin cpu strongarm110
tune flags LDSCHED STRONG
architecture armv4
costs strongarm
end cpu strongarm110
begin cpu strongarm1100
tune flags LDSCHED STRONG
architecture armv4
costs strongarm
end cpu strongarm1100
begin cpu strongarm1110
tune flags LDSCHED STRONG
architecture armv4
costs strongarm
end cpu strongarm1110
begin cpu fa526
tune flags LDSCHED
architecture armv4

View File

@ -122,8 +122,7 @@
(define_insn_reservation "mult_ldsched_strongarm" 3
(and (eq_attr "generic_sched" "yes")
(and (eq_attr "ldsched" "yes")
(and (eq_attr "tune"
"strongarm,strongarm110,strongarm1100,strongarm1110")
(and (eq_attr "tune" "strongarm")
(ior (eq_attr "mul32" "yes")
(eq_attr "mul64" "yes")))))
"core*2")
@ -131,8 +130,7 @@
(define_insn_reservation "mult_ldsched" 4
(and (eq_attr "generic_sched" "yes")
(and (eq_attr "ldsched" "yes")
(and (eq_attr "tune"
"!strongarm,strongarm110,strongarm1100,strongarm1110")
(and (eq_attr "tune" "!strongarm")
(ior (eq_attr "mul32" "yes")
(eq_attr "mul64" "yes")))))
"core*4")

View File

@ -498,6 +498,16 @@ struct arm_build_target
extern struct arm_build_target arm_active_target;
/* Table entry for a CPU alias. */
struct cpu_alias
{
/* The alias name. */
const char *const name;
/* True if the name should be displayed in help text listing cpu names. */
bool visible;
};
/* Table entry for an architectural feature extension. */
struct cpu_arch_extension
{
/* Feature name. */
@ -511,6 +521,7 @@ struct cpu_arch_extension
const enum isa_feature isa_bits[isa_num_bits];
};
/* Common elements of both CPU and architectural options. */
struct cpu_arch_option
{
/* Name for this option. */
@ -521,6 +532,7 @@ struct cpu_arch_option
enum isa_feature isa_bits[isa_num_bits];
};
/* Table entry for an architecture entry. */
struct arch_option
{
/* Common option fields. */
@ -535,10 +547,13 @@ struct arch_option
enum processor_type tune_id;
};
/* Table entry for a CPU entry. */
struct cpu_option
{
/* Common option fields. */
cpu_arch_option common;
/* List of aliases for this CPU. */
const struct cpu_alias *aliases;
/* Architecture upon which this CPU is based. */
enum arch_type arch;
};

View File

@ -33,15 +33,6 @@ Enum(processor_type) String(arm810) Value( TARGET_CPU_arm810)
EnumValue
Enum(processor_type) String(strongarm) Value( TARGET_CPU_strongarm)
EnumValue
Enum(processor_type) String(strongarm110) Value( TARGET_CPU_strongarm110)
EnumValue
Enum(processor_type) String(strongarm1100) Value( TARGET_CPU_strongarm1100)
EnumValue
Enum(processor_type) String(strongarm1110) Value( TARGET_CPU_strongarm1110)
EnumValue
Enum(processor_type) String(fa526) Value( TARGET_CPU_fa526)

View File

@ -22,7 +22,6 @@
(define_attr "tune"
"arm8,arm810,strongarm,
strongarm110,strongarm1100,strongarm1110,
fa526,fa626,arm7tdmi,
arm7tdmis,arm710t,arm720t,
arm740t,arm9,arm9tdmi,

View File

@ -261,6 +261,18 @@ function gen_comm_data () {
print " { NULL, false, false, {isa_nobit}}"
print "};\n"
}
if (cpus[n] in cpu_aliases) {
print "static const cpu_alias cpu_aliastab_" \
cpu_cnames[cpus[n]] "[] = {"
naliases = split (cpu_aliases[cpus[n]], aliases)
for (alias = 1; alias <= naliases; alias++) {
print " { \"" aliases[alias] "\", " \
cpu_alias_visible[cpus[n],aliases[alias]] "},"
}
print " { NULL, false}"
print "};\n"
}
}
print "const cpu_option all_cores[] ="
@ -295,12 +307,16 @@ function gen_comm_data () {
}
print_isa_bits_for(all_isa_bits, " ")
print "\n },"
# aliases
if (cpus[n] in cpu_aliases) {
print " cpu_aliastab_" cpu_cnames[cpus[n]] ","
} else print " NULL,"
# arch
print " TARGET_ARCH_" arch_cnames[feats[1]]
print " },"
}
print " {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
print " {{NULL, NULL, {isa_nobit}}, NULL, TARGET_ARCH_arm_none}"
print "};"
narchs = split (arch_list, archs)
@ -486,13 +502,17 @@ function gen_opt () {
function check_cpu (name) {
exts = split (name, extensions, "+")
if (! (extensions[1] in cpu_cnames)) {
return "error"
cpu_name = extensions[1]
if (! (cpu_name in cpu_cnames)) {
if (! (cpu_name in cpu_all_aliases)) {
return "error"
}
cpu_name = cpu_all_aliases[cpu_name]
}
for (n = 2; n <= exts; n++) {
if (!((extensions[1], extensions[n]) in cpu_opt_remove) \
&& !((extensions[1], extensions[n]) in cpu_optaliases)) {
if (!((cpu_name, extensions[n]) in cpu_opt_remove) \
&& !((cpu_name, extensions[n]) in cpu_optaliases)) {
return "error"
}
}
@ -642,6 +662,12 @@ BEGIN {
toplevel()
cpu_name = $3
parse_ok = 1
if (cpu_name in cpu_cnames) {
fatal(cpu_name " is already defined")
}
if (cpu_name in cpu_all_aliases) {
fatal(cpu_name " has already been defined as an alias")
}
}
/^[ ]*cname / {
@ -651,6 +677,33 @@ BEGIN {
parse_ok = 1
}
/^[ ]*alias / {
if (NF < 2) fatal("syntax: alias <name>+")
if (cpu_name == "") fatal("\"alias\" outside of cpu block")
alias_count = NF
for (n = 2; n <= alias_count; n++) {
visible = "true"
alias = $n
if (alias ~ /!.*/) {
visible = "false"
gsub(/^!/, "", alias)
}
if (alias in cpu_cnames) {
fatal(alias " is already defined as a cpu name")
}
if (n == 2) {
cpu_aliases[cpu_name] = alias
} else cpu_aliases[cpu_name] = cpu_aliases[cpu_name] " " alias
cpu_alias_visible[cpu_name,alias] = visible
if (alias in cpu_all_aliases) {
fatal(alias " is already an alias for " cpu_all_aliases[alias])
}
cpu_all_aliases[alias] = cpu_name
}
cpu_has_alias[cpu_name] = 1
parse_ok = 1
}
/^[ ]*tune for / {
if (NF != 3) fatal("syntax: tune for <cpu-name>")
if (cpu_name != "") {

View File

@ -88,3 +88,32 @@
(match_test "memory_address_p (GET_MODE (op), XEXP (op, 0))
&& no_side_effect_operand (op, GET_MODE (op))")))
;; What follows is a set of constraints used to prevent the generation
;; of insns that have a register as source, and an auto-increment or
;; auto-decrement memory reference as the destination where the register
;; is the same as the source. On the PDP11, such instructions are not
;; implemented consistently across the models and often do something
;; different from what the RTL intends.
(define_register_constraint "Z0" "NOTR0_REG" "Register other than 0")
(define_register_constraint "Z1" "NOTR1_REG" "Register other than 1")
(define_register_constraint "Z2" "NOTR2_REG" "Register other than 2")
(define_register_constraint "Z3" "NOTR3_REG" "Register other than 3")
(define_register_constraint "Z4" "NOTR4_REG" "Register other than 4")
(define_register_constraint "Z5" "NOTR5_REG" "Register other than 5")
(define_register_constraint "Z6" "NOTSP_REG"
"Register other than stack pointer (register 6)")
(define_memory_constraint "Za" "R0 push/pop"
(match_test "pushpop_regeq (op, 0)"))
(define_memory_constraint "Zb" "R1 push/pop"
(match_test "pushpop_regeq (op, 1)"))
(define_memory_constraint "Zc" "R2 push/pop"
(match_test "pushpop_regeq (op, 2)"))
(define_memory_constraint "Zd" "R3 push/pop"
(match_test "pushpop_regeq (op, 3)"))
(define_memory_constraint "Ze" "R4 push/pop"
(match_test "pushpop_regeq (op, 4)"))
(define_memory_constraint "Zf" "R5 push/pop"
(match_test "pushpop_regeq (op, 5)"))
(define_memory_constraint "Zg" "SP push/pop"
(match_test "pushpop_regeq (op, 6)"))

View File

@ -26,14 +26,12 @@ extern int legitimate_const_double_p (rtx);
extern void notice_update_cc_on_set (rtx, rtx);
extern void output_addr_const_pdp11 (FILE *, rtx);
extern const char *output_move_multiple (rtx *);
extern void expand_block_move (rtx *);
extern const char *output_jump (rtx *, int, int);
extern void print_operand_address (FILE *, rtx);
typedef enum { no_action, dec_before, inc_after } pdp11_action;
typedef enum { little, either, big } pdp11_partorder;
extern bool pdp11_expand_operands (rtx *, rtx [][2], int,
extern bool pdp11_expand_operands (rtx *, rtx [][2], int, int,
pdp11_action *, pdp11_partorder);
extern int pdp11_sp_frame_offset (void);
extern int pdp11_initial_elimination_offset (int, int);
extern enum reg_class pdp11_regno_reg_class (int);
extern bool pdp11_fixed_cc_regs (unsigned int *, unsigned int *);
@ -42,6 +40,8 @@ extern bool pdp11_expand_shift (rtx *, rtx (*) (rtx, rtx, rtx),
rtx (*) (rtx, rtx, rtx));
extern const char * pdp11_assemble_shift (rtx *, machine_mode, int);
extern int pdp11_shift_length (rtx *, machine_mode, int, bool);
extern int pdp11_cmp_length (rtx *, int);
extern bool pushpop_regeq (rtx, int);
extern bool pdp11_small_shift (int);
#endif /* RTX_CODE */

View File

@ -304,6 +304,9 @@ static bool pdp11_scalar_mode_supported_p (scalar_mode);
#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
#undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
#define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P hook_bool_void_false
/* A helper function to determine if REGNO should be saved in the
current function's stack frame. */
@ -316,6 +319,13 @@ pdp11_saved_regno (unsigned regno)
/* Expand the function prologue. */
/* Frame layout, from high to low memory (stack push order):
return address (from jsr instruction)
saved CPU registers, lowest number first
saved FPU registers, lowest number first, always 64 bit mode
*** frame pointer points here ***
local variables
alloca storage if any. */
void
pdp11_expand_prologue (void)
{
@ -331,31 +341,9 @@ pdp11_expand_prologue (void)
emit_insn (gen_seti ());
}
if (frame_pointer_needed)
{
x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (Pmode, x);
emit_move_insn (x, hard_frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
}
/* Make frame. */
if (fsize)
{
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-fsize)));
/* Prevent frame references via the frame pointer from being
scheduled before the frame is allocated. */
if (frame_pointer_needed)
emit_insn (gen_blockage ());
}
/* Save CPU registers. */
for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
if (pdp11_saved_regno (regno)
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
if (pdp11_saved_regno (regno))
{
x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (Pmode, x);
@ -383,25 +371,21 @@ pdp11_expand_prologue (void)
x = gen_frame_mem (DFmode, x);
emit_move_insn (x, via_ac);
}
if (frame_pointer_needed)
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
/* Make local variable space. */
if (fsize)
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-fsize)));
}
/* The function epilogue should not depend on the current stack pointer!
It should use the frame pointer only. This is mandatory because
of alloca; we also take advantage of it to omit stack adjustments
before returning. */
/* Maybe we can make leaf functions faster by switching to the
second register file - this way we don't have to save regs!
leaf functions are ~ 50% of all functions (dynamically!)
set/clear bit 11 (dec. 2048) of status word for switching register files -
but how can we do this? the pdp11/45 manual says bit may only
be set (p.24), but not cleared!
switching to kernel is probably more expensive, so we'll leave it
like this and not use the second set of registers...
maybe as option if you want to generate code for kernel mode? */
/* Generate epilogue. This uses the frame pointer to pop the local
variables and any alloca data off the stack. If there is no alloca
and frame pointer elimination hasn't been disabled, there is no
frame pointer and the local variables are popped by adjusting the
stack pointer instead. */
void
pdp11_expand_epilogue (void)
@ -410,6 +394,20 @@ pdp11_expand_epilogue (void)
unsigned regno;
rtx x, reg, via_ac = NULL;
/* Deallocate the local variables. */
if (fsize)
{
if (frame_pointer_needed)
{
/* We can deallocate the frame with a single move. */
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
}
else
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (fsize)));
}
/* Restore the FPU registers. */
if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
{
/* Find a temporary with which to restore AC4/5. */
@ -421,109 +419,33 @@ pdp11_expand_epilogue (void)
}
}
/* If possible, restore registers via pops. */
if (!frame_pointer_needed || crtl->sp_is_unchanging)
{
/* Restore registers via pops. */
/* Restore registers via pops. */
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
if (pdp11_saved_regno (regno))
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
if (pdp11_saved_regno (regno))
{
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (DFmode, x);
reg = gen_rtx_REG (DFmode, regno);
if (LOAD_FPU_REG_P (regno))
emit_move_insn (reg, x);
else
{
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (DFmode, x);
reg = gen_rtx_REG (DFmode, regno);
if (LOAD_FPU_REG_P (regno))
emit_move_insn (reg, x);
else
{
emit_move_insn (via_ac, x);
emit_move_insn (reg, via_ac);
}
emit_move_insn (via_ac, x);
emit_move_insn (reg, via_ac);
}
}
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
if (pdp11_saved_regno (regno)
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
{
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (Pmode, x);
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
}
}
else
{
/* Restore registers via moves. */
/* ??? If more than a few registers need to be restored, it's smaller
to generate a pointer through which we can emit pops. Consider
that moves cost 2*NREG words and pops cost NREG+3 words. This
means that the crossover is NREG=3.
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
if (pdp11_saved_regno (regno))
{
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (Pmode, x);
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
}
Possible registers to use are:
(1) The first call-saved general register. This register will
be restored with the last pop.
(2) R1, if it's not used as a return register.
(3) FP itself. This option may result in +4 words, since we
may need two add imm,rn instructions instead of just one.
This also has the downside that we're not representing
the unwind info in any way, so during the epilogue the
debugger may get lost. */
HOST_WIDE_INT ofs = -pdp11_sp_frame_offset ();
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
if (pdp11_saved_regno (regno))
{
x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
x = gen_frame_mem (DFmode, x);
reg = gen_rtx_REG (DFmode, regno);
if (LOAD_FPU_REG_P (regno))
emit_move_insn (reg, x);
else
{
emit_move_insn (via_ac, x);
emit_move_insn (reg, via_ac);
}
ofs += 8;
}
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
if (pdp11_saved_regno (regno)
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
{
x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
x = gen_frame_mem (Pmode, x);
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
ofs += 2;
}
}
/* Deallocate the stack frame. */
if (fsize)
{
/* Prevent frame references via any pointer from being
scheduled after the frame is deallocated. */
emit_insn (gen_blockage ());
if (frame_pointer_needed)
{
/* We can deallocate the frame with a single move. */
emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
}
else
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (fsize)));
}
if (frame_pointer_needed)
{
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
x = gen_frame_mem (Pmode, x);
emit_move_insn (hard_frame_pointer_rtx, x);
}
emit_jump_insn (gen_return ());
emit_jump_insn (gen_rtspc ());
}
/* Return the best assembler insn template
@ -539,21 +461,23 @@ singlemove_string (rtx *operands)
/* Expand multi-word operands (SImode or DImode) into the 2 or 4
corresponding HImode operands. The number of operands is given
as the third argument, and the required order of the parts as
the fourth argument. */
corresponding HImode operands. The number of operands is given as
the third argument, the word count for the mode as the fourth
argument, and the required order of parts as the sixth argument.
The word count is explicit because sometimes we're asked to compare
two constants, both of which have mode VOIDmode, so we can't always
rely on the input operand mode to imply the operand size. */
bool
pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
pdp11_expand_operands (rtx *operands, rtx exops[][2],
int opcount, int words,
pdp11_action *action, pdp11_partorder order)
{
int words, op, w, i, sh;
int op, w, i, sh;
pdp11_partorder useorder;
bool sameoff = false;
enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
long sval[2];
words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
/* If either piece order is accepted and one is pre-decrement
while the other is post-increment, set order to be high order
word first. That will force the pre-decrement to be turned
@ -566,19 +490,16 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
useorder = either;
if (opcount == 2)
{
if (!REG_P (operands[0]) && !REG_P (operands[1]) &&
!(CONSTANT_P (operands[1]) ||
GET_CODE (operands[1]) == CONST_DOUBLE) &&
if (GET_CODE (operands[0]) == MEM &&
GET_CODE (operands[1]) == MEM &&
((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
(GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
useorder = big;
else if ((!REG_P (operands[0]) &&
else if ((GET_CODE (operands[0]) == MEM &&
GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
(!REG_P (operands[1]) &&
!(CONSTANT_P (operands[1]) ||
GET_CODE (operands[1]) == CONST_DOUBLE) &&
(GET_CODE (operands[1]) == MEM &&
GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
useorder = little;
else if (REG_P (operands[0]) && REG_P (operands[1]) &&
@ -615,7 +536,7 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
/* First classify the operand. */
if (REG_P (operands[op]))
optype = REGOP;
else if (CONSTANT_P (operands[op])
else if (CONST_INT_P (operands[op])
|| GET_CODE (operands[op]) == CONST_DOUBLE)
optype = CNSTOP;
else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
@ -663,8 +584,11 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
}
if (GET_CODE (operands[op]) == CONST_DOUBLE)
REAL_VALUE_TO_TARGET_DOUBLE
(*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
{
gcc_assert (GET_MODE (operands[op]) != VOIDmode);
REAL_VALUE_TO_TARGET_DOUBLE
(*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
}
for (i = 0; i < words; i++)
{
@ -707,24 +631,31 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
const char *
output_move_multiple (rtx *operands)
{
rtx inops[2];
rtx exops[4][2];
rtx adjops[2];
pdp11_action action[2];
int i, words;
words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
adjops[1] = gen_rtx_CONST_INT (HImode, words * 2);
pdp11_expand_operands (operands, exops, 2, action, either);
inops[0] = operands[0];
inops[1] = operands[1];
pdp11_expand_operands (inops, exops, 2, words, action, either);
/* Check for explicit decrement before. */
if (action[0] == dec_before)
{
operands[0] = XEXP (operands[0], 0);
output_asm_insn ("sub\t%#4,%0", operands);
adjops[0] = XEXP (XEXP (operands[0], 0), 0);
output_asm_insn ("sub\t%1,%0", adjops);
}
if (action[1] == dec_before)
{
operands[1] = XEXP (operands[1], 0);
output_asm_insn ("sub\t%#4,%1", operands);
adjops[0] = XEXP (XEXP (operands[1], 0), 0);
output_asm_insn ("sub\t%1,%0", adjops);
}
/* Do the words. */
@ -734,13 +665,13 @@ output_move_multiple (rtx *operands)
/* Check for increment after. */
if (action[0] == inc_after)
{
operands[0] = XEXP (operands[0], 0);
output_asm_insn ("add\t%#4,%0", operands);
adjops[0] = XEXP (XEXP (operands[0], 0), 0);
output_asm_insn ("add\t%1,%0", adjops);
}
if (action[1] == inc_after)
{
operands[1] = XEXP (operands[1], 0);
output_asm_insn ("add\t%#4,%1", operands);
adjops[0] = XEXP (XEXP (operands[1], 0), 0);
output_asm_insn ("add\t%1,%0", adjops);
}
return "";
@ -752,9 +683,9 @@ pdp11_gen_int_label (char *label, const char *prefix, int num)
{
if (TARGET_DEC_ASM)
/* +1 because GCC numbers labels starting at zero. */
sprintf (label, "*%lu$", num + 1);
sprintf (label, "*%u$", num + 1);
else
sprintf (label, "*%s_%lu", prefix, num);
sprintf (label, "*%s_%u", prefix, num);
}
/* Output an ascii string. */
@ -780,7 +711,7 @@ output_ascii (FILE *file, const char *p, int size)
{
if (delim)
putc ('"', file);
fprintf (file, "<%o%>", c);
fprintf (file, "<%o>", c);
delim = false;
}
else
@ -815,15 +746,30 @@ pdp11_asm_output_var (FILE *file, const char *name, int size,
{
if (align > 8)
fprintf (file, "\t.even\n");
if (global)
if (TARGET_DEC_ASM)
{
fprintf (file, ".globl ");
assemble_name (file, name);
if (global)
fputs ("::", file);
else
fputs (":", file);
if (align > 8)
fprintf (file, "\t.blkw\t%o\n", (size & 0xffff) / 2);
else
fprintf (file, "\t.blkb\t%o\n", size & 0xffff);
}
fprintf (file, "\n");
assemble_name (file, name);
fputs (":", file);
ASM_OUTPUT_SKIP (file, size);
else
{
if (global)
{
fprintf (file, ".globl ");
assemble_name (file, name);
}
fprintf (file, "\n");
assemble_name (file, name);
fputs (":", file);
ASM_OUTPUT_SKIP (file, size);
}
}
/* Special format operators handled here:
@ -855,7 +801,7 @@ pdp11_asm_print_operand (FILE *file, rtx x, int code)
fprintf (file, "%s", reg_names[REGNO (x)]);
else if (GET_CODE (x) == MEM)
output_address (GET_MODE (x), XEXP (x, 0));
else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
else if (GET_CODE (x) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (x)))
{
REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
if (TARGET_DEC_ASM)
@ -1013,8 +959,7 @@ static int
pdp11_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
reg_class_t c1, reg_class_t c2)
{
if (((c1 == MUL_REGS || c1 == GENERAL_REGS) &&
(c2 == MUL_REGS || c2 == GENERAL_REGS)))
if (CPU_REG_CLASS (c1) && CPU_REG_CLASS (c2))
return 2;
else if ((c1 >= LOAD_FPU_REGS && c1 <= FPU_REGS && c2 == LOAD_FPU_REGS) ||
(c2 >= LOAD_FPU_REGS && c2 <= FPU_REGS && c1 == LOAD_FPU_REGS))
@ -1512,50 +1457,32 @@ no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
return FALSE;
}
/*
* expand a block move:
*
* operands[0] ... to
* operands[1] ... from
* operands[2] ... length
* operands[3] ... alignment
*/
void
expand_block_move(rtx *operands)
/* Return TRUE if op is a push or pop using the register "regno". */
bool
pushpop_regeq (rtx op, int regno)
{
rtx lb, test;
rtx fromop, toop, counter;
int count;
rtx addr;
/* False if not memory reference. */
if (GET_CODE (op) != MEM)
return FALSE;
/* Get the address of the memory reference. */
addr = XEXP (op, 0);
/* Transform BLKmode MEM reference into a (reg)+ operand. */
toop = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
toop = gen_rtx_POST_INC (Pmode, toop);
fromop = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
fromop = gen_rtx_POST_INC (Pmode, fromop);
count = INTVAL (operands[2]);
if (INTVAL (operands [3]) >= 2 && (count & 1) == 0)
{
count >>= 1;
toop = gen_rtx_MEM (HImode, toop);
fromop = gen_rtx_MEM (HImode, fromop);
}
else
{
toop = gen_rtx_MEM (QImode, toop);
fromop = gen_rtx_MEM (QImode, fromop);
}
counter = copy_to_mode_reg (HImode, gen_rtx_CONST_INT (HImode, count));
/* Label at top of loop */
lb = gen_label_rtx ();
emit_label (lb);
emit_move_insn (toop, fromop);
emit_insn (gen_subhi3 (counter, counter, const1_rtx));
test = gen_rtx_NE (HImode, counter, const0_rtx);
emit_jump_insn (gen_cbranchhi4 (test, counter, const0_rtx, lb));
if (GET_CODE (addr) == MEM)
addr = XEXP (addr, 0);
switch (GET_CODE (addr))
{
case PRE_DEC:
case POST_INC:
case PRE_MODIFY:
case POST_MODIFY:
return REGNO (XEXP (addr, 0)) == regno;
default:
return FALSE;
}
}
/* This function checks whether a real value can be encoded as
@ -1565,7 +1492,12 @@ int
legitimate_const_double_p (rtx address)
{
long sval[2];
/* If it's too big for HOST_WIDE_INT, it's definitely to big here. */
if (GET_MODE (address) == VOIDmode)
return 0;
REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (address), sval);
if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
return 1;
return 0;
@ -1723,7 +1655,7 @@ pdp11_legitimate_address_p (machine_mode mode,
&& GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
&& GET_CODE (XEXP (xfoob, 0)) == REG
&& REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
&& CONSTANT_P (XEXP (xfoob, 1))
&& CONST_INT_P (XEXP (xfoob, 1))
&& INTVAL (XEXP (xfoob,1)) == -2;
case POST_MODIFY:
@ -1733,7 +1665,7 @@ pdp11_legitimate_address_p (machine_mode mode,
&& GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
&& GET_CODE (XEXP (xfoob, 0)) == REG
&& REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
&& CONSTANT_P (XEXP (xfoob, 1))
&& CONST_INT_P (XEXP (xfoob, 1))
&& INTVAL (XEXP (xfoob,1)) == 2;
case MEM:
@ -1792,16 +1724,18 @@ pdp11_legitimate_address_p (machine_mode mode,
enum reg_class
pdp11_regno_reg_class (int regno)
{
if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
return GENERAL_REGS;
if (regno == ARG_POINTER_REGNUM)
return NOTSP_REG;
else if (regno == CC_REGNUM || regno == FCC_REGNUM)
return CC_REGS;
else if (regno > AC3_REGNUM)
return NO_LOAD_FPU_REGS;
else if (regno >= AC0_REGNUM)
return LOAD_FPU_REGS;
else if (regno & 1)
return MUL_REGS;
else if (regno == 6)
return NOTR0_REG;
else if (regno < 6)
return NOTSP_REG;
else
return GENERAL_REGS;
}
@ -1815,11 +1749,11 @@ pdp11_fixed_cc_regs (unsigned int *p1, unsigned int *p2)
return true;
}
int
pdp11_sp_frame_offset (void)
static int
pdp11_reg_save_size (void)
{
int offset = 0, regno;
offset = get_frame_size();
for (regno = 0; regno <= PC_REGNUM; regno++)
if (pdp11_saved_regno (regno))
offset += 2;
@ -1836,32 +1770,18 @@ pdp11_sp_frame_offset (void)
int
pdp11_initial_elimination_offset (int from, int to)
{
/* Get the size of the register save area. */
int spoff;
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return 4;
else if (from == FRAME_POINTER_REGNUM
&& to == HARD_FRAME_POINTER_REGNUM)
return 0;
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return get_frame_size ();
else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
return pdp11_reg_save_size () + 2;
else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return pdp11_reg_save_size () + 2 + get_frame_size ();
else
{
gcc_assert (to == STACK_POINTER_REGNUM);
/* Get the size of the register save area. */
spoff = pdp11_sp_frame_offset ();
if (from == FRAME_POINTER_REGNUM)
return spoff;
gcc_assert (from == ARG_POINTER_REGNUM);
/* If there is a frame pointer, that is saved too. */
if (frame_pointer_needed)
spoff += 2;
/* Account for the saved PC in the function call. */
return spoff + 2;
}
}
gcc_assert (0);
}
/* A copy of output_addr_const modified for pdp11 expression syntax.
output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
@ -1913,21 +1833,6 @@ output_addr_const_pdp11 (FILE *file, rtx x)
output_addr_const_pdp11 (file, XEXP (x, 0));
break;
case CONST_DOUBLE:
if (GET_MODE (x) == VOIDmode)
{
/* We can use %o if the number is one word and positive. */
if (TARGET_DEC_ASM)
fprintf (file, "%o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
else
fprintf (file, "%#o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
}
else
/* We can't handle floating point constants;
PRINT_OPERAND must handle them. */
output_operand_lossage ("floating constant misused");
break;
case PLUS:
/* Some assemblers need integer constants to appear last (e.g. masm). */
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
@ -2033,7 +1938,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
rtx r, test;
rtx_code_label *lb;
if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
else if (TARGET_40_PLUS)
return false;
@ -2043,7 +1948,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
r = gen_reg_rtx (HImode);
emit_move_insn (operands[0], operands[1]);
emit_move_insn (r, operands[2]);
if (!CONSTANT_P (operands[2]))
if (!CONST_INT_P (operands[2]))
{
test = gen_rtx_LE (HImode, r, const0_rtx);
emit_jump_insn (gen_cbranchhi4 (test, r, const0_rtx, lb));
@ -2053,7 +1958,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
optimizer and it doesn't appreciate flow changes happening
while it's doing things. */
emit_insn ((*shift_base) (operands[0], operands[1], r));
if (!CONSTANT_P (operands[2]))
if (!CONST_INT_P (operands[2]))
{
emit_label (lb);
@ -2072,16 +1977,20 @@ const char *
pdp11_assemble_shift (rtx *operands, machine_mode m, int code)
{
int i, n;
rtx exops[4][2];
rtx inops[2];
rtx exops[2][2];
rtx lb[1];
pdp11_action action[2];
const bool small = CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
const bool small = CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
gcc_assert (small || !TARGET_40_PLUS);
if (m == E_SImode)
pdp11_expand_operands (operands, exops, 1, action, either);
{
inops[0] = operands[0];
pdp11_expand_operands (inops, exops, 1, 2, action, either);
}
if (!small)
{
/* Loop case, generate the top of loop label. */
@ -2179,7 +2088,7 @@ pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand
/* If shifting by a small constant, the loop is unrolled by the
shift count. Otherwise, account for the size of the decrement
and branch. */
if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
shift_size *= INTVAL (operands[2]);
else
shift_size += 4;
@ -2191,6 +2100,39 @@ pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand
return shift_size;
}
/* Return the length of 2 or 4 word integer compares. */
int
pdp11_cmp_length (rtx *operands, int words)
{
rtx inops[2];
rtx exops[4][2];
rtx lb[1];
int i, len = 0;
if (!reload_completed)
return 2;
inops[0] = operands[0];
inops[1] = operands[1];
pdp11_expand_operands (inops, exops, 2, words, NULL, big);
for (i = 0; i < words; i++)
{
len += 4; /* cmp instruction word and branch that follows. */
if (!REG_P (exops[i][0]) &&
!simple_memory_operand (exops[i][0], HImode))
len += 2; /* first operand extra word. */
if (!REG_P (exops[i][1]) &&
!simple_memory_operand (exops[i][1], HImode) &&
!(CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0))
len += 2; /* second operand extra word. */
}
/* Deduct one word because there is no branch at the end. */
return len - 2;
}
/* Prepend to CLOBBERS hard registers that are automatically clobbered
for an asm We do this for CC_REGNUM and FCC_REGNUM (on FPU target)
to maintain source compatibility with the original cc0-based

View File

@ -32,6 +32,20 @@ along with GCC; see the file COPYING3. If not see
do \
{ \
builtin_define_std ("pdp11"); \
if (TARGET_INT16) \
builtin_define_with_int_value ("__pdp11_int", 16); \
else \
builtin_define_with_int_value ("__pdp11_int", 32); \
if (TARGET_40) \
builtin_define_with_int_value ("__pdp11_model", 40); \
else if (TARGET_45) \
builtin_define_with_int_value ("__pdp11_model", 45); \
else \
builtin_define_with_int_value ("__pdp11_model", 10); \
if (TARGET_FPU) \
builtin_define ("__pdp11_fpu"); \
if (TARGET_AC0) \
builtin_define ("__pdp11_ac0"); \
} \
while (0)
@ -153,7 +167,7 @@ extern const struct real_format pdp11_d_format;
#define FIXED_REGISTERS \
{0, 0, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 1, 1, \
1, 1 }
1 }
@ -168,7 +182,7 @@ extern const struct real_format pdp11_d_format;
#define CALL_USED_REGISTERS \
{1, 1, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 1, 1, \
1, 1 }
1 }
/* Specify the registers used for certain standard purposes.
@ -211,6 +225,13 @@ CC_REGS is the condition codes (CPU and FPU)
enum reg_class
{ NO_REGS,
NOTR0_REG,
NOTR1_REG,
NOTR2_REG,
NOTR3_REG,
NOTR4_REG,
NOTR5_REG,
NOTSP_REG,
MUL_REGS,
GENERAL_REGS,
LOAD_FPU_REGS,
@ -229,6 +250,13 @@ enum reg_class
#define REG_CLASS_NAMES \
{ "NO_REGS", \
"NOTR0_REG", \
"NOTR1_REG", \
"NOTR2_REG", \
"NOTR3_REG", \
"NOTR4_REG", \
"NOTR5_REG", \
"SP_REG", \
"MUL_REGS", \
"GENERAL_REGS", \
"LOAD_FPU_REGS", \
@ -243,13 +271,20 @@ enum reg_class
#define REG_CLASS_CONTENTS \
{ {0x00000}, /* NO_REGS */ \
{0x000aa}, /* MUL_REGS */ \
{0x0c0ff}, /* GENERAL_REGS */ \
{0x000fe}, /* NOTR0_REG */ \
{0x000fd}, /* NOTR1_REG */ \
{0x000fb}, /* NOTR2_REG */ \
{0x000f7}, /* NOTR3_REG */ \
{0x000ef}, /* NOTR4_REG */ \
{0x000df}, /* NOTR5_REG */ \
{0x000bf}, /* NOTSP_REG */ \
{0x0002a}, /* MUL_REGS */ \
{0x040ff}, /* GENERAL_REGS */ \
{0x00f00}, /* LOAD_FPU_REGS */ \
{0x03000}, /* NO_LOAD_FPU_REGS */ \
{0x03f00}, /* FPU_REGS */ \
{0x30000}, /* CC_REGS */ \
{0x3ffff}} /* ALL_REGS */
{0x18000}, /* CC_REGS */ \
{0x1ffff}} /* ALL_REGS */
/* The same information, inverted:
Return the class number of the smallest class containing
@ -262,13 +297,17 @@ enum reg_class
#define INDEX_REG_CLASS GENERAL_REGS
#define BASE_REG_CLASS GENERAL_REGS
/* Return TRUE if the class is a CPU register. */
#define CPU_REG_CLASS(CLASS) \
(CLASS >= NOTR0_REG && CLASS <= GENERAL_REGS)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
((CLASS == GENERAL_REGS || CLASS == MUL_REGS)? \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD): \
1 \
)
(CPU_REG_CLASS (CLASS) ? \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD): \
1 \
)
/* Stack layout; function entry, exit and calling. */
@ -328,16 +367,13 @@ extern int current_first_parm_offset;
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
#define FUNCTION_PROFILER(FILE, LABELNO) \
gcc_unreachable ();
#define FUNCTION_PROFILER(FILE, LABELNO)
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers.
No definition is equivalent to always zero. */
extern int may_call_alloca;
#define EXIT_IGNORE_STACK 1
/* Definitions for register eliminations.
@ -347,17 +383,14 @@ extern int may_call_alloca;
followed by "to". Eliminations of the same "from" register are listed
in order of preference.
There are two registers that can always be eliminated on the pdp11.
The frame pointer and the arg pointer can be replaced by either the
hard frame pointer or to the stack pointer, depending upon the
circumstances. The hard frame pointer is not used before reload and
so it is not eligible for elimination. */
There are two registers that can be eliminated on the pdp11. The
arg pointer can be replaced by the frame pointer; the frame pointer
can often be replaced by the stack pointer. */
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
((OFFSET) = pdp11_initial_elimination_offset ((FROM), (TO)))
@ -514,8 +547,8 @@ extern int may_call_alloca;
#define REGISTER_NAMES \
{"r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc", \
"ac0", "ac1", "ac2", "ac3", "ac4", "ac5", "fp", "ap", \
"cc", "fcc" }
"ac0", "ac1", "ac2", "ac3", "ac4", "ac5", "ap", "cc", \
"fcc" }
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.globl\t"
@ -568,28 +601,22 @@ extern int may_call_alloca;
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
pdp11_output_addr_vec_elt (FILE, VALUE)
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes.
/* This is how to output an assembler line that says to advance the
location counter to a multiple of 2**LOG bytes. Only values 0 and
1 should appear, but due to PR87795 larger values (which are not
supported) can also appear. So we treat all alignment of LOG >= 1
as word (2 byte) alignment.
*/
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
switch (LOG) \
{ \
case 0: \
break; \
case 1: \
fprintf (FILE, "\t.even\n"); \
break; \
default: \
gcc_unreachable (); \
}
if (LOG != 0) \
fprintf (FILE, "\t.even\n")
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
if (TARGET_DEC_ASM) \
fprintf (FILE, "\t.blkb\t%ho\n", (SIZE) & 0xffff); \
fprintf (FILE, "\t.blkb\t%o\n", (SIZE) & 0xffff); \
else \
fprintf (FILE, "\t.=.+ %#ho\n", (SIZE) & 0xffff);
fprintf (FILE, "\t.=.+ %#o\n", (SIZE) & 0xffff);
/* This says how to output an assembler line
to define a global common symbol. */
@ -597,7 +624,6 @@ extern int may_call_alloca;
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, true)
/* This says how to output an assembler line
to define a local common symbol. */

View File

@ -26,6 +26,7 @@
UNSPECV_BLOCKAGE
UNSPECV_SETD
UNSPECV_SETI
UNSPECV_MOVMEM
])
(define_constants
@ -33,22 +34,21 @@
;; Register numbers
(R0_REGNUM 0)
(RETVAL_REGNUM 0)
(HARD_FRAME_POINTER_REGNUM 5)
(FRAME_POINTER_REGNUM 5)
(STACK_POINTER_REGNUM 6)
(PC_REGNUM 7)
(AC0_REGNUM 8)
(AC3_REGNUM 11)
(AC4_REGNUM 12)
(AC5_REGNUM 13)
;; The next two are not physical registers but are used for addressing
;; arguments.
(FRAME_POINTER_REGNUM 14)
(ARG_POINTER_REGNUM 15)
;; The next one is not a physical register but is used for
;; addressing arguments.
(ARG_POINTER_REGNUM 14)
;; Condition code registers
(CC_REGNUM 16)
(FCC_REGNUM 17)
(CC_REGNUM 15)
(FCC_REGNUM 16)
;; End of hard registers
(FIRST_PSEUDO_REGISTER 18)
(FIRST_PSEUDO_REGISTER 17)
;; Branch offset limits, as byte offsets from (pc). That is NOT
;; the same thing as "instruction address" -- it is for backward
@ -178,12 +178,7 @@
DONE;
})
(define_expand "return"
[(return)]
"reload_completed && !frame_pointer_needed && pdp11_sp_frame_offset () == 0"
"")
(define_insn "*rts"
(define_insn "rtspc"
[(return)]
""
"rts\tpc")
@ -249,6 +244,78 @@
cmp<PDPint:isfx>\t%0,%1"
[(set_attr "length" "2,2,4,4,4,6")])
;; Two word compare
(define_insn "cmpsi"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 0 "general_operand" "rDQi")
(match_operand:SI 1 "general_operand" "rDQi")))]
""
{
rtx inops[2];
rtx exops[2][2];
rtx lb[1];
inops[0] = operands[0];
inops[1] = operands[1];
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
lb[0] = gen_label_rtx ();
if (CONST_INT_P (exops[0][1]) && INTVAL (exops[0][1]) == 0)
output_asm_insn ("tst\t%0", exops[0]);
else
output_asm_insn ("cmp\t%0,%1", exops[0]);
output_asm_insn ("bne\t%l0", lb);
if (CONST_INT_P (exops[1][1]) && INTVAL (exops[1][1]) == 0)
output_asm_insn ("tst\t%0", exops[1]);
else
output_asm_insn ("cmp\t%0,%1", exops[1]);
output_asm_label (lb[0]);
fputs (":\n", asm_out_file);
return "";
}
[(set (attr "length")
(symbol_ref "pdp11_cmp_length (operands, 2)"))
(set_attr "base_cost" "0")])
;; Four word compare
(define_insn "cmpdi"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:DI 0 "general_operand" "rDQi")
(match_operand:DI 1 "general_operand" "rDQi")))]
""
{
rtx inops[4];
rtx exops[4][2];
rtx lb[1];
int i;
inops[0] = operands[0];
inops[1] = operands[1];
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
lb[0] = gen_label_rtx ();
for (i = 0; i < 3; i++)
{
if (CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0)
output_asm_insn ("tst\t%0", exops[i]);
else
output_asm_insn ("cmp\t%0,%1", exops[i]);
output_asm_insn ("bne\t%l0", lb);
}
if (CONST_INT_P (exops[3][1]) && INTVAL (exops[3][1]) == 0)
output_asm_insn ("tst\t%0", exops[3]);
else
output_asm_insn ("cmp\t%0,%1", exops[3]);
output_asm_label (lb[0]);
fputs (":\n", asm_out_file);
return "";
}
[(set (attr "length")
(symbol_ref "pdp11_cmp_length (operands, 2)"))
(set_attr "base_cost" "0")])
;; sob instruction
;;
;; This expander has to check for mode match because the doloop pass
@ -368,8 +435,8 @@
(define_insn_and_split "cbranch<mode>4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:PDPint 1 "general_operand" "g")
(match_operand:PDPint 2 "general_operand" "g")])
[(match_operand:QHSDint 1 "general_operand" "g")
(match_operand:QHSDint 2 "general_operand" "g")])
(label_ref (match_operand 3 "" ""))
(pc)))]
""
@ -473,12 +540,19 @@
"* return output_move_multiple (operands);"
[(set_attr "length" "4,6,8,16")])
;; That long string of "Z" constraints enforces the restriction that
;; a register source and auto increment or decrement destination must
;; not use the same register, because that case is not consistently
;; implemented across the PDP11 models.
;; TODO: the same should be applied to insn like add, but this is not
;; necessary yet because the incdec optimization pass does not apply
;; that optimization to 3-operand insns at the moment.
(define_insn "mov<mode>"
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
(match_operand:PDPint 1 "general_operand" "rRN,Qi,rRN,Qi"))]
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q")
(match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi"))]
""
""
[(set_attr "length" "2,4,4,6")])
[(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")])
;; This splits all the integer moves: DI and SI modes as well as
;; the simple machine operations.
@ -493,8 +567,8 @@
;; MOV clears V
(define_insn "*mov<mode>_<cc_cc>"
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
(match_operand:PDPint 1 "general_operand" "rRN,Qi,rRN,Qi"))
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q")
(match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi"))
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
"*
@ -504,7 +578,7 @@
return \"mov<PDPint:isfx>\t%1,%0\";
}"
[(set_attr "length" "2,4,4,6")])
[(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")])
;; movdf has unusually complicated condition code handling, because
;; load (into float register) updates the FCC, while store (from
@ -591,18 +665,98 @@
;; Expand a block move. We turn this into a move loop.
(define_expand "movmemhi"
[(match_operand:BLK 0 "general_operand" "=g")
(match_operand:BLK 1 "general_operand" "g")
(match_operand:HI 2 "immediate_operand" "i")
(match_operand:HI 3 "immediate_operand" "i")]
[(parallel [(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
(match_operand:BLK 0 "general_operand" "=g")
(match_operand:BLK 1 "general_operand" "g")
(match_operand:HI 2 "immediate_operand" "i")
(match_operand:HI 3 "immediate_operand" "i")
(clobber (mem:BLK (scratch)))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))])]
""
"
{
if (INTVAL (operands[2]) != 0)
expand_block_move (operands);
DONE;
int count;
count = INTVAL (operands[2]);
if (count == 0)
DONE;
if (INTVAL (operands [3]) >= 2 && (count & 1) == 0)
count >>= 1;
else
operands[3] = const1_rtx;
operands[2] = copy_to_mode_reg (HImode,
gen_rtx_CONST_INT (HImode, count));
/* Load BLKmode MEM addresses into scratch registers. */
operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
}")
;; Expand a block move. We turn this into a move loop.
(define_insn_and_split "movmemhi1"
[(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
(match_operand:HI 0 "register_operand" "+r")
(match_operand:HI 1 "register_operand" "+r")
(match_operand:HI 2 "register_operand" "+r")
(match_operand:HI 3 "immediate_operand" "i")
(clobber (mem:BLK (scratch)))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))]
""
"#"
"reload_completed"
[(parallel [(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
(match_dup 0)
(match_dup 1)
(match_dup 2)
(match_dup 3)
(clobber (mem:BLK (scratch)))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (reg:CC CC_REGNUM))])]
"")
(define_insn "movmemhi_nocc"
[(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
(match_operand:HI 0 "register_operand" "+r")
(match_operand:HI 1 "register_operand" "+r")
(match_operand:HI 2 "register_operand" "+r")
(match_operand:HI 3 "immediate_operand" "i")
(clobber (mem:BLK (scratch)))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
"*
{
rtx lb[2];
lb[0] = operands[2];
lb[1] = gen_label_rtx ();
output_asm_label (lb[1]);
fputs (\":\n\", asm_out_file);
if (INTVAL (operands[3]) > 1)
output_asm_insn (\"mov\t(%1)+,(%0)+\", operands);
else
output_asm_insn (\"movb\t(%1)+,(%0)+\", operands);
if (TARGET_40_PLUS)
output_asm_insn (\"sob\t%0,%l1\", lb);
else
{
output_asm_insn (\"dec\t%0\", lb);
output_asm_insn (\"bne\t%l1\", lb);
}
return \"\";
}"
[(set (attr "length")
(if_then_else (match_test "TARGET_40_PLUS")
(const_int 4)
(const_int 6)))])
;;- truncation instructions
@ -659,7 +813,8 @@
emit_move_insn (r, const0_rtx);
DONE;
}
else if (!rtx_equal_p (operands[0], operands[1]))
else if (!REG_P (operands[1]) ||
REGNO (operands[0]) != REGNO (operands[1]))
{
/* Alternatives 2 and 3 */
emit_move_insn (operands[0], const0_rtx);
@ -975,22 +1130,22 @@
inops[0] = operands[0];
inops[1] = operands[2];
pdp11_expand_operands (inops, exops, 2, NULL, either);
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
output_asm_insn (\"add\t%1,%0\", exops[0]);
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
{
output_asm_insn (\"add\t%1,%0\", exops[1]);
output_asm_insn (\"adc\t%0\", exops[0]);
}
if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
{
output_asm_insn (\"add\t%1,%0\", exops[2]);
output_asm_insn (\"adc\t%0\", exops[1]);
output_asm_insn (\"adc\t%0\", exops[0]);
}
if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
{
output_asm_insn (\"add\t%1,%0\", exops[3]);
output_asm_insn (\"adc\t%0\", exops[2]);
@ -1037,11 +1192,11 @@
inops[0] = operands[0];
inops[1] = operands[2];
pdp11_expand_operands (inops, exops, 2, NULL, either);
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
output_asm_insn (\"add\t%1,%0\", exops[0]);
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
{
output_asm_insn (\"add\t%1,%0\", exops[1]);
output_asm_insn (\"adc\t%0\", exops[0]);
@ -1169,22 +1324,22 @@
inops[0] = operands[0];
inops[1] = operands[2];
pdp11_expand_operands (inops, exops, 2, NULL, either);
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
output_asm_insn (\"sub\t%1,%0\", exops[0]);
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
{
output_asm_insn (\"sub\t%1,%0\", exops[1]);
output_asm_insn (\"sbc\t%0\", exops[0]);
}
if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
{
output_asm_insn (\"sub\t%1,%0\", exops[2]);
output_asm_insn (\"sbc\t%0\", exops[1]);
output_asm_insn (\"sbc\t%0\", exops[0]);
}
if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
{
output_asm_insn (\"sub\t%1,%0\", exops[3]);
output_asm_insn (\"sbc\t%0\", exops[2]);
@ -1222,11 +1377,11 @@
inops[0] = operands[0];
inops[1] = operands[2];
pdp11_expand_operands (inops, exops, 2, NULL, either);
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
output_asm_insn (\"sub\t%1,%0\", exops[0]);
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
{
output_asm_insn (\"sub\t%1,%0\", exops[1]);
output_asm_insn (\"sbc\t%0\", exops[0]);
@ -1702,9 +1857,11 @@
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
{
rtx inops[2];
rtx exops[4][2];
pdp11_expand_operands (operands, exops, 1, NULL, either);
inops[0] = operands[0];
pdp11_expand_operands (inops, exops, 1, 4, NULL, big);
output_asm_insn (\"com\t%0\", exops[3]);
output_asm_insn (\"com\t%0\", exops[2]);
@ -1738,9 +1895,11 @@
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
{
rtx exops[2][2];
pdp11_expand_operands (operands, exops, 1, NULL, either);
rtx inops[2];
rtx exops[4][2];
inops[0] = operands[0];
pdp11_expand_operands (inops, exops, 1, 2, NULL, big);
output_asm_insn (\"com\t%0\", exops[1]);
output_asm_insn (\"com\t%0\", exops[0]);
@ -2046,10 +2205,13 @@
(clobber (reg:CC CC_REGNUM))]
""
{
rtx inops[2];
rtx exops[2][2];
rtx t;
pdp11_expand_operands (operands, exops, 2, NULL, either);
inops[0] = operands[0];
inops[1] = operands[1];
pdp11_expand_operands (inops, exops, 2, 2, NULL, either);
t = exops[0][0];
exops[0][0] = exops[1][0];

View File

@ -68,4 +68,4 @@ Use UNIX assembler syntax.
mlra
Target Report Mask(LRA)
Use LRA register allocator
Use LRA register allocator.

View File

@ -18,6 +18,10 @@
MULTILIB_OPTIONS = msoft-float
# Optimize for space
LIBGCC2_CFLAGS = -Os
CRTSTUFF_T_CFLAGS = -Os
# Because the pdp11 POINTER_SIZE is only 16, in dwarf2out.c,
# DWARF_ARANGES_PAD_SIZE is 0, thus a loop in output_aranges that checks
# (i < (unsigned) DWARF_ARANGES_PAD_SIZE) elicits a warning that the

View File

@ -14115,7 +14115,7 @@ information on callsites that were inlined, along with callsites
that were not inlined.
By default, the dump will contain messages about successful
optimizations (equivalent to @option {-optimized}) together with
optimizations (equivalent to @option{-optimized}) together with
low-level details about the analysis.
@item -fdump-lang-all

View File

@ -1,3 +1,345 @@
2018-11-08 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c-c++-common/task-reduction-8.c (bar): Add
in_reduction clause for s[0].
* affinity.c (gomp_display_affinity_place): New function.
* affinity-fmt.c: New file.
* alloc.c (gomp_aligned_alloc, gomp_aligned_free): New functions.
* config/linux/affinity.c (gomp_display_affinity_place): New function.
* config/nvptx/icv-device.c (omp_get_num_teams, omp_get_team_num):
Move these functions to ...
* config/nvptx/teams.c: ... here. New file.
* config/nvptx/target.c (omp_pause_resource, omp_pause_resource_all):
New functions.
* config/nvptx/team.c (gomp_team_start, gomp_pause_host): New
functions.
* configure.ac: Check for aligned_alloc, posix_memalign, memalign
and _aligned_malloc.
(HAVE_UNAME, HAVE_GETHOSTNAME, HAVE_GETPID): Add new tests.
* configure.tgt: Add -DUSING_INITIAL_EXEC_TLS to XCFLAGS for Linux.
* env.c (gomp_display_affinity_var, gomp_affinity_format_var,
gomp_affinity_format_len): New variables.
(parse_schedule): Parse monotonic and nonmonotonic modifiers in
OMP_SCHEDULE variable. Set GFS_MONOTONIC for monotonic schedules.
(handle_omp_display_env): Display monotonic/nonmonotonic schedule
modifiers. Display (non-default) chunk sizes. Print
OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT.
(initialize_env): Don't call pthread_attr_setdetachstate. Handle
OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT env vars.
* fortran.c: Include stdio.h and string.h.
(omp_pause_resource, omp_pause_resource_all): Add ialias_redirect.
(omp_get_schedule_, omp_get_schedule_8_): Mask off GFS_MONOTONIC bit.
(omp_set_affinity_format_, omp_get_affinity_format_,
omp_display_affinity_, omp_capture_affinity_, omp_pause_resource_,
omp_pause_resource_all_): New functions.
* icv.c (omp_set_schedule): Mask off omp_sched_monotonic bit in
switch.
* icv-device.c (omp_get_num_teams, omp_get_team_num): Move these
functions to ...
* teams.c: ... here. New file.
* libgomp_g.h: Include gstdint.h.
(GOMP_loop_nonmonotonic_runtime_start,
GOMP_loop_maybe_nonmonotonic_runtime_start, GOMP_loop_start,
GOMP_loop_ordered_start, GOMP_loop_nonmonotonic_runtime_next,
GOMP_loop_maybe_nonmonotonic_runtime_next, GOMP_loop_doacross_start,
GOMP_parallel_loop_nonmonotonic_runtime,
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
GOMP_loop_ull_nonmonotonic_runtime_start,
GOMP_loop_ull_maybe_nonmonotonic_runtime_start, GOMP_loop_ull_start,
GOMP_loop_ull_ordered_start, GOMP_loop_ull_nonmonotonic_runtime_next,
GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
GOMP_loop_ull_doacross_start, GOMP_parallel_reductions,
GOMP_taskwait_depend, GOMP_taskgroup_reduction_register,
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
GOMP_teams_reg): Declare.
* libgomp.h (GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC): Define unless
gomp_aligned_alloc uses fallback implementation.
(gomp_aligned_alloc, gomp_aligned_free): Declare.
(enum gomp_schedule_type): Add GFS_MONOTONIC.
(struct gomp_doacross_work_share): Add extra field.
(struct gomp_work_share): Add task_reductions field.
(struct gomp_taskgroup): Add workshare and reductions fields.
(GOMP_NEEDS_THREAD_HANDLE): Define if needed.
(gomp_thread_handle): New typedef.
(gomp_display_affinity_place, gomp_set_affinity_format,
gomp_display_string, gomp_display_affinity,
gomp_display_affinity_thread): Declare.
(gomp_doacross_init, gomp_doacross_ull_init): Add size_t argument.
(gomp_parallel_reduction_register, gomp_workshare_taskgroup_start,
gomp_workshare_task_reduction_register): Declare.
(gomp_team_start): Add taskgroup argument.
(gomp_pause_host): Declare.
(gomp_init_work_share, gomp_work_share_start): Change bool argument
to size_t.
(gomp_thread_self, gomp_thread_to_pthread_t): New inline functions.
* libgomp.map (GOMP_5.0): Export GOMP_loop_start,
GOMP_loop_ordered_start, GOMP_loop_doacross_start,
GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
GOMP_loop_ull_doacross_start,
GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
GOMP_loop_maybe_nonmonotonic_runtime_next,
GOMP_loop_maybe_nonmonotonic_runtime_start,
GOMP_loop_nonmonotonic_runtime_next,
GOMP_loop_nonmonotonic_runtime_start,
GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
GOMP_loop_ull_nonmonotonic_runtime_next,
GOMP_loop_ull_nonmonotonic_runtime_start,
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
GOMP_parallel_loop_nonmonotonic_runtime, GOMP_parallel_reductions,
GOMP_taskgroup_reduction_register,
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
GOMP_teams_reg and GOMP_taskwait_depend.
(OMP_5.0): Export omp_pause_resource{,_all}{,_},
omp_{capture,display}_affinity{,_}, and
omp_[gs]et_affinity_format{,_}.
* loop.c: Include string.h.
(GOMP_loop_runtime_next): Add ialias.
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
(gomp_loop_static_start, gomp_loop_dynamic_start,
gomp_loop_guided_start, gomp_loop_ordered_static_start,
gomp_loop_ordered_dynamic_start, gomp_loop_ordered_guided_start,
gomp_loop_doacross_static_start, gomp_loop_doacross_dynamic_start,
gomp_loop_doacross_guided_start): Adjust gomp_work_share_start
or gomp_doacross_init callers.
(gomp_adjust_sched, GOMP_loop_start, GOMP_loop_ordered_start,
GOMP_loop_doacross_start): New functions.
(GOMP_loop_runtime_start, GOMP_loop_ordered_runtime_start,
GOMP_loop_doacross_runtime_start, GOMP_parallel_loop_runtime_start):
Mask off GFS_MONOTONIC bit.
(GOMP_loop_maybe_nonmonotonic_runtime_next,
GOMP_loop_maybe_nonmonotonic_runtime_start,
GOMP_loop_nonmonotonic_runtime_next,
GOMP_loop_nonmonotonic_runtime_start,
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
GOMP_parallel_loop_nonmonotonic_runtime): New aliases or wrapper
functions.
(gomp_parallel_loop_start): Pass NULL as taskgroup to
gomp_team_start.
* loop_ull.c: Include string.h.
(GOMP_loop_ull_runtime_next): Add ialias.
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
(gomp_loop_ull_static_start, gomp_loop_ull_dynamic_start,
gomp_loop_ull_guided_start, gomp_loop_ull_ordered_static_start,
gomp_loop_ull_ordered_dynamic_start,
gomp_loop_ull_ordered_guided_start,
gomp_loop_ull_doacross_static_start,
gomp_loop_ull_doacross_dynamic_start,
gomp_loop_ull_doacross_guided_start): Adjust gomp_work_share_start
and gomp_doacross_ull_init callers.
(gomp_adjust_sched, GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
GOMP_loop_ull_doacross_start): New functions.
(GOMP_loop_ull_runtime_start,
GOMP_loop_ull_ordered_runtime_start,
GOMP_loop_ull_doacross_runtime_start): Mask off GFS_MONOTONIC bit.
(GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
GOMP_loop_ull_nonmonotonic_runtime_next,
GOMP_loop_ull_nonmonotonic_runtime_start): Likewise.
* Makefile.am (libgomp_la_SOURCES): Add teams.c and affinity-fmt.c.
* omp.h.in (enum omp_sched_t): Add omp_sched_monotonic.
(omp_pause_resource_t, omp_depend_t): New typedefs.
(enum omp_lock_hint_t): Renamed to ...
(enum omp_sync_hint_t): ... this. Define omp_sync_hint_*
enumerators using numbers and omp_lock_hint_* as their aliases.
(omp_lock_hint_t): New typedef. Rename to ...
(omp_sync_hint_t): ... this.
(omp_init_lock_with_hint, omp_init_nest_lock_with_hint): Use
omp_sync_hint_t instead of omp_lock_hint_t.
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
Declare.
(omp_target_is_present, omp_target_disassociate_ptr):
Change first argument from void * to const void *.
(omp_target_memcpy, omp_target_memcpy_rect): Change second argument
from void * to const void *.
(omp_target_associate_ptr): Change first and second arguments from
void * to const void *.
* omp_lib.f90.in (omp_pause_resource_kind, omp_pause_soft,
omp_pause_hard): New parameters.
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
New interfaces.
* omp_lib.h.in (omp_pause_resource_kind, omp_pause_soft,
omp_pause_hard): New parameters.
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
New externals.
* ordered.c (gomp_doacross_init, gomp_doacross_ull_init): Add
EXTRA argument. If not needed to prepare array, if extra is 0,
clear ws->doacross, otherwise allocate just doacross structure and
extra payload. If array is needed, allocate also extra payload.
(GOMP_doacross_post, GOMP_doacross_wait, GOMP_doacross_ull_post,
GOMP_doacross_ull_wait): Handle doacross->array == NULL like
doacross == NULL.
* parallel.c (GOMP_parallel_start): Pass NULL as taskgroup to
gomp_team_start.
(GOMP_parallel): Likewise. Formatting fix.
(GOMP_parallel_reductions): New function.
(GOMP_cancellation_point): If taskgroup has workshare
flag set, check cancelled of prev taskgroup if any.
(GOMP_cancel): If taskgroup has workshare flag set, set cancelled
on prev taskgroup if any.
* sections.c: Include string.h.
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
(GOMP_sections_start): Adjust gomp_work_share_start caller.
(GOMP_sections2_start): New function.
(GOMP_parallel_sections_start, GOMP_parallel_sections):
Pass NULL as taskgroup to gomp_team_start.
* single.c (GOMP_single_start, GOMP_single_copy_start): Adjust
gomp_work_share_start callers.
* target.c (GOMP_target_update_ext, GOMP_target_enter_exit_data):
If taskgroup has workshare flag set, check cancelled on prev
taskgroup if any. Guard all cancellation tests with
gomp_cancel_var test.
(omp_target_is_present, omp_target_disassociate_ptr):
Change ptr argument from void * to const void *.
(omp_target_memcpy): Change src argument from void * to const void *.
(omp_target_memcpy_rect): Likewise.
(omp_target_memcpy_rect_worker): Likewise. Use const char * casts
instead of char * where needed.
(omp_target_associate_ptr): Change host_ptr and device_ptr arguments
from void * to const void *.
(omp_pause_resource, omp_pause_resource_all): New functions.
* task.c (gomp_task_handle_depend): Handle new depend array format
in addition to the old. Handle mutexinoutset kinds the same as
inout for now, handle unspecified kinds.
(gomp_create_target_task): If taskgroup has workshare flag set, check
cancelled on prev taskgroup if any. Guard all cancellation tests with
gomp_cancel_var test. Handle new depend array format count in
addition to the old.
(GOMP_task): Likewise. Adjust function comment.
(gomp_task_run_pre): If taskgroup has workshare flag set, check
cancelled on prev taskgroup if any. Guard all cancellation tests with
gomp_cancel_var test.
(GOMP_taskwait_depend): New function.
(gomp_task_maybe_wait_for_dependencies): Handle new depend array
format in addition to the old. Handle mutexinoutset kinds the same as
inout for now, handle unspecified kinds. Fix a function comment typo.
(gomp_taskgroup_init): New function.
(GOMP_taskgroup_start): Use it.
(gomp_reduction_register, gomp_create_artificial_team,
GOMP_taskgroup_reduction_register,
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
gomp_parallel_reduction_register,
gomp_workshare_task_reduction_register,
gomp_workshare_taskgroup_start,
GOMP_workshare_task_reduction_unregister): New functions.
* taskloop.c (GOMP_taskloop): If taskgroup has workshare flag set,
check cancelled on prev taskgroup if any. Guard all cancellation
tests with gomp_cancel_var test. Handle GOMP_TASK_FLAG_REDUCTION flag
by calling GOMP_taskgroup_reduction_register.
* team.c (gomp_thread_attr): Remove comment.
(struct gomp_thread_start_data): Add handle field.
(gomp_thread_start): Call pthread_detach.
(gomp_new_team): Adjust gomp_init_work_share caller.
(gomp_free_pool_helper): Call pthread_detach.
(gomp_team_start): Add taskgroup argument, initialize implicit
tasks' taskgroup field to that. Don't call
pthread_attr_setdetachstate. Handle OMP_DISPLAY_AFFINITY env var.
(gomp_team_end): Determine nesting by thr->ts.level != 0
rather than thr->ts.team != NULL.
(gomp_pause_pool_helper, gomp_pause_host): New functions.
* work.c (alloc_work_share): Use gomp_aligned_alloc instead of
gomp_malloc if GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC is defined.
(gomp_init_work_share): Change ORDERED argument from bool to size_t,
if more than 1 allocate also extra payload at the end of array. Never
keep ordered_team_ids NULL, set it to inline_ordered_team_ids instead.
(gomp_work_share_start): Change ORDERED argument from bool to size_t,
return true instead of ws.
* Makefile.in: Regenerated.
* configure: Regenerated.
* config.h.in: Regenerated.
* testsuite/libgomp.c/cancel-for-2.c (foo): Use cancel modifier
in some cases.
* testsuite/libgomp.c-c++-common/cancel-parallel-1.c: New test.
* testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c: New test.
* testsuite/libgomp.c-c++-common/depend-iterator-1.c: New test.
* testsuite/libgomp.c-c++-common/depend-iterator-2.c: New test.
* testsuite/libgomp.c-c++-common/depend-mutexinout-1.c: New test.
* testsuite/libgomp.c-c++-common/depend-mutexinout-2.c: New test.
* testsuite/libgomp.c-c++-common/depobj-1.c: New test.
* testsuite/libgomp.c-c++-common/display-affinity-1.c: New test.
* testsuite/libgomp.c-c++-common/for-10.c: New test.
* testsuite/libgomp.c-c++-common/for-11.c: New test.
* testsuite/libgomp.c-c++-common/for-12.c: New test.
* testsuite/libgomp.c-c++-common/for-13.c: New test.
* testsuite/libgomp.c-c++-common/for-14.c: New test.
* testsuite/libgomp.c-c++-common/for-15.c: New test.
* testsuite/libgomp.c-c++-common/for-2.h: If CONDNE macro is defined,
define a different N(test), don't define N(f0) to N(f14), but instead
define N(f20) to N(f34) using != comparisons.
* testsuite/libgomp.c-c++-common/for-7.c: New test.
* testsuite/libgomp.c-c++-common/for-8.c: New test.
* testsuite/libgomp.c-c++-common/for-9.c: New test.
* testsuite/libgomp.c-c++-common/master-combined-1.c: New test.
* testsuite/libgomp.c-c++-common/pause-1.c: New test.
* testsuite/libgomp.c-c++-common/pause-2.c: New test.
* testsuite/libgomp.c-c++-common/pr66199-10.c: New test.
* testsuite/libgomp.c-c++-common/pr66199-11.c: New test.
* testsuite/libgomp.c-c++-common/pr66199-12.c: New test.
* testsuite/libgomp.c-c++-common/pr66199-13.c: New test.
* testsuite/libgomp.c-c++-common/pr66199-14.c: New test.
* testsuite/libgomp.c-c++-common/simd-1.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-1.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-2.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-11.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-12.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-1.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-2.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-3.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-4.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-5.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-6.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-7.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-8.c: New test.
* testsuite/libgomp.c-c++-common/task-reduction-9.c: New test.
* testsuite/libgomp.c-c++-common/taskwait-depend-1.c: New test.
* testsuite/libgomp.c++/depend-1.C: New test.
* testsuite/libgomp.c++/depend-iterator-1.C: New test.
* testsuite/libgomp.c++/depobj-1.C: New test.
* testsuite/libgomp.c++/for-16.C: New test.
* testsuite/libgomp.c++/for-21.C: New test.
* testsuite/libgomp.c++/for-22.C: New test.
* testsuite/libgomp.c++/for-23.C: New test.
* testsuite/libgomp.c++/for-24.C: New test.
* testsuite/libgomp.c++/for-25.C: New test.
* testsuite/libgomp.c++/for-26.C: New test.
* testsuite/libgomp.c++/taskloop-reduction-1.C: New test.
* testsuite/libgomp.c++/taskloop-reduction-2.C: New test.
* testsuite/libgomp.c++/taskloop-reduction-3.C: New test.
* testsuite/libgomp.c++/taskloop-reduction-4.C: New test.
* testsuite/libgomp.c++/task-reduction-10.C: New test.
* testsuite/libgomp.c++/task-reduction-11.C: New test.
* testsuite/libgomp.c++/task-reduction-12.C: New test.
* testsuite/libgomp.c++/task-reduction-13.C: New test.
* testsuite/libgomp.c++/task-reduction-14.C: New test.
* testsuite/libgomp.c++/task-reduction-15.C: New test.
* testsuite/libgomp.c++/task-reduction-16.C: New test.
* testsuite/libgomp.c++/task-reduction-17.C: New test.
* testsuite/libgomp.c++/task-reduction-18.C: New test.
* testsuite/libgomp.c++/task-reduction-19.C: New test.
* testsuite/libgomp.c/task-reduction-1.c: New test.
* testsuite/libgomp.c++/task-reduction-1.C: New test.
* testsuite/libgomp.c/task-reduction-2.c: New test.
* testsuite/libgomp.c++/task-reduction-2.C: New test.
* testsuite/libgomp.c++/task-reduction-3.C: New test.
* testsuite/libgomp.c++/task-reduction-4.C: New test.
* testsuite/libgomp.c++/task-reduction-5.C: New test.
* testsuite/libgomp.c++/task-reduction-6.C: New test.
* testsuite/libgomp.c++/task-reduction-7.C: New test.
* testsuite/libgomp.c++/task-reduction-8.C: New test.
* testsuite/libgomp.c++/task-reduction-9.C: New test.
* testsuite/libgomp.c/teams-1.c: New test.
* testsuite/libgomp.c/teams-2.c: New test.
* testsuite/libgomp.c/thread-limit-4.c: New test.
* testsuite/libgomp.c/thread-limit-5.c: New test.
* testsuite/libgomp.fortran/display-affinity-1.f90: New test.
2018-11-06 Chung-Lin Tang <cltang@codesourcery.com>
* oacc-mem.c (memcpy_tofrom_device): New function, combined from

View File

@ -45,7 +45,8 @@ unsigned long long int
bar (int z, int *a, unsigned long long int *b, int *s)
{
unsigned long long int x = 1;
#pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
#pragma omp taskloop reduction (*:x) in_reduction (*:b[0]) \
in_reduction (+:s[0])
for (int i = z; i < z + 8; i++)
{
#pragma omp task in_reduction (*:x)