aco: add and set precise flag

No fossil-db changes.

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5245>
This commit is contained in:
Rhys Perry 2020-05-15 13:58:20 +01:00 committed by Marge Bot
parent a8f800a836
commit 1b6a319c15
5 changed files with 29 additions and 3 deletions

View File

@ -166,11 +166,18 @@ public:
std::vector<aco_ptr<Instruction>> *instructions; std::vector<aco_ptr<Instruction>> *instructions;
std::vector<aco_ptr<Instruction>>::iterator it; std::vector<aco_ptr<Instruction>>::iterator it;
bool is_precise = false;
Builder(Program *pgm) : program(pgm), use_iterator(false), start(false), lm(pgm->lane_mask), instructions(NULL) {} Builder(Program *pgm) : program(pgm), use_iterator(false), start(false), lm(pgm->lane_mask), instructions(NULL) {}
Builder(Program *pgm, Block *block) : program(pgm), use_iterator(false), start(false), lm(pgm ? pgm->lane_mask : s2), instructions(&block->instructions) {} Builder(Program *pgm, Block *block) : program(pgm), use_iterator(false), start(false), lm(pgm ? pgm->lane_mask : s2), instructions(&block->instructions) {}
Builder(Program *pgm, std::vector<aco_ptr<Instruction>> *instrs) : program(pgm), use_iterator(false), start(false), lm(pgm ? pgm->lane_mask : s2), instructions(instrs) {} Builder(Program *pgm, std::vector<aco_ptr<Instruction>> *instrs) : program(pgm), use_iterator(false), start(false), lm(pgm ? pgm->lane_mask : s2), instructions(instrs) {}
Builder precise() const {
Builder res = *this;
res.is_precise = true;
return res;
};
void moveEnd(Block *block) { void moveEnd(Block *block) {
instructions = &block->instructions; instructions = &block->instructions;
} }
@ -524,6 +531,7 @@ formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.prod
${struct} *instr = create_instruction<${struct}>(opcode, (Format)(${'|'.join('(int)Format::%s' % f.name for f in formats)}), ${num_operands}, ${num_definitions}); ${struct} *instr = create_instruction<${struct}>(opcode, (Format)(${'|'.join('(int)Format::%s' % f.name for f in formats)}), ${num_operands}, ${num_definitions});
% for i in range(num_definitions): % for i in range(num_definitions):
instr->definitions[${i}] = def${i}; instr->definitions[${i}] = def${i};
instr->definitions[${i}].setPrecise(is_precise);
% endfor % endfor
% for i in range(num_operands): % for i in range(num_operands):
instr->operands[${i}] = op${i}.op; instr->operands[${i}] = op${i}.op;

View File

@ -590,6 +590,8 @@ void emit_vop2_instruction(isel_context *ctx, nir_alu_instr *instr, aco_opcode o
bool commutative, bool swap_srcs=false, bool flush_denorms = false) bool commutative, bool swap_srcs=false, bool flush_denorms = false)
{ {
Builder bld(ctx->program, ctx->block); Builder bld(ctx->program, ctx->block);
bld.is_precise = instr->exact;
Temp src0 = get_alu_src(ctx, instr->src[swap_srcs ? 1 : 0]); Temp src0 = get_alu_src(ctx, instr->src[swap_srcs ? 1 : 0]);
Temp src1 = get_alu_src(ctx, instr->src[swap_srcs ? 0 : 1]); Temp src1 = get_alu_src(ctx, instr->src[swap_srcs ? 0 : 1]);
if (src1.type() == RegType::sgpr) { if (src1.type() == RegType::sgpr) {
@ -628,6 +630,7 @@ void emit_vop3a_instruction(isel_context *ctx, nir_alu_instr *instr, aco_opcode
src2 = as_vgpr(ctx, src2); src2 = as_vgpr(ctx, src2);
Builder bld(ctx->program, ctx->block); Builder bld(ctx->program, ctx->block);
bld.is_precise = instr->exact;
if (flush_denorms && ctx->program->chip_class < GFX9) { if (flush_denorms && ctx->program->chip_class < GFX9) {
assert(dst.size() == 1); assert(dst.size() == 1);
Temp tmp = bld.vop3(op, Definition(dst), src0, src1, src2); Temp tmp = bld.vop3(op, Definition(dst), src0, src1, src2);
@ -640,6 +643,7 @@ void emit_vop3a_instruction(isel_context *ctx, nir_alu_instr *instr, aco_opcode
void emit_vop1_instruction(isel_context *ctx, nir_alu_instr *instr, aco_opcode op, Temp dst) void emit_vop1_instruction(isel_context *ctx, nir_alu_instr *instr, aco_opcode op, Temp dst)
{ {
Builder bld(ctx->program, ctx->block); Builder bld(ctx->program, ctx->block);
bld.is_precise = instr->exact;
if (dst.type() == RegType::sgpr) if (dst.type() == RegType::sgpr)
bld.pseudo(aco_opcode::p_as_uniform, Definition(dst), bld.pseudo(aco_opcode::p_as_uniform, Definition(dst),
bld.vop1(op, bld.def(RegType::vgpr, dst.size()), get_alu_src(ctx, instr->src[0]))); bld.vop1(op, bld.def(RegType::vgpr, dst.size()), get_alu_src(ctx, instr->src[0])));
@ -1041,6 +1045,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
abort(); abort();
} }
Builder bld(ctx->program, ctx->block); Builder bld(ctx->program, ctx->block);
bld.is_precise = instr->exact;
Temp dst = get_ssa_temp(ctx, &instr->dest.dest.ssa); Temp dst = get_ssa_temp(ctx, &instr->dest.dest.ssa);
switch(instr->op) { switch(instr->op) {
case nir_op_vec2: case nir_op_vec2:
@ -2703,7 +2708,6 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} }
case nir_op_unpack_half_2x16_split_x: { case nir_op_unpack_half_2x16_split_x: {
if (dst.regClass() == v1) { if (dst.regClass() == v1) {
Builder bld(ctx->program, ctx->block);
bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst), get_alu_src(ctx, instr->src[0])); bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst), get_alu_src(ctx, instr->src[0]));
} else { } else {
fprintf(stderr, "Unimplemented NIR instr bit size: "); fprintf(stderr, "Unimplemented NIR instr bit size: ");
@ -2714,7 +2718,6 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} }
case nir_op_unpack_half_2x16_split_y: { case nir_op_unpack_half_2x16_split_y: {
if (dst.regClass() == v1) { if (dst.regClass() == v1) {
Builder bld(ctx->program, ctx->block);
/* TODO: use SDWA here */ /* TODO: use SDWA here */
bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst), bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst),
bld.vop2(aco_opcode::v_lshrrev_b32, bld.def(v1), Operand(16u), as_vgpr(ctx, get_alu_src(ctx, instr->src[0])))); bld.vop2(aco_opcode::v_lshrrev_b32, bld.def(v1), Operand(16u), as_vgpr(ctx, get_alu_src(ctx, instr->src[0]))));

View File

@ -652,7 +652,7 @@ private:
class Definition final class Definition final
{ {
public: public:
constexpr Definition() : temp(Temp(0, s1)), reg_(0), isFixed_(0), hasHint_(0), isKill_(0) {} constexpr Definition() : temp(Temp(0, s1)), reg_(0), isFixed_(0), hasHint_(0), isKill_(0), isPrecise_(0) {}
Definition(uint32_t index, RegClass type) noexcept Definition(uint32_t index, RegClass type) noexcept
: temp(index, type) {} : temp(index, type) {}
explicit Definition(Temp tmp) noexcept explicit Definition(Temp tmp) noexcept
@ -739,6 +739,16 @@ public:
return isKill_; return isKill_;
} }
constexpr void setPrecise(bool precise) noexcept
{
isPrecise_ = precise;
}
constexpr bool isPrecise() const noexcept
{
return isPrecise_;
}
private: private:
Temp temp = Temp(0, s1); Temp temp = Temp(0, s1);
PhysReg reg_; PhysReg reg_;
@ -747,6 +757,7 @@ private:
uint8_t isFixed_:1; uint8_t isFixed_:1;
uint8_t hasHint_:1; uint8_t hasHint_:1;
uint8_t isKill_:1; uint8_t isKill_:1;
uint8_t isPrecise_:1;
}; };
/* can't initialize bit-fields in c++11, so work around using a union */ /* can't initialize bit-fields in c++11, so work around using a union */
uint8_t control_ = 0; uint8_t control_ = 0;

View File

@ -401,6 +401,8 @@ void process_block(vn_ctx& ctx, Block& block)
assert(instr->definitions[i].regClass() == orig_instr->definitions[i].regClass()); assert(instr->definitions[i].regClass() == orig_instr->definitions[i].regClass());
assert(instr->definitions[i].isTemp()); assert(instr->definitions[i].isTemp());
ctx.renames[instr->definitions[i].tempId()] = orig_instr->definitions[i].getTemp(); ctx.renames[instr->definitions[i].tempId()] = orig_instr->definitions[i].getTemp();
if (instr->definitions[i].isPrecise())
orig_instr->definitions[i].setPrecise(true);
} }
} else { } else {
ctx.expr_values.erase(res.first); ctx.expr_values.erase(res.first);

View File

@ -174,6 +174,8 @@ static void print_operand(const Operand *operand, FILE *output)
static void print_definition(const Definition *definition, FILE *output) static void print_definition(const Definition *definition, FILE *output)
{ {
print_reg_class(definition->regClass(), output); print_reg_class(definition->regClass(), output);
if (definition->isPrecise())
fprintf(output, "(precise)");
fprintf(output, "%%%d", definition->tempId()); fprintf(output, "%%%d", definition->tempId());
if (definition->isFixed()) if (definition->isFixed())