Module: Mesa
Branch: master
Commit: 8c02a8e2d207a1d085f7a8fb3a0117b50b769611
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8c02a8e2d207a1d085f7a8fb3a0117b50b769611

Author: Rhys Perry <[email protected]>
Date:   Thu Dec  3 15:18:30 2020 +0000

aco: add get_const/is_constant_representable helpers

Signed-off-by: Rhys Perry <[email protected]>
Reviewed-by: Daniel Schürmann <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7798>

---

 src/amd/compiler/aco_ir.h                  | 45 ++++++++++++++++++++++++++++++
 src/amd/compiler/aco_lower_to_hw_instr.cpp | 19 +++++--------
 src/amd/compiler/aco_optimizer.cpp         | 37 ++++--------------------
 3 files changed, 58 insertions(+), 43 deletions(-)

diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h
index 0b313ca0dfb..daa30667a0f 100644
--- a/src/amd/compiler/aco_ir.h
+++ b/src/amd/compiler/aco_ir.h
@@ -556,6 +556,51 @@ public:
       setFixed(reg);
    }
 
+   /* This is useful over the constructors when you want to take a chip class
+    * for 1/2 PI or an unknown operand size.
+    */
+   static Operand get_const(enum chip_class chip, uint64_t val, unsigned bytes)
+   {
+      if (val == 0x3e22f983 && bytes == 4 && chip >= GFX8) {
+         /* 1/2 PI can be an inline constant on GFX8+ */
+         Operand op((uint32_t)val);
+         op.setFixed(PhysReg{248});
+         return op;
+      }
+
+      if (bytes == 8)
+         return Operand(val);
+      else if (bytes == 4)
+         return Operand((uint32_t)val);
+      else if (bytes == 2)
+         return Operand((uint16_t)val);
+      assert(bytes == 1);
+      return Operand((uint8_t)val);
+   }
+
+   static bool is_constant_representable(uint64_t val, unsigned bytes, bool 
zext=false, bool sext=false)
+   {
+      if (bytes <= 4)
+         return true;
+
+      if (zext && (val & 0xFFFFFFFF00000000) == 0x0000000000000000)
+         return true;
+      uint64_t upper33 = val & 0xFFFFFFFF80000000;
+      if (sext && (upper33 == 0xFFFFFFFF80000000 || upper33 == 0))
+         return true;
+
+      return val <= 64 ||
+             val >= 0xFFFFFFFFFFFFFFF0 || /* [-16 .. -1] */
+             val == 0x3FE0000000000000 || /* 0.5 */
+             val == 0xBFE0000000000000 || /* -0.5 */
+             val == 0x3FF0000000000000 || /* 1.0 */
+             val == 0xBFF0000000000000 || /* -1.0 */
+             val == 0x4000000000000000 || /* 2.0 */
+             val == 0xC000000000000000 || /* -2.0 */
+             val == 0x4010000000000000 || /* 4.0 */
+             val == 0xC010000000000000; /* -4.0 */
+   }
+
    constexpr bool isTemp() const noexcept
    {
       return isTemp_;
diff --git a/src/amd/compiler/aco_lower_to_hw_instr.cpp 
b/src/amd/compiler/aco_lower_to_hw_instr.cpp
index c372c8779fb..1d98b931763 100644
--- a/src/amd/compiler/aco_lower_to_hw_instr.cpp
+++ b/src/amd/compiler/aco_lower_to_hw_instr.cpp
@@ -924,7 +924,8 @@ struct copy_operation {
    };
 };
 
-void split_copy(unsigned offset, Definition *def, Operand *op, const 
copy_operation& src, bool ignore_uses, unsigned max_size)
+void split_copy(lower_context *ctx, unsigned offset, Definition *def, Operand 
*op,
+                const copy_operation& src, bool ignore_uses, unsigned max_size)
 {
    PhysReg def_reg = src.def.physReg();
    PhysReg op_reg = src.op.physReg();
@@ -952,14 +953,8 @@ void split_copy(unsigned offset, Definition *def, Operand 
*op, const copy_operat
    *def = Definition(src.def.tempId(), def_reg, def_cls);
    if (src.op.isConstant()) {
       assert(bytes >= 1 && bytes <= 8);
-      if (bytes == 8)
-         *op = Operand(src.op.constantValue64() >> (offset * 8u));
-      else if (bytes == 4)
-         *op = Operand(uint32_t(src.op.constantValue64() >> (offset * 8u)));
-      else if (bytes == 2)
-         *op = Operand(uint16_t(src.op.constantValue64() >> (offset * 8u)));
-      else if (bytes == 1)
-         *op = Operand(uint8_t(src.op.constantValue64() >> (offset * 8u)));
+      uint64_t val = src.op.constantValue64() >> (offset * 8u);
+      *op = Operand::get_const(ctx->program->chip_class, val, bytes);
    } else {
       RegClass op_cls = bytes % 4 == 0 ? RegClass(src.op.regClass().type(), 
bytes / 4u) :
                         RegClass(src.op.regClass().type(), 
bytes).as_subdword();
@@ -1072,7 +1067,7 @@ bool do_copy(lower_context* ctx, Builder& bld, const 
copy_operation& copy, bool
 
       Definition def;
       Operand op;
-      split_copy(offset, &def, &op, copy, false, 8);
+      split_copy(ctx, offset, &def, &op, copy, false, 8);
 
       if (def.physReg() == scc) {
          bld.sopc(aco_opcode::s_cmp_lg_i32, def, op, Operand(0u));
@@ -1160,7 +1155,7 @@ void do_swap(lower_context *ctx, Builder& bld, const 
copy_operation& copy, bool
    for (; offset < copy.bytes;) {
       Definition def;
       Operand op;
-      split_copy(offset, &def, &op, copy, true, 8);
+      split_copy(ctx, offset, &def, &op, copy, true, 8);
 
       assert(op.regClass() == def.regClass());
       Operand def_as_op = Operand(def.physReg(), def.regClass());
@@ -1548,7 +1543,7 @@ void handle_operands(std::map<PhysReg, copy_operation>& 
copy_map, lower_context*
             }
             Definition def;
             Operand op;
-            split_copy(offset, &def, &op, original, false, 8);
+            split_copy(ctx, offset, &def, &op, original, false, 8);
 
             copy_operation new_copy = {op, def, def.bytes()};
             for (unsigned i = 0; i < new_copy.bytes; i++)
diff --git a/src/amd/compiler/aco_optimizer.cpp 
b/src/amd/compiler/aco_optimizer.cpp
index b780a8f1529..3a4cf6c8556 100644
--- a/src/amd/compiler/aco_optimizer.cpp
+++ b/src/amd/compiler/aco_optimizer.cpp
@@ -185,37 +185,18 @@ struct ssa_info {
    void set_constant(chip_class chip, uint64_t constant)
    {
       Operand op16((uint16_t)constant);
-      Operand op32((uint32_t)constant);
+      Operand op32 = Operand::get_const(chip, constant, 4);
       add_label(label_literal);
       val = constant;
 
       if (chip >= GFX8 && !op16.isLiteral())
          add_label(label_constant_16bit);
 
-      if (!op32.isLiteral() || ((uint32_t)constant == 0x3e22f983 && chip >= 
GFX8))
+      if (!op32.isLiteral())
          add_label(label_constant_32bit);
 
-      if (constant <= 64) {
+      if (Operand::is_constant_representable(constant, 8))
          add_label(label_constant_64bit);
-      } else if (constant >= 0xFFFFFFFFFFFFFFF0) { /* [-16 .. -1] */
-         add_label(label_constant_64bit);
-      } else if (constant == 0x3FE0000000000000) { /* 0.5 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0xBFE0000000000000) { /* -0.5 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0x3FF0000000000000) { /* 1.0 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0xBFF0000000000000) { /* -1.0 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0x4000000000000000) { /* 2.0 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0xC000000000000000) { /* -2.0 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0x4010000000000000) { /* 4.0 */
-         add_label(label_constant_64bit);
-      } else if (constant == 0xC010000000000000) { /* -4.0 */
-         add_label(label_constant_64bit);
-      }
 
       if (label & label_constant_64bit) {
          val = Operand(constant).constantValue();
@@ -809,15 +790,9 @@ unsigned get_operand_size(aco_ptr<Instruction>& instr, 
unsigned index)
 
 Operand get_constant_op(opt_ctx &ctx, ssa_info info, uint32_t bits)
 {
-   if (bits == 8)
-      return Operand((uint8_t)info.val);
-   if (bits == 16)
-      return Operand((uint16_t)info.val);
-   // TODO: this functions shouldn't be needed if we store Operand instead of 
value.
-   Operand op(info.val, bits == 64);
-   if (info.is_literal(32) && info.val == 0x3e22f983 && 
ctx.program->chip_class >= GFX8)
-      op.setFixed(PhysReg{248}); /* 1/2 PI can be an inline constant on GFX8+ 
*/
-   return op;
+   if (bits == 64)
+      return Operand(info.val, true);
+   return Operand::get_const(ctx.program->chip_class, info.val, bits / 8u);
 }
 
 bool fixed_to_exec(Operand op)

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to