glsl: Make is_16bit_constant from i965 an ir_constant method.
The i965 MUL instruction doesn't natively support 32-bit by 32-bit integer multiplication; additional instructions (MACH/MOV) are required. However, we can avoid those if we know one of the operands can be represented in 16 bits or less. The vector backend's is_16bit_constant static helper function checks for this. We want to be able to use it in the scalar backend as well, which means moving the function to a more generally-usable location. Since it isn't i965 specific, I decided to make it an ir_constant method, in case it ends up being useful to other people as well. v2: Rename from is_16bit_integer_constant to is_uint16_constant, as suggested by Ilia Mirkin. Update comments to clarify that it does apply to both int and uint types, as long as the value is non-negative and fits in 16-bits. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -1223,6 +1223,15 @@ ir_constant::is_basis() const
|
||||
return ones == 1;
|
||||
}
|
||||
|
||||
bool
|
||||
ir_constant::is_uint16_constant() const
|
||||
{
|
||||
if (!type->is_integer())
|
||||
return false;
|
||||
|
||||
return value.u[0] < (1 << 16);
|
||||
}
|
||||
|
||||
ir_loop::ir_loop()
|
||||
{
|
||||
this->ir_type = ir_type_loop;
|
||||
|
@@ -265,6 +265,13 @@ public:
|
||||
*/
|
||||
virtual bool is_basis() const;
|
||||
|
||||
/**
|
||||
* Determine if an r-value is an unsigned integer constant which can be
|
||||
* stored in 16 bits.
|
||||
*
|
||||
* \sa ir_constant::is_uint16_constant.
|
||||
*/
|
||||
virtual bool is_uint16_constant() const { return false; }
|
||||
|
||||
/**
|
||||
* Return a generic value of error_type.
|
||||
@@ -2164,6 +2171,14 @@ public:
|
||||
virtual bool is_negative_one() const;
|
||||
virtual bool is_basis() const;
|
||||
|
||||
/**
|
||||
* Return true for constants that could be stored as 16-bit unsigned values.
|
||||
*
|
||||
* Note that this will return true even for signed integer ir_constants, as
|
||||
* long as the value is non-negative and fits in 16-bits.
|
||||
*/
|
||||
virtual bool is_uint16_constant() const;
|
||||
|
||||
/**
|
||||
* Value of the constant.
|
||||
*
|
||||
|
@@ -1174,20 +1174,6 @@ vec4_visitor::emit_lrp(const dst_reg &dst,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_16bit_constant(ir_rvalue *rvalue)
|
||||
{
|
||||
ir_constant *constant = rvalue->as_constant();
|
||||
if (!constant)
|
||||
return false;
|
||||
|
||||
if (constant->type != glsl_type::int_type &&
|
||||
constant->type != glsl_type::uint_type)
|
||||
return false;
|
||||
|
||||
return constant->value.u[0] < (1 << 16);
|
||||
}
|
||||
|
||||
void
|
||||
vec4_visitor::visit(ir_expression *ir)
|
||||
{
|
||||
@@ -1371,12 +1357,12 @@ vec4_visitor::visit(ir_expression *ir)
|
||||
* operand. If we can determine that one of the args is in the low
|
||||
* 16 bits, though, we can just emit a single MUL.
|
||||
*/
|
||||
if (is_16bit_constant(ir->operands[0])) {
|
||||
if (ir->operands[0]->is_uint16_constant()) {
|
||||
if (brw->gen < 7)
|
||||
emit(MUL(result_dst, op[0], op[1]));
|
||||
else
|
||||
emit(MUL(result_dst, op[1], op[0]));
|
||||
} else if (is_16bit_constant(ir->operands[1])) {
|
||||
} else if (ir->operands[1]->is_uint16_constant()) {
|
||||
if (brw->gen < 7)
|
||||
emit(MUL(result_dst, op[1], op[0]));
|
||||
else
|
||||
|
Reference in New Issue
Block a user