From f2ee7edfe370c37fcf79f26154e95519b1aea3fa Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 8 Nov 2018 22:07:23 +0100 Subject: svn merge -r265930:265934 svn+ssh://gcc.gnu.org/svn/gcc/trunk From-SVN: r265937 --- gcc/ChangeLog | 398 +++++++++++++++++ gcc/common/config/arm/arm-common.c | 21 +- gcc/config/arm/arm-cpus.in | 23 +- gcc/config/arm/arm-generic.md | 6 +- gcc/config/arm/arm-protos.h | 15 + gcc/config/arm/arm-tables.opt | 9 - gcc/config/arm/arm-tune.md | 1 - gcc/config/arm/parsecpu.awk | 63 ++- gcc/config/pdp11/constraints.md | 29 ++ gcc/config/pdp11/pdp11-protos.h | 6 +- gcc/config/pdp11/pdp11.c | 484 +++++++++------------ gcc/config/pdp11/pdp11.h | 106 +++-- gcc/config/pdp11/pdp11.md | 268 +++++++++--- gcc/config/pdp11/pdp11.opt | 2 +- gcc/config/pdp11/t-pdp11 | 4 + gcc/doc/invoke.texi | 2 +- libgomp/ChangeLog | 342 +++++++++++++++ .../libgomp.c-c++-common/task-reduction-8.c | 3 +- 18 files changed, 1374 insertions(+), 408 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3e77f3..e131f62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,401 @@ +2018-11-08 Paul Koning + + * 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. + (cbranch4): Change to apply to SI and DI modes as well. + (mov): Change constraints to enforce that push/pop + destination cannot use the same register as source. + (*mov): 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 + + * 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 + + * 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 ::test): Allow + GIMPLE_OMP_TEAMS. + (is_a_helper ::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) : 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) : 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 PR ipa/86395 diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c index 76c357b..32cf36e 100644 --- a/gcc/common/config/arm/arm-common.c +++ b/gcc/common/config/arm/arm-common.c @@ -309,7 +309,16 @@ arm_print_hint_for_cpu_option (const char *target, { auto_vec 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) diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in index b3163a9..1def1ca 100644 --- a/gcc/config/arm/arm-cpus.in +++ b/gcc/config/arm/arm-cpus.in @@ -617,6 +617,7 @@ end arch iwmmxt2 # format: # begin cpu # [cname ] +# [alias +] # [tune for ] # [tune flags ] # architecture @@ -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 diff --git a/gcc/config/arm/arm-generic.md b/gcc/config/arm/arm-generic.md index 81200fa..da97303 100644 --- a/gcc/config/arm/arm-generic.md +++ b/gcc/config/arm/arm-generic.md @@ -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") diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index cea9866..8d6d2395 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -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; }; diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt index ceac4b4..cd49636 100644 --- a/gcc/config/arm/arm-tables.opt +++ b/gcc/config/arm/arm-tables.opt @@ -34,15 +34,6 @@ 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) EnumValue diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md index 2bd7e87..bbe09cf 100644 --- a/gcc/config/arm/arm-tune.md +++ b/gcc/config/arm/arm-tune.md @@ -22,7 +22,6 @@ (define_attr "tune" "arm8,arm810,strongarm, - strongarm110,strongarm1100,strongarm1110, fa526,fa626,arm7tdmi, arm7tdmis,arm710t,arm720t, arm740t,arm9,arm9tdmi, diff --git a/gcc/config/arm/parsecpu.awk b/gcc/config/arm/parsecpu.awk index aabe1b0..ba2dee5 100644 --- a/gcc/config/arm/parsecpu.awk +++ b/gcc/config/arm/parsecpu.awk @@ -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 +") + 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 ") if (cpu_name != "") { diff --git a/gcc/config/pdp11/constraints.md b/gcc/config/pdp11/constraints.md index 33882ed..d821af3 100644 --- a/gcc/config/pdp11/constraints.md +++ b/gcc/config/pdp11/constraints.md @@ -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)")) + diff --git a/gcc/config/pdp11/pdp11-protos.h b/gcc/config/pdp11/pdp11-protos.h index 0ed61ea..135d437 100644 --- a/gcc/config/pdp11/pdp11-protos.h +++ b/gcc/config/pdp11/pdp11-protos.h @@ -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 */ diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 06129f1..0019efe 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -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); } -} - -/* 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! + if (frame_pointer_needed) + emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); - switching to kernel is probably more expensive, so we'll leave it - like this and not use the second set of registers... + /* Make local variable space. */ + if (fsize) + emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (-fsize))); +} - 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. */ - - 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 - { - emit_move_insn (via_ac, x); - emit_move_insn (reg, via_ac); - } - } + /* Restore registers via pops. */ - 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. - - 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 = 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); - for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--) - if (pdp11_saved_regno (regno) - && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed)) + if (LOAD_FPU_REG_P (regno)) + emit_move_insn (reg, x); + else { - 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; + emit_move_insn (via_ac, x); + emit_move_insn (reg, via_ac); } - } - - /* 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); - } + 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); + } - 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; - - /* 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)); + 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); - /* 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 diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index d65d8f5..92c237b 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -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. */ diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 773715d..fc5efc7 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -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\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 "cbranch4" [(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" - [(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_" - [(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\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]; diff --git a/gcc/config/pdp11/pdp11.opt b/gcc/config/pdp11/pdp11.opt index 5da3b39..79fca28 100644 --- a/gcc/config/pdp11/pdp11.opt +++ b/gcc/config/pdp11/pdp11.opt @@ -68,4 +68,4 @@ Use UNIX assembler syntax. mlra Target Report Mask(LRA) -Use LRA register allocator +Use LRA register allocator. diff --git a/gcc/config/pdp11/t-pdp11 b/gcc/config/pdp11/t-pdp11 index ab01bff..467d228 100644 --- a/gcc/config/pdp11/t-pdp11 +++ b/gcc/config/pdp11/t-pdp11 @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 24136eb..4ff3a150 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 81bfc77..636cb49 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,345 @@ +2018-11-08 Jakub Jelinek + + * 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 * oacc-mem.c (memcpy_tofrom_device): New function, combined from diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c index 7b0859d..52d238a 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c @@ -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) -- cgit v1.1