aboutsummaryrefslogtreecommitdiff
path: root/gcc/internal-fn.c
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2016-11-22 19:57:29 +0300
committerAlexander Monakov <amonakov@gcc.gnu.org>2016-11-22 19:57:29 +0300
commit9669b00bfb16ced0d5bf09b9e016e9ffa8be4219 (patch)
tree36fcb281bf349333f6b5a61f5076bda2cef9590a /gcc/internal-fn.c
parent9435cd52b3180e6171c0f738fe7e8ffd79dd9b28 (diff)
downloadgcc-9669b00bfb16ced0d5bf09b9e016e9ffa8be4219.zip
gcc-9669b00bfb16ced0d5bf09b9e016e9ffa8be4219.tar.gz
gcc-9669b00bfb16ced0d5bf09b9e016e9ffa8be4219.tar.bz2
OpenMP offloading to NVPTX: middle-end changes
* internal-fn.c (expand_GOMP_SIMT_LANE): New. (expand_GOMP_SIMT_VF): New. (expand_GOMP_SIMT_LAST_LANE): New. (expand_GOMP_SIMT_ORDERED_PRED): New. (expand_GOMP_SIMT_VOTE_ANY): New. (expand_GOMP_SIMT_XCHG_BFLY): New. (expand_GOMP_SIMT_XCHG_IDX): New. * internal-fn.def (GOMP_SIMT_LANE): New. (GOMP_SIMT_VF): New. (GOMP_SIMT_LAST_LANE): New. (GOMP_SIMT_ORDERED_PRED): New. (GOMP_SIMT_VOTE_ANY): New. (GOMP_SIMT_XCHG_BFLY): New. (GOMP_SIMT_XCHG_IDX): New. * omp-low.c (omp_maybe_offloaded_ctx): New, outlined from... (create_omp_child_function): ...here. Set "omp target entrypoint" or "omp declare target" attribute based on is_gimple_omp_offloaded. (omp_max_simt_vf): New. Use it... (omp_max_vf): ...here. (lower_rec_input_clauses): Add reduction lowering for SIMT execution. (lower_lastprivate_clauses): Likewise, for "lastprivate" lowering. (lower_omp_ordered): Likewise, for "ordered" lowering. (expand_omp_simd): Add SIMT transforms. (pass_data_lower_omp): Add PROP_gimple_lomp_dev. (execute_omp_device_lower): New. (pass_data_omp_device_lower): New. (pass_omp_device_lower): New pass. (make_pass_omp_device_lower): New. * passes.def (pass_omp_device_lower): Position new pass. * tree-pass.h (PROP_gimple_lomp_dev): Define. (make_pass_omp_device_lower): Declare. From-SVN: r242710
Diffstat (limited to 'gcc/internal-fn.c')
-rw-r--r--gcc/internal-fn.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index ca347c5..6cd8522 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -158,6 +158,132 @@ expand_ANNOTATE (internal_fn, gcall *)
gcc_unreachable ();
}
+/* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
+ without SIMT execution this should be expanded in omp_device_lower pass. */
+
+static void
+expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ gcc_assert (targetm.have_omp_simt_lane ());
+ emit_insn (targetm.gen_omp_simt_lane (target));
+}
+
+/* This should get expanded in omp_device_lower pass. */
+
+static void
+expand_GOMP_SIMT_VF (internal_fn, gcall *)
+{
+ gcc_unreachable ();
+}
+
+/* Lane index of the first SIMT lane that supplies a non-zero argument.
+ This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
+ lane that executed the last iteration for handling OpenMP lastprivate. */
+
+static void
+expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx cond = expand_normal (gimple_call_arg (stmt, 0));
+ machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ struct expand_operand ops[2];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], cond, mode);
+ gcc_assert (targetm.have_omp_simt_last_lane ());
+ expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
+}
+
+/* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
+
+static void
+expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
+ machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ struct expand_operand ops[2];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], ctr, mode);
+ gcc_assert (targetm.have_omp_simt_ordered ());
+ expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
+}
+
+/* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
+ any lane supplies a non-zero argument. */
+
+static void
+expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx cond = expand_normal (gimple_call_arg (stmt, 0));
+ machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ struct expand_operand ops[2];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], cond, mode);
+ gcc_assert (targetm.have_omp_simt_vote_any ());
+ expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
+}
+
+/* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
+ is destination lane index XOR given offset. */
+
+static void
+expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx src = expand_normal (gimple_call_arg (stmt, 0));
+ rtx idx = expand_normal (gimple_call_arg (stmt, 1));
+ machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ struct expand_operand ops[3];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], src, mode);
+ create_input_operand (&ops[2], idx, SImode);
+ gcc_assert (targetm.have_omp_simt_xchg_bfly ());
+ expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
+}
+
+/* Exchange between SIMT lanes according to given source lane index. */
+
+static void
+expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs)
+ return;
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx src = expand_normal (gimple_call_arg (stmt, 0));
+ rtx idx = expand_normal (gimple_call_arg (stmt, 1));
+ machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ struct expand_operand ops[3];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], src, mode);
+ create_input_operand (&ops[2], idx, SImode);
+ gcc_assert (targetm.have_omp_simt_xchg_idx ());
+ expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
+}
+
/* This should get expanded in adjust_simduid_builtins. */
static void