redo the way immediates are handled
authorZack Rusin <zack@tungstengraphics.com>
Fri, 15 Feb 2008 03:42:57 +0000 (22:42 -0500)
committerZack Rusin <zack@tungstengraphics.com>
Fri, 15 Feb 2008 06:17:17 +0000 (01:17 -0500)
implement madd
start implementing arl

src/mesa/pipe/llvm/instructionssoa.cpp
src/mesa/pipe/llvm/instructionssoa.h
src/mesa/pipe/llvm/storagesoa.cpp
src/mesa/pipe/llvm/storagesoa.h
src/mesa/pipe/llvm/tgsitollvm.cpp

index 0c2032e56ff6d62e80088c9c053604e68217b723..1e144393e0fcf12afe935375b4dfea9506439e63 100644 (file)
@@ -1,12 +1,67 @@
 #include "instructionssoa.h"
 
+#include "storagesoa.h"
+
+#include <llvm/Constants.h>
+
+using namespace llvm;
+
 InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func,
                                  llvm::BasicBlock *block, StorageSoa *storage)
    : m_builder(block),
+     m_storage(storage),
      m_idx(0)
 {
 }
 
+const char * InstructionsSoa::name(const char *prefix) const
+{
+   ++m_idx;
+   snprintf(m_name, 32, "%s%d", prefix, m_idx);
+   return m_name;
+}
+
+llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y,
+                                              llvm::Value *z, llvm::Value *w)
+{
+   VectorType  *vectorType = VectorType::get(Type::FloatTy, 4);
+   Constant *constVector = Constant::getNullValue(vectorType);
+   Value *res = m_builder.CreateInsertElement(constVector, x,
+                                              m_storage->constantInt(0),
+                                              name("vecx"));
+   res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1),
+                               name("vecxy"));
+   res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2),
+                               name("vecxyz"));
+   if (w)
+      res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3),
+                                          name("vecxyzw"));
+   return res;
+}
+
+std::vector<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in)
+{
+   std::vector<llvm::Value*> res(4);
+
+   //Extract the first x (all 4 should be the same)
+   llvm::Value *x = m_builder.CreateExtractElement(in[0],
+                                                   m_storage->constantInt(0),
+                                                   name("extractX"));
+   //cast it to an unsigned int
+   x = m_builder.CreateFPToUI(x, IntegerType::get(32), name("xIntCast"));
+
+   res[0] = x;
+   //only x is valid. the others shouldn't be necessary
+   /*
+   res[1] = Constant::getNullValue(m_floatVecType);
+   res[2] = Constant::getNullValue(m_floatVecType);
+   res[3] = Constant::getNullValue(m_floatVecType);
+   */
+
+   return res;
+}
+
+
 std::vector<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1,
                                                const std::vector<llvm::Value*> in2)
 {
@@ -38,9 +93,10 @@ void InstructionsSoa::end()
    m_builder.CreateRetVoid();
 }
 
-const char * InstructionsSoa::name(const char *prefix) const
+std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1,
+                                                const std::vector<llvm::Value*> in2,
+                                                const std::vector<llvm::Value*> in3)
 {
-   ++m_idx;
-   snprintf(m_name, 32, "%s%d", prefix, m_idx);
-   return m_name;
+   std::vector<llvm::Value*> res = mul(in1, in2);
+   return add(res, in3);
 }
index 0195501584499e03bfde50936d46ef45d9ce5e11..25ff4ac712a797555b28c3ea8792d945f09802ad 100644 (file)
@@ -46,17 +46,24 @@ public:
    InstructionsSoa(llvm::Module *mod, llvm::Function *func,
                    llvm::BasicBlock *block, StorageSoa *storage);
 
+   std::vector<llvm::Value*> arl(const std::vector<llvm::Value*> in);
+
    std::vector<llvm::Value*> add(const std::vector<llvm::Value*> in1,
                                  const std::vector<llvm::Value*> in2);
+   std::vector<llvm::Value*> madd(const std::vector<llvm::Value*> in1,
+                                  const std::vector<llvm::Value*> in2,
+                                  const std::vector<llvm::Value*> in3);
    std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
                                  const std::vector<llvm::Value*> in2);
    void         end();
 
 private:
    const char * name(const char *prefix) const;
+   llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y,
+                               llvm::Value *z, llvm::Value *w);
 private:
    llvm::LLVMFoldingBuilder  m_builder;
-
+   StorageSoa *m_storage;
 private:
    mutable int  m_idx;
    mutable char m_name[32];
index 408b29417cefb07348b1d1dd5dbc328c2a0f0cb7..f8f4193fd7f4602ac1659fc5550076e96b4f8f39 100644 (file)
@@ -55,39 +55,81 @@ StorageSoa::StorageSoa(llvm::BasicBlock *block,
      m_output(output),
      m_consts(consts),
      m_temps(temps),
+     m_immediates(0),
      m_idx(0)
 {
 }
 
 void StorageSoa::addImmediate(float *vec)
 {
-   float vals[4]; //decompose into soa
-
-   vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
-   llvm::Value *xChannel = createConstGlobalVector(vals);
-
-   vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
-   llvm::Value *yChannel = createConstGlobalVector(vals);
+   std::vector<float> vals(4);
+   vals[0] = vec[0];
+   vals[1] = vec[1];
+   vals[2] = vec[2];
+   vals[3] = vec[3];
+   m_immediatesToFlush.push_back(vals);
+}
 
+void StorageSoa::declareImmediates()
+{
+   if (m_immediatesToFlush.empty())
+      return;
 
-   vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2];
-   llvm::Value *zChannel = createConstGlobalVector(vals);
+   VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
+   ArrayType  *vectorChannels = ArrayType::get(vectorType, 4);
+   ArrayType  *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size());
 
-   vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3];
-   llvm::Value *wChannel = createConstGlobalVector(vals);
+   m_immediates = new GlobalVariable(
+      /*Type=*/arrayType,
+      /*isConstant=*/false,
+      /*Linkage=*/GlobalValue::ExternalLinkage,
+      /*Initializer=*/0, // has initializer, specified below
+      /*Name=*/name("immediates"),
+      currentModule());
 
-   std::vector<llvm::Value*> res(4);
-   res[0] = xChannel;
-   res[1] = yChannel;
-   res[2] = zChannel;
-   res[3] = wChannel;
+   std::vector<Constant*> arrayVals;
+   for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) {
+      std::vector<float> vec = m_immediatesToFlush[i];
+      std::vector<float> vals(4);
+      std::vector<Constant*> channelArray;
+
+      vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
+      llvm::Constant *xChannel = createConstGlobalVector(vals);
+
+      vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
+      llvm::Constant *yChannel = createConstGlobalVector(vals);
+
+      vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2];
+      llvm::Constant *zChannel = createConstGlobalVector(vals);
+
+      vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3];
+      llvm::Constant *wChannel = createConstGlobalVector(vals);
+      channelArray.push_back(xChannel);
+      channelArray.push_back(yChannel);
+      channelArray.push_back(zChannel);
+      channelArray.push_back(wChannel);
+      Constant *constChannels = ConstantArray::get(vectorChannels,
+                                                   channelArray);
+      arrayVals.push_back(constChannels);
+   }
+   Constant *constArray = ConstantArray::get(arrayType, arrayVals);
+   m_immediates->setInitializer(constArray);
 
-   m_immediates[m_immediates.size()] = res;
+   m_immediatesToFlush.clear();
 }
 
 llvm::Value *StorageSoa::addrElement(int idx) const
 {
-   return 0;
+   std::map<int, llvm::Value*>::const_iterator itr = m_addresses.find(idx);
+   if (itr == m_addresses.end()) {
+      debug_printf("Trying to access invalid shader 'address'\n");
+      return 0;
+   }
+   llvm::Value * res = (*itr).second;
+
+   res = new LoadInst(res, name("addr"), false, m_block);
+
+   return res;
 }
 
 std::vector<llvm::Value*> StorageSoa::inputElement(int idx, llvm::Value *indIdx)
@@ -145,25 +187,21 @@ std::vector<llvm::Value*> StorageSoa::tempElement(int idx, llvm::Value *indIdx)
 std::vector<llvm::Value*> StorageSoa::immediateElement(int idx)
 {
    std::vector<llvm::Value*> res(4);
-   res = m_immediates[idx];
 
-   res[0] = new LoadInst(res[0], name("immx"), false, m_block);
-   res[1] = new LoadInst(res[1], name("immy"), false, m_block);
-   res[2] = new LoadInst(res[2], name("immz"), false, m_block);
-   res[3] = new LoadInst(res[3], name("immw"), false, m_block);
+   res[0] = element(m_immediates, idx, 0);
+   res[1] = element(m_immediates, idx, 1);
+   res[2] = element(m_immediates, idx, 2);
+   res[3] = element(m_immediates, idx, 3);
 
    return res;
 }
 
-llvm::Value * StorageSoa::extractIndex(llvm::Value *vec)
-{
-   return 0;
-}
-
 llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, int index,
                                          int channel) const
 {
    std::vector<Value*> indices;
+   if (m_immediates == ptr)
+      indices.push_back(constantInt(0));
    indices.push_back(constantInt(index));
    indices.push_back(constantInt(channel));
 
@@ -220,17 +258,9 @@ llvm::Module * StorageSoa::currentModule() const
     return m_block->getParent()->getParent();
 }
 
-llvm::Value * StorageSoa::createConstGlobalVector(float *vec)
+llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector<float> &vec)
 {
    VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
-   GlobalVariable *immediate = new GlobalVariable(
-      /*Type=*/vectorType,
-      /*isConstant=*/true,
-      /*Linkage=*/GlobalValue::ExternalLinkage,
-      /*Initializer=*/0, // has initializer, specified below
-      /*Name=*/name("immediate"),
-      currentModule());
-
    std::vector<Constant*> immValues;
    ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0]));
    ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1]));
@@ -242,16 +272,15 @@ llvm::Value * StorageSoa::createConstGlobalVector(float *vec)
    immValues.push_back(constw);
    Constant  *constVector = ConstantVector::get(vectorType, immValues);
 
-   // Global Variable Definitions
-   immediate->setInitializer(constVector);
-
-   return immediate;
+   return constVector;
 }
 
 std::vector<llvm::Value*> StorageSoa::load(Argument type, int idx, int swizzle,
-                                           llvm::Value *indIdx )
+                                           llvm::Value *indIdx)
 {
    std::vector<llvm::Value*> val(4);
+   debug_printf("XXXXXXXXX indIdx = %p\n", indIdx);
+   assert(!indIdx);
    switch(type) {
    case Input:
       val = inputElement(idx, indIdx);
@@ -269,7 +298,7 @@ std::vector<llvm::Value*> StorageSoa::load(Argument type, int idx, int swizzle,
       val = immediateElement(idx);
       break;
    case Address:
-      debug_printf("Address not handled in the fetch phase!\n");
+      debug_printf("Address not handled in the load phase!\n");
       assert(0);
       break;
    }
@@ -299,6 +328,17 @@ void StorageSoa::store(Argument type, int idx, const std::vector<llvm::Value*> &
    case Input:
       out = m_input;
       break;
+   case Address: {
+      llvm::Value *addr = m_addresses[idx];
+      if (!addr) {
+         addAddress(idx);
+         addr = m_addresses[idx];
+         assert(addr);
+      }
+      new StoreInst(val[0], addr, false, m_block);
+      return;
+      break;
+   }
    default:
       debug_printf("Can't save output of this type: %d !\n", type);
       assert(0);
@@ -322,3 +362,19 @@ void StorageSoa::store(Argument type, int idx, const std::vector<llvm::Value*> &
       new StoreInst(val[3], wChannel, false, m_block);
    }
 }
+
+void StorageSoa::addAddress(int idx)
+{
+   GlobalVariable *val = new GlobalVariable(
+      /*Type=*/IntegerType::get(32),
+      /*isConstant=*/false,
+      /*Linkage=*/GlobalValue::ExternalLinkage,
+      /*Initializer=*/0, // has initializer, specified below
+      /*Name=*/name("address"),
+      currentModule());
+   //val->setInitializer(Constant::getNullValue(IntegerType::get(32)));
+   val->setInitializer(constantInt(1));
+
+   debug_printf("adding to %d\n", idx);
+   m_addresses[idx] = val;
+}
index d59168f07dab13acb060299cbee9e60ac180143c..ea5db2b427659fd33072cdd8c6fca1ff4a2b1377 100644 (file)
 #define STORAGESOA_H
 
 #include <vector>
+#include <list>
 #include <map>
 
 namespace llvm {
    class BasicBlock;
    class Constant;
    class ConstantInt;
+   class GlobalVariable;
    class LoadInst;
    class Value;
    class VectorType;
@@ -66,20 +68,22 @@ public:
               int mask);
 
    void addImmediate(float *vec);
+   void declareImmediates();
+
+   void addAddress(int idx);
 
    llvm::Value  * addrElement(int idx) const;
 
-   llvm::Value *extractIndex(llvm::Value *vec);
+   llvm::ConstantInt *constantInt(int) const;
 private:
    llvm::Value *elementPointer(llvm::Value *ptr, int index,
                                int channel) const;
    llvm::Value *element(llvm::Value *ptr, int index,
                         int channel) const;
    const char *name(const char *prefix) const;
-   llvm::ConstantInt *constantInt(int) const;
    llvm::Value  *alignedArrayLoad(llvm::Value *val);
    llvm::Module *currentModule() const;
-   llvm::Value  *createConstGlobalVector(float *vec);
+   llvm::Constant  *createConstGlobalVector(const std::vector<float> &vec);
 
    std::vector<llvm::Value*> inputElement(int idx, llvm::Value *indIdx =0);
    std::vector<llvm::Value*> constElement(int idx, llvm::Value *indIdx =0);
@@ -93,8 +97,11 @@ private:
    llvm::Value *m_output;
    llvm::Value *m_consts;
    llvm::Value *m_temps;
+   llvm::GlobalVariable *m_immediates;
+
+   std::map<int, llvm::Value*> m_addresses;
 
-   std::map<int, std::vector<llvm::Value*> > m_immediates;
+   std::vector<std::vector<float> > m_immediatesToFlush;
 
    mutable std::map<int, llvm::ConstantInt*> m_constInts;
    mutable char        m_name[32];
index 0c2c3a9a0acd7fcbba01c1e587250e5206db4555..071b7d112e42df91a9017344a5a8c70946210972 100644 (file)
@@ -148,10 +148,14 @@ translate_declaration(struct gallivm_ir *prog,
 static void
 translate_declarationir(struct gallivm_ir *,
                       llvm::Module *,
-                      StorageSoa *,
-                      struct tgsi_full_declaration *,
+                      StorageSoa *storage,
+                      struct tgsi_full_declaration *decl,
                       struct tgsi_full_declaration *)
 {
+   if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
+      int idx = decl->u.DeclarationRange.First;
+      storage->addAddress(idx);
+   }
 }
 
 static void
@@ -703,7 +707,7 @@ translate_instructionir(llvm::Module *module,
 
       if (src->SrcRegister.Indirect) {
          indIdx = storage->addrElement(src->SrcRegisterInd.Index);
-         indIdx = storage->extractIndex(indIdx);
+         debug_printf("AAAAAAAAAAAAAAA INDIRECT %p\n", indIdx);
       }
       if (src->SrcRegister.File == TGSI_FILE_CONSTANT) {
          val = storage->load(StorageSoa::Const,
@@ -713,13 +717,13 @@ translate_instructionir(llvm::Module *module,
                              src->SrcRegister.Index, swizzle, indIdx);
       } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
          val = storage->load(StorageSoa::Temp,
-                             src->SrcRegister.Index, swizzle);
+                             src->SrcRegister.Index, swizzle, indIdx);
       } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
          val = storage->load(StorageSoa::Output,
                              src->SrcRegister.Index, swizzle, indIdx);
       } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
          val = storage->load(StorageSoa::Immediate,
-                             src->SrcRegister.Index, swizzle);
+                             src->SrcRegister.Index, swizzle, indIdx);
       } else {
          fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
          return;
@@ -731,6 +735,7 @@ translate_instructionir(llvm::Module *module,
    std::vector<llvm::Value*> out(4);
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_ARL: {
+      out = instr->arl(inputs[0]);
    }
       break;
    case TGSI_OPCODE_MOV: {
@@ -780,6 +785,7 @@ translate_instructionir(llvm::Module *module,
    }
       break;
    case TGSI_OPCODE_MAD: {
+      out = instr->madd(inputs[0], inputs[1], inputs[2]);
    }
       break;
    case TGSI_OPCODE_SUB: {
@@ -1198,6 +1204,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
          break;
 
       case TGSI_TOKEN_TYPE_INSTRUCTION:
+         storage.declareImmediates();
          translate_instructionir(mod, &storage, &instr,
                                  &parse.FullToken.FullInstruction,
                                  &fi, instno);