aco: add Instruction::usesModifiers() and add more checks in the optimizer
authorRhys Perry <pendingchaos02@gmail.com>
Tue, 29 Oct 2019 13:59:59 +0000 (13:59 +0000)
committerRhys Perry <pendingchaos02@gmail.com>
Fri, 8 Nov 2019 00:14:06 +0000 (00:14 +0000)
No pipeline-db changes.

v2: use early-exit for VOP3

Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> (v1)
src/amd/compiler/aco_ir.h
src/amd/compiler/aco_optimizer.cpp

index 5a16afdca364928adad077d4dfc3868a92931ef0..5b708c884e6c03361b337d9a0b706d5ef4edf3ed 100644 (file)
@@ -614,6 +614,8 @@ struct Instruction {
    {
       return format == Format::FLAT || format == Format::GLOBAL;
    }
+
+   constexpr bool usesModifiers() const noexcept;
 };
 
 struct SOPK_instruction : public Instruction {
@@ -877,6 +879,20 @@ T* create_instruction(aco_opcode opcode, Format format, uint32_t num_operands, u
    return inst;
 }
 
+constexpr bool Instruction::usesModifiers() const noexcept
+{
+   if (isDPP() || isSDWA())
+      return true;
+   if (!isVOP3())
+      return false;
+   const VOP3A_instruction *vop3 = static_cast<const VOP3A_instruction*>(this);
+   for (unsigned i = 0; i < operands.size(); i++) {
+      if (vop3->abs[i] || vop3->opsel[i] || vop3->neg[i])
+         return true;
+   }
+   return vop3->opsel[3] || vop3->clamp || vop3->omod;
+}
+
 constexpr bool is_phi(Instruction* instr)
 {
    return instr->opcode == aco_opcode::p_phi || instr->opcode == aco_opcode::p_linear_phi;
index 9501073debb6af306b1269a7c1f7638893f99a88..679f25b5dda8e82fad632eacacc9f9e4fa460081 100644 (file)
@@ -496,6 +496,9 @@ bool parse_base_offset(opt_ctx &ctx, Instruction* instr, unsigned op_index, Temp
       return false;
    }
 
+   if (add_instr->usesModifiers())
+      return false;
+
    for (unsigned i = 0; i < 2; i++) {
       if (add_instr->operands[i].isConstant()) {
          *offset = add_instr->operands[i].constantValue();
@@ -799,13 +802,13 @@ void label_instruction(opt_ctx &ctx, aco_ptr<Instruction>& instr)
    case aco_opcode::p_as_uniform:
       if (instr->definitions[0].isFixed()) {
          /* don't copy-propagate copies into fixed registers */
+      } else if (instr->usesModifiers()) {
+         // TODO
       } else if (instr->operands[0].isConstant()) {
          if (instr->operands[0].isLiteral())
             ctx.info[instr->definitions[0].tempId()].set_literal(instr->operands[0].constantValue());
          else
             ctx.info[instr->definitions[0].tempId()].set_constant(instr->operands[0].constantValue());
-      } else if (instr->isDPP()) {
-         // TODO
       } else if (instr->operands[0].isTemp()) {
          ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
       } else {
@@ -849,11 +852,8 @@ void label_instruction(opt_ctx &ctx, aco_ptr<Instruction>& instr)
    }
    case aco_opcode::v_mul_f32: { /* omod */
       /* TODO: try to move the negate/abs modifier to the consumer instead */
-      if (instr->isVOP3()) {
-         VOP3A_instruction *vop3 = static_cast<VOP3A_instruction*>(instr.get());
-         if (vop3->abs[0] || vop3->abs[1] || vop3->neg[0] || vop3->neg[1] || vop3->omod || vop3->clamp)
-            break;
-      }
+      if (instr->usesModifiers())
+         break;
 
       for (unsigned i = 0; i < 2; i++) {
          if (instr->operands[!i].isConstant() && instr->operands[i].isTemp()) {