Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherrypick move optimization patch from upstream #34

Open
wants to merge 1 commit into
base: pstl
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions gcc/brig/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
2017-11-16 Henry Linjamäki <henry.linjamaki@parmance.com>

Change internal representation of HSA registers. Instead
representing HSA's untyped registers as unsigned int the gccbrig
analyzes brig code and builds the register variables as a type
used in tree expressions at most. This gives better chance to
optimize CONVERT_VIEW_EXPRs away.
* brigfrontend/brig-code-entry-handler.cc: Add analysis method for
register type usage. Handle any-typed register variables.
* brigfrontend/brig-code-entry-handler.h: New declarations for the
above.
* brigfrontend/brig-copy-move-inst-handler.cc: Handle any-typed
register variables.
* brigfrontend/brig-cvt-inst-handler.cc: Likewise.
* brigfrontend/brig-function.cc: Build register variables as a
type based on results of analysis phase.
* brigfrontend/brig-function.h: Move HSA register count defines to
brig-utils.h.
* brigfrontend/brig-to-generic.cc: New analysis handler. Analyze
HSA register usage.
* brigfrontend/brig-to-generic.h: New declarations.
* brigfrontend/brig-util.cc: New utility functions.
* brigfrontend/brig-util.h: New declarations for the above.

2017-11-16 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>

* gccbrig.texi: Added some documentation.

2017-10-31 Henry Linjamäki <henry.linjamaki@parmance.com>

* brig-lang.c (brig_langhook_type_for_mode): Fix PR 82771.

2017-10-23 Richard Sandiford <richard.sandiford@linaro.org>

* brig-lang.c (brig_langhook_type_for_mode): Use scalar_int_mode
and scalar_float_mode.

2017-10-09 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>

* brigfrontend/brig-to-generic.cc: Support BRIG_KIND_NONE
Expand Down
13 changes: 7 additions & 6 deletions gcc/brig/brigfrontend/brig-basic-inst-handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,16 @@ brig_basic_inst_handler::build_unpack (tree_stl_vec &operands)
tree and_mask_vec = build_constructor (vec_type, and_mask_vals);

tree perm = build3 (VEC_PERM_EXPR, vec_type,
build_reinterpret_cast (vec_type, operands[0]),
build_reinterpret_cast (vec_type, operands[0]), mask_vec);
build_resize_convert_view (vec_type, operands[0]),
build_resize_convert_view (vec_type, operands[0]),
mask_vec);

tree cleared = build2 (BIT_AND_EXPR, vec_type, perm, and_mask_vec);

size_t s = int_size_in_bytes (TREE_TYPE (cleared)) * BITS_PER_UNIT;
tree raw_type = build_nonstandard_integer_type (s, true);

tree as_int = build_reinterpret_cast (raw_type, cleared);
tree as_int = build_resize_convert_view (raw_type, cleared);

if (int_size_in_bytes (src_element_type) < 4)
{
Expand All @@ -217,7 +218,7 @@ brig_basic_inst_handler::build_pack (tree_stl_vec &operands)
size_t vecsize = int_size_in_bytes (TREE_TYPE (operands[0])) * BITS_PER_UNIT;
tree wide_type = build_nonstandard_integer_type (vecsize, 1);

tree src_vect = build_reinterpret_cast (wide_type, operands[0]);
tree src_vect = build_resize_convert_view (wide_type, operands[0]);
src_vect = add_temp_var ("src_vect", src_vect);

tree scalar = operands[1];
Expand Down Expand Up @@ -650,10 +651,10 @@ brig_basic_inst_handler::operator () (const BrigBase *base)

if (is_fp16_operation)
old_value = build_h2f_conversion
(build_reinterpret_cast (half_storage_type, operands[0]));
(build_resize_convert_view (half_storage_type, operands[0]));
else
old_value
= build_reinterpret_cast (TREE_TYPE (instr_expr), operands[0]);
= build_resize_convert_view (TREE_TYPE (instr_expr), operands[0]);

size_t esize = is_fp16_operation ? 32 : element_size_bits;

Expand Down
126 changes: 68 additions & 58 deletions gcc/brig/brigfrontend/brig-code-entry-handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,7 @@ brig_code_entry_handler::build_tree_operand (const BrigInstBase &brig_inst,
correct size here so we don't need a separate unpack/pack for it.
fp16-fp32 conversion is done in build_operands (). */
if (is_input && TREE_TYPE (element) != operand_type)
{
if (int_size_in_bytes (TREE_TYPE (element))
== int_size_in_bytes (operand_type)
&& !INTEGRAL_TYPE_P (operand_type))
element = build1 (VIEW_CONVERT_EXPR, operand_type, element);
else
element = convert (operand_type, element);
}
element = build_resize_convert_view (operand_type, element);

CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, element);
++operand_ptr;
Expand Down Expand Up @@ -368,7 +361,7 @@ brig_code_entry_handler::build_address_operand
to the array object. */

if (POINTER_TYPE_P (TREE_TYPE (arg_var_decl)))
symbol_base = build_reinterpret_cast (ptype, arg_var_decl);
symbol_base = build_resize_convert_view (ptype, arg_var_decl);
else
{
/* In case we are referring to an array (the argument in
Expand Down Expand Up @@ -436,7 +429,8 @@ brig_code_entry_handler::build_address_operand
= (const BrigOperandRegister *) m_parent.get_brig_operand_entry
(addr_operand.reg);
tree base_reg_var = m_parent.m_cf->get_m_var_declfor_reg (mem_base_reg);
var_offset = convert_to_pointer (ptr_type_node, base_reg_var);
tree as_uint = build_reinterpret_to_uint (base_reg_var);
var_offset = convert_to_pointer (ptr_type_node, as_uint);

gcc_assert (var_offset != NULL_TREE);
}
Expand Down Expand Up @@ -527,7 +521,10 @@ brig_code_entry_handler::build_tree_operand_from_brig
= ((const uint32_t *) &operand_entries->bytes)[operand_index];
const BrigBase *operand_data
= m_parent.get_brig_operand_entry (operand_offset);
return build_tree_operand (*brig_inst, *operand_data, operand_type);

bool inputp = !gccbrig_hsa_opcode_op_output_p (brig_inst->opcode,
operand_index);
return build_tree_operand (*brig_inst, *operand_data, operand_type, inputp);
}

/* Builds a single (scalar) constant initialized element of type
Expand Down Expand Up @@ -991,8 +988,8 @@ brig_code_entry_handler::expand_or_call_builtin (BrigOpcode16_t brig_opcode,
call_operands.resize (4, NULL_TREE);
operand_types.resize (4, NULL_TREE);
for (size_t i = 0; i < operand_count; ++i)
call_operands.at (i) = build_reinterpret_cast (operand_types.at (i),
call_operands.at (i));
call_operands.at (i) = build_resize_convert_view (operand_types.at (i),
call_operands.at (i));

tree fnptr = build_fold_addr_expr (built_in);
return build_call_array (TREE_TYPE (TREE_TYPE (built_in)), fnptr,
Expand Down Expand Up @@ -1140,6 +1137,28 @@ brig_code_entry_handler::build_h2f_conversion (tree source)

tree_stl_vec
brig_code_entry_handler::build_operands (const BrigInstBase &brig_inst)
{
return build_or_analyze_operands (brig_inst, false);
}

void
brig_code_entry_handler::analyze_operands (const BrigInstBase &brig_inst)
{
build_or_analyze_operands (brig_inst, true);
}

/* Implements both the build_operands () and analyze_operands () call
so changes go in tandem. Performs build_operands () when ANALYZE
is false. Otherwise, only analyze operands and return empty
list.

If analyzing record each HSA register operand with the
corresponding resolved operand tree type to
brig_to_generic::m_fn_regs_use_index. */

tree_stl_vec
brig_code_entry_handler::
build_or_analyze_operands (const BrigInstBase &brig_inst, bool analyze)
{
/* Flush to zero. */
bool ftz_mod = false;
Expand Down Expand Up @@ -1327,9 +1346,19 @@ brig_code_entry_handler::build_operands (const BrigInstBase &brig_inst)
/* Treat the operands as the storage type at this point. */
operand_type = half_storage_type;

if (analyze)
{
if (operand_data->kind == BRIG_KIND_OPERAND_REGISTER)
{
const BrigOperandRegister &brig_reg
= (const BrigOperandRegister &) *operand_data;
m_parent.add_reg_used_as_type (brig_reg, operand_type);
}
continue;
}

tree operand = build_tree_operand (brig_inst, *operand_data, operand_type,
!is_output);

gcc_assert (operand);

/* Cast/convert the inputs to correct types as expected by the GENERIC
Expand All @@ -1338,36 +1367,17 @@ brig_code_entry_handler::build_operands (const BrigInstBase &brig_inst)
{
if (half_to_float)
operand = build_h2f_conversion
(build_reinterpret_cast (half_storage_type, operand));
(build_resize_convert_view (half_storage_type, operand));
else if (TREE_CODE (operand) != LABEL_DECL
&& TREE_CODE (operand) != TREE_VEC
&& operand_data->kind != BRIG_KIND_OPERAND_ADDRESS
&& !VECTOR_TYPE_P (TREE_TYPE (operand)))
&& operand_data->kind != BRIG_KIND_OPERAND_OPERAND_LIST)
{
size_t reg_width = int_size_in_bytes (TREE_TYPE (operand));
size_t instr_width = int_size_in_bytes (operand_type);
if (reg_width == instr_width)
operand = build_reinterpret_cast (operand_type, operand);
else if (reg_width > instr_width)
{
/* Clip the operand because the instruction's bitwidth
is smaller than the HSAIL reg width. */
if (INTEGRAL_TYPE_P (operand_type))
operand
= convert_to_integer (signed_or_unsigned_type_for
(TYPE_UNSIGNED (operand_type),
operand_type), operand);
else
operand = build_reinterpret_cast (operand_type, operand);
}
else if (reg_width < instr_width)
/* At least shift amount operands can be read from smaller
registers than the data operands. */
operand = convert (operand_type, operand);
operand = build_resize_convert_view (operand_type, operand);
}
else if (brig_inst.opcode == BRIG_OPCODE_SHUFFLE)
/* Force the operand type to be treated as the raw type. */
operand = build_reinterpret_cast (operand_type, operand);
operand = build_resize_convert_view (operand_type, operand);

if (brig_inst.opcode == BRIG_OPCODE_CMOV && i == 1)
{
Expand Down Expand Up @@ -1399,8 +1409,9 @@ tree
brig_code_entry_handler::build_output_assignment (const BrigInstBase &brig_inst,
tree output, tree inst_expr)
{
/* The destination type might be different from the output register
variable type (which is always an unsigned integer type). */
/* The result/input type might be different from the output register
variable type (can be any type; see get_m_var_declfor_reg @
brig-function.cc). */
tree output_type = TREE_TYPE (output);
tree input_type = TREE_TYPE (inst_expr);
bool is_fp16 = (brig_inst.type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16
Expand Down Expand Up @@ -1440,12 +1451,12 @@ brig_code_entry_handler::build_output_assignment (const BrigInstBase &brig_inst,
{
inst_expr = add_temp_var ("before_f2h", inst_expr);
tree f2h_output = build_f2h_conversion (inst_expr);
tree conv_int = convert_to_integer (output_type, f2h_output);
tree assign = build2 (MODIFY_EXPR, output_type, output, conv_int);
tree conv = build_resize_convert_view (output_type, f2h_output);
tree assign = build2 (MODIFY_EXPR, output_type, output, conv);
m_parent.m_cf->append_statement (assign);
return assign;
}
else if (VECTOR_TYPE_P (TREE_TYPE (output)))
else if (VECTOR_TYPE_P (output_type) && TREE_CODE (output) == CONSTRUCTOR)
{
/* Expand/unpack the input value to the given vector elements. */
size_t i;
Expand Down Expand Up @@ -1473,22 +1484,21 @@ brig_code_entry_handler::build_output_assignment (const BrigInstBase &brig_inst,
bitwidths. */
size_t src_width = int_size_in_bytes (input_type);
size_t dst_width = int_size_in_bytes (output_type);

if (src_width == dst_width)
{
/* A simple bitcast should do. */
tree bitcast = build_reinterpret_cast (output_type, inst_expr);
tree assign = build2 (MODIFY_EXPR, output_type, output, bitcast);
m_parent.m_cf->append_statement (assign);
return assign;
}
else
tree input = inst_expr;
/* Integer results are extended to the target register width, using
the same sign as the inst_expr. */
if (INTEGRAL_TYPE_P (TREE_TYPE (input)) && src_width != dst_width)
{
tree conv_int = convert_to_integer (output_type, inst_expr);
tree assign = build2 (MODIFY_EXPR, output_type, output, conv_int);
m_parent.m_cf->append_statement (assign);
return assign;
bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (input));
tree resized_type
= build_nonstandard_integer_type (dst_width * BITS_PER_UNIT,
unsigned_p);
input = convert_to_integer (resized_type, input);
}
input = build_resize_convert_view (output_type, input);
tree assign = build2 (MODIFY_EXPR, output_type, output, input);
m_parent.m_cf->append_statement (assign);
return assign;
}
return NULL_TREE;
}
Expand Down Expand Up @@ -1691,7 +1701,7 @@ float_to_half::visit_element (brig_code_entry_handler &caller, tree operand)
{
tree built_in = builtin_decl_explicit (BUILT_IN_HSAIL_F32_TO_F16);

tree casted_operand = build_reinterpret_cast (uint32_type_node, operand);
tree casted_operand = build_resize_convert_view (uint32_type_node, operand);

tree call = call_builtin (built_in, 1, uint16_type_node, uint32_type_node,
casted_operand);
Expand Down Expand Up @@ -1720,7 +1730,7 @@ half_to_float::visit_element (brig_code_entry_handler &caller, tree operand)

tree output = create_tmp_var (const_fp32_type, "fp32out");
tree casted_result
= build_reinterpret_cast (brig_to_generic::s_fp32_type, call);
= build_resize_convert_view (brig_to_generic::s_fp32_type, call);

tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted_result);

Expand Down
6 changes: 6 additions & 0 deletions gcc/brig/brigfrontend/brig-code-entry-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class brig_code_entry_handler : public brig_entry_handler
tree build_h2f_conversion (tree source);

tree_stl_vec build_operands (const BrigInstBase &brig_inst);
void analyze_operands (const BrigInstBase &brig_inst);
tree build_output_assignment (const BrigInstBase &brig_inst, tree output,
tree inst_expr);

Expand All @@ -105,6 +106,11 @@ class brig_code_entry_handler : public brig_entry_handler
/* HSAIL-specific builtin functions not yet integrated to gcc. */

static builtin_map s_custom_builtins;

private:

tree_stl_vec build_or_analyze_operands (const BrigInstBase &brig_inst,
bool analyze);
};

/* Implement the Visitor software pattern for performing various actions on
Expand Down
4 changes: 2 additions & 2 deletions gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ brig_copy_move_inst_handler::operator () (const BrigBase *base)

tree input = build_tree_operand_from_brig (brig_inst, source_type, 1);
tree output = build_tree_operand_from_brig (brig_inst, dest_type, 0);

if (brig_inst->opcode == BRIG_OPCODE_COMBINE)
{
/* For combine, a simple reinterpret cast from the array constructor
works. */

tree casted = build_reinterpret_cast (dest_type, input);
tree casted = build_resize_convert_view (TREE_TYPE (output), input);
tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted);
m_parent.m_cf->append_statement (assign);
}
Expand Down
Loading