[Beignet] [PATCH 1/5] GBE: refactor the immediate class to support vector data type.

Song, Ruiling ruiling.song at intel.com
Wed Jul 30 19:46:25 PDT 2014


Except two minor comments sent out, other parts of the patchset looks good.
I would say this is a big improvement on the constant expression support!

Thanks!
Ruiling

-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Zhigang Gong
Sent: Thursday, July 24, 2014 1:49 PM
To: beignet at lists.freedesktop.org
Cc: Gong, Zhigang
Subject: [Beignet] [PATCH 1/5] GBE: refactor the immediate class to support vector data type.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/backend/gen_insn_selection.cpp |  58 +++++------
 backend/src/ir/function.cpp                |  26 ++---
 backend/src/ir/immediate.hpp               | 162 +++++++++++++++++++++++++----
 backend/src/ir/instruction.cpp             |   2 +-
 backend/src/ir/lowering.cpp                |  12 +--
 backend/src/llvm/llvm_gen_backend.cpp      |  27 ++---
 6 files changed, 206 insertions(+), 81 deletions(-)

diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 348aca4..5b35f6a 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1729,7 +1729,7 @@ namespace gbe
     using namespace ir;
     const auto &childInsn = cast<LoadImmInstruction>(insn);
     const auto &imm = childInsn.getImmediate();
-    if(imm.type != TYPE_DOUBLE && imm.type != TYPE_S64 && imm.type != TYPE_U64)
+    if(imm.getType() != TYPE_DOUBLE && imm.getType() != TYPE_S64 && 
+ imm.getType() != TYPE_U64)
       return true;
     return false;
   }
@@ -1739,15 +1739,15 @@ namespace gbe
     using namespace ir;
     int sign = negate ? -1 : 1;
     switch (type) {
-      case TYPE_U32:   return GenRegister::immud(imm.data.u32 * sign);
-      case TYPE_S32:   return GenRegister::immd(imm.data.s32 * sign);
-      case TYPE_FLOAT: return GenRegister::immf(imm.data.f32 * sign);
-      case TYPE_U16: return GenRegister::immuw(imm.data.u16 * sign);
-      case TYPE_S16: return  GenRegister::immw(imm.data.s16 * sign);
-      case TYPE_U8:  return GenRegister::immuw(imm.data.u8 * sign);
-      case TYPE_S8:  return GenRegister::immw(imm.data.s8 * sign);
-      case TYPE_DOUBLE: return GenRegister::immdf(imm.data.f64 * sign);
-      case TYPE_BOOL: return GenRegister::immuw(-imm.data.b);  //return 0xffff when true
+      case TYPE_U32:   return GenRegister::immud(imm.getIntegerValue() * sign);
+      case TYPE_S32:   return GenRegister::immd(imm.getIntegerValue() * sign);
+      case TYPE_FLOAT: return GenRegister::immf(imm.getFloatValue() * sign);
+      case TYPE_U16: return GenRegister::immuw(imm.getIntegerValue() * sign);
+      case TYPE_S16: return  GenRegister::immw((int16_t)imm.getIntegerValue() * sign);
+      case TYPE_U8:  return GenRegister::immuw(imm.getIntegerValue() * sign);
+      case TYPE_S8:  return GenRegister::immw((int8_t)imm.getIntegerValue() * sign);
+      case TYPE_DOUBLE: return GenRegister::immdf(imm.getDoubleValue() * sign);
+      case TYPE_BOOL: return 
+ GenRegister::immuw(-imm.getIntegerValue());  //return 0xffff when true
       default: NOT_SUPPORTED; return GenRegister::immuw(0);
     }
   }
@@ -2529,9 +2529,9 @@ namespace gbe
         if (src0DAG->insn.getOpcode() == OP_LOADI) {
           const auto &loadimm = cast<LoadImmInstruction>(src0DAG->insn);
           const Immediate imm = loadimm.getImmediate();
-          const Type type = imm.type;
+          const Type type = imm.getType();
           GBE_ASSERT(type == TYPE_U32 || type == TYPE_S32);
-          if (type == TYPE_U32 && imm.data.u32 <= 0xffff) {
+          if (type == TYPE_U32 && imm.getIntegerValue() <= 0xffff) {
             sel.push();
               if (sel.isScalarReg(insn.getDst(0)) == true) {
                 sel.curr.execWidth = 1; @@ -2541,13 +2541,13 @@ namespace gbe
 
               sel.MUL(sel.selReg(dst, type),
                       sel.selReg(src1, type),
-                      GenRegister::immuw(imm.data.u32));
+                      GenRegister::immuw(imm.getIntegerValue()));
             sel.pop();
             if (dag.child[childID ^ 1] != NULL)
               dag.child[childID ^ 1]->isRoot = 1;
             return true;
           }
-          if (type == TYPE_S32 && (imm.data.s32 >= -32768 && imm.data.s32 <= 32767)) {
+          if (type == TYPE_S32 && (imm.getIntegerValue() >= -32768 && 
+ imm.getIntegerValue() <= 32767)) {
             sel.push();
               if (sel.isScalarReg(insn.getDst(0)) == true) {
                 sel.curr.execWidth = 1; @@ -2557,7 +2557,7 @@ namespace gbe
 
               sel.MUL(sel.selReg(dst, type),
                       sel.selReg(src1, type),
-                      GenRegister::immw(imm.data.s32));
+                      GenRegister::immw(imm.getIntegerValue()));
             sel.pop();
             if (dag.child[childID ^ 1] != NULL)
               dag.child[childID ^ 1]->isRoot = 1; @@ -2647,21 +2647,21 @@ namespace gbe
             sel.curr.physicalFlag = 0;
             sel.curr.flagIndex = (uint16_t) insn.getDst(0);
           }
-          sel.MOV(dst, imm.data.b ? GenRegister::immuw(0xffff) : GenRegister::immuw(0));
+          sel.MOV(dst, imm.getIntegerValue() ? 
+ GenRegister::immuw(0xffff) : GenRegister::immuw(0));
         break;
         case TYPE_U32:
         case TYPE_S32:
         case TYPE_FLOAT:
           sel.MOV(GenRegister::retype(dst, GEN_TYPE_F),
-                  GenRegister::immf(imm.data.f32));
+                  GenRegister::immf(imm.asFloatValue()));
         break;
-        case TYPE_U16: sel.MOV(dst, GenRegister::immuw(imm.data.u16)); break;
-        case TYPE_S16: sel.MOV(dst, GenRegister::immw(imm.data.s16)); break;
-        case TYPE_U8:  sel.MOV(dst, GenRegister::immuw(imm.data.u8)); break;
-        case TYPE_S8:  sel.MOV(dst, GenRegister::immw(imm.data.s8)); break;
-        case TYPE_DOUBLE: sel.LOAD_DF_IMM(dst, GenRegister::immdf(imm.data.f64), sel.selReg(sel.reg(FAMILY_QWORD))); break;
-        case TYPE_S64: sel.LOAD_INT64_IMM(dst, GenRegister::immint64(imm.data.s64)); break;
-        case TYPE_U64: sel.LOAD_INT64_IMM(dst, GenRegister::immint64(imm.data.u64)); break;
+        case TYPE_U16: sel.MOV(dst, GenRegister::immuw(imm.getIntegerValue())); break;
+        case TYPE_S16: sel.MOV(dst, GenRegister::immw(imm.getIntegerValue())); break;
+        case TYPE_U8:  sel.MOV(dst, GenRegister::immuw(imm.getIntegerValue())); break;
+        case TYPE_S8:  sel.MOV(dst, GenRegister::immw(imm.getIntegerValue())); break;
+        case TYPE_DOUBLE: sel.LOAD_DF_IMM(dst, GenRegister::immdf(imm.getDoubleValue()), sel.selReg(sel.reg(FAMILY_QWORD))); break;
+        case TYPE_S64: sel.LOAD_INT64_IMM(dst, GenRegister::immint64(imm.getIntegerValue())); break;
+        case TYPE_U64: sel.LOAD_INT64_IMM(dst, 
+ GenRegister::immint64(imm.getIntegerValue())); break;
         default: NOT_SUPPORTED;
       }
       sel.pop();
@@ -3204,13 +3204,13 @@ namespace gbe
         const auto imm = immInsn.getImmediate();
         const Type immType = immInsn.getType();
         if (immType == TYPE_S64 &&
-          imm.data.s64 <= INT_MAX &&
-          imm.data.s64 >= INT_MIN) {
-          src = GenRegister::immd((int32_t)imm.data.s64);
+          imm.getIntegerValue() <= INT_MAX &&
+          imm.getIntegerValue() >= INT_MIN) {
+          src = GenRegister::immd((int32_t)imm.getIntegerValue());
           return true;
         } else if (immType == TYPE_U64 &&
-                   imm.data.u64 <= UINT_MAX) {
-          src = GenRegister::immud((uint32_t)imm.data.s64);
+                   imm.getIntegerValue() <= UINT_MAX) {
+          src = GenRegister::immud((uint32_t)imm.getIntegerValue());
           return true;
         }
       } else if (dag->insn.getOpcode() == OP_CVT) { diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp index 519a70b..fa69ad2 100644
--- a/backend/src/ir/function.cpp
+++ b/backend/src/ir/function.cpp
@@ -146,19 +146,19 @@ namespace ir {
   void Function::outImmediate(std::ostream &out, ImmediateIndex index) const {
     GBE_ASSERT(index < immediates.size());
     const Immediate imm = immediates[index];
-    switch (imm.type) {
-      case TYPE_BOOL: out << !!imm.data.u8; break;
-      case TYPE_S8: out << imm.data.s8; break;
-      case TYPE_U8: out << imm.data.u8; break;
-      case TYPE_S16: out << imm.data.s16; break;
-      case TYPE_U16: out << imm.data.u16; break;
-      case TYPE_S32: out << imm.data.s32; break;
-      case TYPE_U32: out << imm.data.u32; break;
-      case TYPE_S64: out << imm.data.s64; break;
-      case TYPE_U64: out << imm.data.u64; break;
-      case TYPE_HALF: out << "half(" << imm.data.u16 << ")"; break;
-      case TYPE_FLOAT: out << imm.data.f32; break;
-      case TYPE_DOUBLE: out << imm.data.f64; break;
+    switch (imm.getType()) {
+      case TYPE_BOOL: out << !!imm.getIntegerValue(); break;
+      case TYPE_S8:
+      case TYPE_U8:
+      case TYPE_S16:
+      case TYPE_U16:
+      case TYPE_S32:
+      case TYPE_U32:
+      case TYPE_S64: out << imm.getIntegerValue(); break;
+      case TYPE_U64: out << (uint64_t)imm.getIntegerValue(); break;
+      case TYPE_HALF: out << "half(" << imm.getIntegerValue() << ")"; break;
+      case TYPE_FLOAT: out << imm.getFloatValue(); break;
+      case TYPE_DOUBLE: out << imm.getDoubleValue(); break;
     }
   }
 
diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp index 67dd03f..1902fde 100644
--- a/backend/src/ir/immediate.hpp
+++ b/backend/src/ir/immediate.hpp
@@ -25,6 +25,7 @@
 #ifndef __GBE_IR_IMMEDIATE_HPP__
 #define __GBE_IR_IMMEDIATE_HPP__
 
+#include <string.h>
 #include "ir/type.hpp"
 #include "sys/platform.hpp"
 
@@ -36,12 +37,38 @@ namespace ir {
   {
   public:
     INLINE Immediate(void) {}
-#define DECL_CONSTRUCTOR(TYPE, FIELD, IR_TYPE)  \
-    Immediate(TYPE FIELD) {                     \
-      this->type = IR_TYPE;                     \
-      this->data.u64 = 0llu;                    \
-      this->data.FIELD = FIELD;                 \
+
+    Type getType(void) const {
+      return type;
+    }
+
+    uint32_t getTypeSize(void) const {
+      switch(type) {
+        default:
+          GBE_ASSERT(0 && "Invalid immeidate type.\n");
+        case TYPE_BOOL:
+        case TYPE_S8:
+        case TYPE_U8:   return 1;
+        case TYPE_S16:
+        case TYPE_U16:  return 2;
+        case TYPE_FLOAT:
+        case TYPE_S32:
+        case TYPE_U32:  return 4;
+        case TYPE_DOUBLE:
+        case TYPE_S64:
+        case TYPE_U64:  return 8;
+      }
     }
+
+#define DECL_CONSTRUCTOR(TYPE, FIELD, IR_TYPE)                  \
+    Immediate(TYPE FIELD) {                                     \
+      this->type = IR_TYPE;                                     \
+      this->elemNum = 1;                                        \
+      this->data.p = &defaultData;                              \
+      defaultData = 0ull;                                       \
+      *this->data.FIELD = FIELD;                                \
+    }
+
     DECL_CONSTRUCTOR(bool, b, TYPE_BOOL)
     DECL_CONSTRUCTOR(int8_t, s8, TYPE_S8)
     DECL_CONSTRUCTOR(uint8_t, u8, TYPE_U8) @@ -54,28 +81,125 @@ namespace ir {
     DECL_CONSTRUCTOR(float, f32, TYPE_FLOAT)
     DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE)  #undef DECL_CONSTRUCTOR
+
+#define DECL_CONSTRUCTOR(TYPE, FIELD, IR_TYPE, ELEMNUM)         \
+    Immediate(TYPE *FIELD, uint32_t ELEMNUM) {                  \
+      this->type = IR_TYPE;                                     \
+      this->elemNum = ELEMNUM;                                  \
+      if (elemNum * ELEMNUM > 8)                                \
+        this->data.p = malloc(ELEMNUM * getTypeSize());         \
+      else                                                      \
+        this->data.p = &defaultData;                            \
+      defaultData = 0ull;                                       \
+      memcpy(this->data.FIELD, FIELD, ELEMNUM * getTypeSize()); \
+    }
+
+    DECL_CONSTRUCTOR(bool, b, TYPE_BOOL, elemNum)
+    DECL_CONSTRUCTOR(int8_t, s8, TYPE_S8, elemNum)
+    DECL_CONSTRUCTOR(uint8_t, u8, TYPE_U8, elemNum)
+    DECL_CONSTRUCTOR(int16_t, s16, TYPE_S16, elemNum)
+    DECL_CONSTRUCTOR(uint16_t, u16, TYPE_S16, elemNum)
+    DECL_CONSTRUCTOR(int32_t, s32, TYPE_S32, elemNum)
+    DECL_CONSTRUCTOR(uint32_t, u32, TYPE_S32, elemNum)
+    DECL_CONSTRUCTOR(int64_t, s64, TYPE_S64, elemNum)
+    DECL_CONSTRUCTOR(uint64_t, u64, TYPE_S64, elemNum)
+    DECL_CONSTRUCTOR(float, f32, TYPE_FLOAT, elemNum)
+    DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE, elemNum) #undef 
+DECL_CONSTRUCTOR
+
+    int64_t getIntegerValue(void) const {
+      switch (type) {
+        default:
+          GBE_ASSERT(0 && "Invalid immediate type.\n");
+        case TYPE_BOOL: return *data.b;
+        case TYPE_S8:   return *data.s8;
+        case TYPE_U8:   return *data.u8;
+        case TYPE_S16:  return *data.s16;
+        case TYPE_U16:  return *data.u16;
+        case TYPE_S32:  return *data.s32;
+        case TYPE_U32:  return *data.u32;
+        case TYPE_S64:  return *data.s64;
+        case TYPE_U64:  return *data.u64;
+      }
+    }
+
+    float getFloatValue(void) const {
+      GBE_ASSERT(type == TYPE_FLOAT);
+      return *data.f32;
+    }
+
+    float asFloatValue(void) const {
+      GBE_ASSERT(type == TYPE_FLOAT || type == TYPE_U32 || type == TYPE_S32);
+      return *data.f32;
+    }
+
+    int64_t asIntegerValue(void) const {
+      GBE_ASSERT(elemNum == 1);
+      return *data.s64;
+    }
+
+    double getDoubleValue(void) const {
+      GBE_ASSERT(type == TYPE_DOUBLE);
+      return *data.f64;
+    }
+
+    Immediate(const Immediate & other) {
+      if (this != &other) {
+        this->type = other.type;
+        this->elemNum = other.elemNum;
+        if (other.data.p != &other.defaultData) {
+          this->data.p = malloc(other.elemNum * other.getTypeSize());
+          memcpy(this->data.p, other.data.p, other.elemNum * other.getTypeSize());
+        }
+        else {
+          this->defaultData = other.defaultData;
+          this->data.p = &this->defaultData;
+        }
+      }
+    }
+
+    Immediate & operator= (const Immediate & other) {
+      *this = Immediate(other);
+      return *this;
+    }
+
+    ~Immediate() {
+      if (data.p != &defaultData) {
+        free(data.p);
+        data.p = NULL;
+      }
+    }
+
+  private:
     union {
-      bool b;
-      int8_t s8;
-      uint8_t u8;
-      int16_t s16;
-      uint16_t u16;
-      int32_t s32;
-      uint32_t u32;
-      int64_t s64;
-      uint64_t u64;
-      float f32;
-      double f64;
+      bool *b;
+      int8_t *s8;
+      uint8_t *u8;
+      int16_t *s16;
+      uint16_t *u16;
+      int32_t *s32;
+      uint32_t *u32;
+      int64_t *s64;
+      uint64_t *u64;
+      float *f32;
+      double *f64;
+      void *p;
     } data;     //!< Value to store
     Type type;  //!< Type of the value
+    uint32_t elemNum; //!< vector imm data type
+    uint64_t defaultData;
+
     GBE_CLASS(Immediate);
   };
 
   /*! Compare two immediates */
   INLINE bool operator< (const Immediate &imm0, const Immediate &imm1) {
-    if (imm0.type != imm1.type)
-      return uint32_t(imm0.type) < uint32_t(imm1.type);
-    return imm0.data.u64 < imm1.data.u64;
+    if (imm0.getType() != imm1.getType())
+      return uint32_t(imm0.getType()) < uint32_t(imm1.getType());
+    else if (imm0.getType() == TYPE_FLOAT || imm0.getType() == TYPE_DOUBLE)
+      return imm0.asIntegerValue() < imm1.asIntegerValue();
+    else
+      return imm0.getIntegerValue() < imm1.getIntegerValue();
   }
 
   /*! A value is stored in a per-function vector. This is the index to it */ diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index 3006893..286841b 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -975,7 +975,7 @@ namespace ir {
         whyNot = "Out-of-bound immediate value index";
         return false;
       }
-      const ir::Type immType = fn.getImmediate(immediateIndex).type;
+      const ir::Type immType = 
+ fn.getImmediate(immediateIndex).getType();
       if (UNLIKELY(type != immType)) {
         whyNot = "Inconsistant type for the immediate value to load";
         return false;
diff --git a/backend/src/ir/lowering.cpp b/backend/src/ir/lowering.cpp index 8042711..739e944 100644
--- a/backend/src/ir/lowering.cpp
+++ b/backend/src/ir/lowering.cpp
@@ -120,19 +120,19 @@ namespace ir {
   };
 
   INLINE uint64_t getOffsetFromImm(const Immediate &imm) {
-    switch (imm.type) {
+    switch (imm.getType()) {
       // bit-cast these ones
       case TYPE_DOUBLE:
-      case TYPE_FLOAT:
+      case TYPE_FLOAT: NOT_SUPPORTED; return 0;
       case TYPE_S64:
       case TYPE_U64:
       case TYPE_U32:
       case TYPE_U16:
-      case TYPE_U8: return imm.data.u64;
+      case TYPE_U8:
       // sign extend these ones
-      case TYPE_S32: return int64_t(imm.data.s32);
-      case TYPE_S16: return int64_t(imm.data.s16);
-      case TYPE_S8: return int64_t(imm.data.s8);
+      case TYPE_S32:
+      case TYPE_S16:
+      case TYPE_S8: return imm.getIntegerValue();
       case TYPE_BOOL:
       case TYPE_HALF: NOT_SUPPORTED; return 0;
     }
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index e6aff27..7f6dbe1 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1003,8 +1003,8 @@ namespace gbe
 
     const ir::ImmediateIndex immIndex = this->newImmediate(c, elemID);
     const ir::Immediate imm = ctx.getImmediate(immIndex);
-    const ir::Register reg = ctx.reg(getFamily(imm.type));
-    ctx.LOADI(imm.type, reg, immIndex);
+    const ir::Register reg = ctx.reg(getFamily(imm.getType()));
+    ctx.LOADI(imm.getType(), reg, immIndex);
     return reg;
   }
 
@@ -1986,7 +1986,7 @@ namespace gbe
           const ir::ImmediateIndex index = ctx.newImmediate(CPV);
           const ir::Immediate imm = ctx.getImmediate(index);
           const ir::Register reg = this->getRegister(dstValue);
-          ctx.LOADI(imm.type, reg, index);
+          ctx.LOADI(imm.getType(), reg, index);
         }
       }
       break;
@@ -2509,9 +2509,9 @@ namespace gbe
       // This is not a kernel argument sampler, we need to append it to sampler set,
       // and allocate a sampler slot for it.
       auto x = processConstant<ir::Immediate>(CPV, InsertExtractFunctor(ctx));
-      GBE_ASSERTM(x.type == ir::TYPE_U16 || x.type == ir::TYPE_S16, "Invalid sampler type");
+      GBE_ASSERTM(x.getType() == ir::TYPE_U16 || x.getType() == 
+ ir::TYPE_S16, "Invalid sampler type");
 
-      index = ctx.getFunction().getSamplerSet()->append(x.data.u32, &ctx);
+      index = 
+ ctx.getFunction().getSamplerSet()->append(x.getIntegerValue(), &ctx);
     } else {
       const ir::Register samplerReg = this->getRegister(*AI);
       index = ctx.getFunction().getSamplerSet()->append(samplerReg, &ctx); @@ -2735,8 +2735,8 @@ handle_read_image:
             GBE_ASSERT(AI != AE); Constant *CPV = dyn_cast<Constant>(*AI);
             assert(CPV);
             auto x = processConstant<ir::Immediate>(CPV, InsertExtractFunctor(ctx));
-            GBE_ASSERTM(x.type == ir::TYPE_U32 || x.type == ir::TYPE_S32, "Invalid sampler type");
-            samplerOffset = x.data.u32;
+            GBE_ASSERTM(x.getType() == ir::TYPE_U32 || x.getType() == ir::TYPE_S32, "Invalid sampler type");
+            samplerOffset = x.getIntegerValue();
 #endif
             const ir::Tuple dstTuple = ctx.arrayTuple(&dstTupleData[0], elemNum);
             const ir::Tuple srcTuple = ctx.arrayTuple(&srcTupleData[0], 3); @@ -3120,10 +3120,11 @@ handle_write_image:
       Constant *CPV = dyn_cast<Constant>(src);
       GBE_ASSERT(CPV);
       const uint64_t elemNum = processConstant<uint64_t>(CPV, U64CPVExtractFunctor(ctx));
-      ir::Immediate imm = ctx.getImmediate(immIndex);
-      imm.data.u64 = ALIGN(imm.data.u64 * elemNum, 4);
       elementSize *= elemNum;
-      ctx.setImmediate(immIndex, imm);
+      if (ctx.getPointerSize() == ir::POINTER_32_BITS)
+        immIndex = ctx.newImmediate(uint32_t(ALIGN(elementSize, 4)));
+      else
+        immIndex = ctx.newImmediate(uint64_t(ALIGN(elementSize, 4)));
     }
 
     // Now emit the stream of instructions to get the allocated pointer @@ -3149,10 +3150,10 @@ handle_write_image:
       }
     }
     // Set the destination register properly
-    ctx.MOV(imm.type, dst, stack);
+    ctx.MOV(imm.getType(), dst, stack);
 
-    ctx.LOADI(imm.type, reg, immIndex);
-    ctx.ADD(imm.type, stack, stack, reg);
+    ctx.LOADI(imm.getType(), reg, immIndex);
+    ctx.ADD(imm.getType(), stack, stack, reg);
     ctx.getFunction().pushStackSize(elementSize);
   }
 
--
1.8.3.2

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list