@@ -796,10 +796,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
fprintf (f, "%s", hsa_opcode_name (mem->opcode));
if (addr->symbol)
fprintf (f, "_%s", hsa_seg_name (addr->symbol->segment));
- if (mem->memoryorder != BRIG_MEMORY_ORDER_NONE)
- fprintf (f, "_%s", hsa_memsem_name (mem->memoryorder));
- if (mem->memoryscope != BRIG_MEMORY_SCOPE_NONE)
- fprintf (f, "_%s", hsa_memscope_name (mem->memoryscope));
if (mem->equiv_class != 0)
fprintf (f, "_equiv(%i)", mem->equiv_class);
fprintf (f, "_%s ", hsa_type_name (mem->type));
@@ -888,6 +888,31 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc)
operands.safe_grow_cleared (nops);
}
+/* Make OP the operand number INDEX of operands of this instuction. If OP is a
+ register or an address containing a register, then either set the definition
+ of the register to this instruction if it an output operand or add this
+ instruction to the uses if it is an input one. */
+
+void
+hsa_insn_basic::set_op (int index, hsa_op_base *op)
+{
+ if (hsa_opcode_op_output_p (opcode, index))
+ {
+ if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
+ reg->set_definition (this);
+ }
+ else
+ {
+ hsa_op_address *addr;
+ if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
+ reg->uses.safe_push (this);
+ else if ((addr = dyn_cast <hsa_op_address *> (op))
+ && addr->reg)
+ addr->reg->uses.safe_push (this);
+ }
+ operands[index] = op;
+}
+
/* Constructor of the class which is the bases of all instructions and directly
represents the most basic ones. NOPS is the number of operands that the
operand vector will contain (and which will be cleared). OPC is the opcode
@@ -1005,8 +1030,6 @@ hsa_insn_mem::hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0,
|| opc == BRIG_OPCODE_EXPAND);
equiv_class = 0;
- memoryorder = BRIG_MEMORY_ORDER_NONE;
- memoryscope = BRIG_MEMORY_SCOPE_NONE;
operands[0] = arg0;
operands[1] = arg1;
}
@@ -1019,8 +1042,6 @@ hsa_insn_mem::hsa_insn_mem (unsigned nops, int opc, BrigType16_t t)
: hsa_insn_basic (nops, opc, t)
{
equiv_class = 0;
- memoryorder = BRIG_MEMORY_ORDER_NONE;
- memoryscope = BRIG_MEMORY_SCOPE_NONE;
}
/* New operator to allocate memory instruction from pool alloc. */
@@ -1031,9 +1052,9 @@ hsa_insn_mem::operator new (size_t)
return hsa_allocp_inst_mem->vallocate ();
}
-/* Constructor of class representing atomic instructions. OPC is the prinicpa;
- opcode, aop is the specific atomic operation opcode. T is the type of the
- instruction. */
+/* Constructor of class representing atomic instructions and signals. OPC is
+ the prinicpal opcode, aop is the specific atomic operation opcode. T is the
+ type of the instruction. */
hsa_insn_atomic::hsa_insn_atomic (int nops, int opc,
enum BrigAtomicOperation aop,
@@ -1045,6 +1066,18 @@ hsa_insn_atomic::hsa_insn_atomic (int nops, int opc,
opc == BRIG_OPCODE_SIGNAL ||
opc == BRIG_OPCODE_SIGNALNORET);
atomicop = aop;
+ /* TODO: Review the following defaults (together with the few overriddes we
+ have in the code). */
+ memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
+ memoryscope = BRIG_MEMORY_SCOPE_SYSTEM;
+}
+
+/* New operator to allocate signal instruction from pool alloc. */
+
+void *
+hsa_insn_atomic::operator new (size_t)
+{
+ return hsa_allocp_inst_atomic->vallocate ();
}
/* Constructor of class representing signal instructions. OPC is the prinicpa;
@@ -3399,6 +3432,7 @@ specialop:
/* FIXME: Using the native instruction may not be precise enough.
Perhaps only allow if using -ffast-math? */
gen_hsa_unaryop_for_builtin (BRIG_OPCODE_NSIN, stmt, hbb, ssa_map);
+ break;
case BUILT_IN_ATOMIC_LOAD_1:
case BUILT_IN_ATOMIC_LOAD_2:
@@ -3412,17 +3446,13 @@ specialop:
hsa_op_address *addr = gen_hsa_addr (gimple_call_arg (stmt, 0),
hbb, ssa_map);
dest = hsa_reg_for_gimple_ssa (lhs, ssa_map);
- hsa_insn_mem *meminsn = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dest,
- addr);
-
- /* Should check what the memory scope is */
- meminsn->memoryscope = BRIG_MEMORY_SCOPE_WORKGROUP;
- meminsn->memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ hsa_insn_atomic *atominsn
+ = new hsa_insn_atomic (2, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_LD, mtype);
- dest->set_definition (meminsn);
- if (addr->reg)
- addr->reg->uses.safe_push (meminsn);
- hbb->append_insn (meminsn);
+ atominsn->set_op (0, dest);
+ atominsn->set_op (1, addr);
+ atominsn->memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ hbb->append_insn (atominsn);
break;
}
@@ -333,6 +333,7 @@ public:
hsa_op_base *arg3 = NULL);
void *operator new (size_t);
+ void set_op (int index, hsa_op_base *op);
/* The previous and next instruction in the basic block. */
hsa_insn_basic *prev, *next;
@@ -474,12 +475,6 @@ public:
/* HSA equiv class, basically an alias set number. */
uint8_t equiv_class;
- /* Things like acquire/release/aligned. */
- enum BrigMemoryOrder memoryorder;
-
- /* Scope of the atomic operation. */
- enum BrigMemoryScope memoryscope;
-
/* TODO: Add width modifier, perhaps also other things. */
protected:
hsa_insn_mem (unsigned nops, int opc, BrigType16_t t);
@@ -510,9 +505,17 @@ class hsa_insn_atomic : public hsa_insn_mem
public:
hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
BrigType16_t t);
+ void *operator new (size_t);
/* The operation itself. */
enum BrigAtomicOperation atomicop;
+
+ /* Things like acquire/release/aligned. */
+ enum BrigMemoryOrder memoryorder;
+
+ /* Scope of the atomic operation. */
+ enum BrigMemoryScope memoryscope;
+
private:
/* Make the default constructor inaccessible. */
hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {}