From 77d7f6ee98a46fa123394a5073f44ae591e26c76 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 27 Oct 2015 17:49:05 +0100
Subject: [PATCH 8/9] HSA: correctly handle memory order for atomic insns
gcc/ChangeLog:
2015-10-27 Martin Liska <mliska@suse.cz>
* hsa-gen.c (hsa_insn_signal::hsa_insn_signal): Use modified
ctor of hsa_insn_atomic.
(gen_hsa_insns_for_kernel_call): Likewise.
(get_memory_order_name): New function.
(get_memory_order): New function.
(gen_hsa_ternary_atomic_for_builtin): Fill up memory order.
(gen_hsa_insns_for_call): Likewise.
* hsa.h: Declare new argument for
hsa_insn_atomic::hsa_insn_atomic.
---
gcc/hsa-gen.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
gcc/hsa.h | 2 +-
2 files changed, 108 insertions(+), 18 deletions(-)
@@ -1429,11 +1429,12 @@ hsa_insn_mem::operator new (size_t)
hsa_insn_atomic::hsa_insn_atomic (int nops, int opc,
enum BrigAtomicOperation aop,
- BrigType16_t t, hsa_op_base *arg0,
+ BrigType16_t t, BrigMemoryOrder memorder,
+ hsa_op_base *arg0,
hsa_op_base *arg1, hsa_op_base *arg2,
hsa_op_base *arg3)
: hsa_insn_mem (nops, opc, t, arg0, arg1, arg2, arg3), m_atomicop (aop),
- m_memoryorder (BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE),
+ m_memoryorder (memorder),
m_memoryscope (BRIG_MEMORY_SCOPE_SYSTEM)
{
gcc_checking_assert (opc == BRIG_OPCODE_ATOMICNORET ||
@@ -1462,7 +1463,8 @@ hsa_insn_signal::hsa_insn_signal (int nops, int opc,
BrigType16_t t, hsa_op_base *arg0,
hsa_op_base *arg1, hsa_op_base *arg2,
hsa_op_base *arg3)
- : hsa_insn_atomic (nops, opc, sop, t, arg0, arg1, arg2, arg3)
+ : hsa_insn_atomic (nops, opc, sop, t, BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE,
+ arg0, arg1, arg2, arg3)
{
}
@@ -4028,10 +4030,9 @@ gen_hsa_insns_for_kernel_call (hsa_bb *hbb, gcall *call)
/* Store 5122 << 16 + 1 to packet->header. */
c = new hsa_op_immed (70658, BRIG_TYPE_U32);
- hsa_insn_atomic *atomic = new hsa_insn_atomic (2, BRIG_OPCODE_ATOMICNORET,
- BRIG_ATOMIC_ST, BRIG_TYPE_B32,
- addr, c);
- atomic->m_memoryorder = BRIG_MEMORY_ORDER_SC_RELEASE;
+ hsa_insn_atomic *atomic = new hsa_insn_atomic
+ (2, BRIG_OPCODE_ATOMICNORET, BRIG_ATOMIC_ST, BRIG_TYPE_B32,
+ BRIG_MEMORY_ORDER_SC_RELEASE, addr, c);
atomic->m_memoryscope = BRIG_MEMORY_SCOPE_SYSTEM;
hbb->append_insn (atomic);
@@ -4145,6 +4146,54 @@ get_address_from_value (tree val, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map)
}
}
+/* Return strign for MEMMODEL. */
+
+static const char *
+get_memory_order_name (unsigned memmodel)
+{
+ switch (memmodel)
+ {
+ case __ATOMIC_RELAXED:
+ return "__ATOMIC_RELAXED";
+ case __ATOMIC_CONSUME:
+ return "__ATOMIC_CONSUME";
+ case __ATOMIC_ACQUIRE:
+ return "__ATOMIC_ACQUIRE";
+ case __ATOMIC_RELEASE:
+ return "__ATOMIC_RELEASE";
+ case __ATOMIC_ACQ_REL:
+ return "__ATOMIC_ACQ_REL";
+ case __ATOMIC_SEQ_CST:
+ return "__ATOMIC_SEQ_CST";
+ default:
+ return NULL;
+ }
+}
+
+/* Return memory order according to predefined __atomic memory model
+ constants. LOCATION is provided to locate the problemati statement. */
+
+static BrigMemoryOrder
+get_memory_order (unsigned memmodel, location_t location)
+{
+ switch (memmodel)
+ {
+ case __ATOMIC_RELAXED:
+ return BRIG_MEMORY_ORDER_RELAXED;
+ case __ATOMIC_ACQUIRE:
+ return BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ case __ATOMIC_RELEASE:
+ return BRIG_MEMORY_ORDER_SC_RELEASE;
+ case __ATOMIC_ACQ_REL:
+ return BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
+ default:
+ HSA_SORRY_ATV (location,
+ "support for HSA does not implement memory model: %s",
+ get_memory_order_name (memmodel));
+ return BRIG_MEMORY_ORDER_NONE;
+ }
+}
+
/* Helper function to create an HSA atomic binary operation instruction out of
calls to atomic builtins. RET_ORIG is true if the built-in is the variant
that return s the value before applying operation, and false if it should
@@ -4161,8 +4210,22 @@ gen_hsa_ternary_atomic_for_builtin (bool ret_orig,
tree lhs = gimple_call_lhs (stmt);
tree type = TREE_TYPE (gimple_call_arg (stmt, 1));
- BrigType16_t hsa_type = hsa_type_for_scalar_tree_type (type, false);
+ BrigType16_t hsa_type = hsa_type_for_scalar_tree_type (type, false);
BrigType16_t mtype = mem_type_for_type (hsa_type);
+ tree model = gimple_call_arg (stmt, 2);
+
+ if (!tree_fits_uhwi_p (model))
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model %E", model);
+ return;
+ }
+
+ unsigned HOST_WIDE_INT mmodel = tree_to_uhwi (model);
+
+ BrigMemoryOrder memorder = get_memory_order
+ (mmodel, gimple_location (stmt));
/* Certain atomic insns must have Bx memory types. */
switch (acode)
@@ -4193,12 +4256,19 @@ gen_hsa_ternary_atomic_for_builtin (bool ret_orig,
nops = 2;
}
- hsa_insn_atomic *atominsn = new hsa_insn_atomic (nops, opcode, acode, mtype);
-
/* Overwrite default memory order for ATOMIC_ST insn which can have just
RLX or SCREL memory order. */
- if (acode == BRIG_ATOMIC_ST)
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_RELEASE;
+ if (acode == BRIG_ATOMIC_ST && memorder != BRIG_MEMORY_ORDER_RELAXED
+ && memorder != BRIG_MEMORY_ORDER_SC_RELEASE)
+ {
+ HSA_SORRY_ATV (gimple_location (stmt),
+ "support for HSA does not implement memory model for "
+ "ATOMIC_ST: %s", get_memory_order_name (mmodel));
+ return;
+ }
+
+ hsa_insn_atomic *atominsn = new hsa_insn_atomic (nops, opcode, acode, mtype,
+ memorder);
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
@@ -4369,6 +4439,28 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
BrigType16_t mtype;
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
+ tree model = gimple_call_arg (stmt, 1);
+ if (!tree_fits_uhwi_p (model))
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model: %E", model);
+ return;
+ }
+
+ unsigned HOST_WIDE_INT mmodel = tree_to_uhwi (model);
+ BrigMemoryOrder memorder = get_memory_order (mmodel,
+ gimple_location (stmt));
+
+ if (memorder != BRIG_MEMORY_ORDER_RELAXED
+ && memorder != BRIG_MEMORY_ORDER_SC_RELEASE)
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model for "
+ "ATOMIC_LD: %s", get_memory_order_name (mmodel));
+ return;
+ }
if (lhs)
{
@@ -4385,9 +4477,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
hsa_insn_atomic *atominsn
= new hsa_insn_atomic (2, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_LD, mtype,
- dest, addr);
-
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ memorder, dest, addr);
hbb->append_insn (atominsn);
break;
@@ -4515,7 +4605,8 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
(hsa_type_for_scalar_tree_type (type, false));
hsa_insn_atomic *atominsn = new hsa_insn_atomic
- (4, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_CAS, atype);
+ (4, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_CAS, atype,
+ BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE);
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
@@ -4534,7 +4625,6 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
atominsn->set_op
(3, hsa_reg_or_immed_for_gimple_op (gimple_call_arg (stmt, 2),
hbb, ssa_map));
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
hbb->append_insn (atominsn);
break;
@@ -612,7 +612,7 @@ class hsa_insn_atomic : public hsa_insn_mem
{
public:
hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
- BrigType16_t t,
+ BrigType16_t t, BrigMemoryOrder memorder,
hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
void *operator new (size_t);
--
2.6.2