add code handling dependencies between generated code
authorZack Rusin <zack@tungstengraphics.com>
Thu, 13 Mar 2008 02:51:57 +0000 (22:51 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Thu, 13 Mar 2008 02:57:52 +0000 (22:57 -0400)
src/gallium/auxiliary/gallivm/instructionssoa.cpp
src/gallium/auxiliary/gallivm/instructionssoa.h
src/gallium/auxiliary/gallivm/soabuiltins.c
src/gallium/auxiliary/gallivm/tgsitollvm.cpp

index 89d513afd0d9b06e17d0d45c2286ecdbe6205361..6f83b56a7277900a11ffc0887b006b9f2cabfa10 100644 (file)
@@ -143,8 +143,16 @@ std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector)
 
 void InstructionsSoa::createFunctionMap()
 {
-   m_functionsMap[TGSI_OPCODE_DP3] = "dp3";
-   m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
+   m_functionsMap[TGSI_OPCODE_DP3]   = "dp3";
+   m_functionsMap[TGSI_OPCODE_DP4]   = "dp4";
+   m_functionsMap[TGSI_OPCODE_POWER] = "pow";
+}
+
+void InstructionsSoa::createDependencies()
+{
+   std::vector<std::string> powDeps(1);
+   powDeps[0] = "powf";
+   m_builtinDependencies["pow"] = powDeps;
 }
 
 llvm::Function * InstructionsSoa::function(int op)
@@ -154,15 +162,14 @@ llvm::Function * InstructionsSoa::function(int op)
 
     std::string name = m_functionsMap[op];
 
+    std::vector<std::string> deps = m_builtinDependencies[name];
+    for (unsigned int i = 0; i < deps.size(); ++i) {
+       injectFunction(m_builtins->getFunction(deps[i]));
+    }
+
     llvm::Function *originalFunc = m_builtins->getFunction(name);
-    llvm::Function *func = CloneFunction(originalFunc);
-    currentModule()->getFunctionList().push_back(func);
-    std::cout << "Func parent is "<<func->getParent()
-              <<", cur is "<<currentModule() <<std::endl;
-    func->dump();
-       //func->setParent(currentModule());
-    m_functions[op] = func;
-    return func;
+    injectFunction(originalFunc, op);
+    return m_functions[op];
 }
 
 llvm::Module * InstructionsSoa::currentModule() const
@@ -177,6 +184,7 @@ llvm::Module * InstructionsSoa::currentModule() const
 void InstructionsSoa::createBuiltins()
 {
    m_builtins = createSoaBuiltins();
+   createDependencies();
 }
 
 std::vector<llvm::Value*> InstructionsSoa::dp3(const std::vector<llvm::Value*> in1,
@@ -304,3 +312,71 @@ std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std
 
    return allocaToResult(allocaPtr);
 }
+
+std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1,
+                                               const std::vector<llvm::Value*> in2)
+{
+   llvm::Function *func = function(TGSI_OPCODE_POWER);
+   return callBuiltin(func, in1, in2);
+}
+
+void checkFunction(Function *func)
+{
+   for (Function::const_iterator BI = func->begin(), BE = func->end();
+        BI != BE; ++BI) {
+      const BasicBlock &BB = *BI;
+      for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end();
+           II != IE; ++II) {
+         const Instruction &I = *II;
+         std::cout<< "Instr = "<<I;
+         for (unsigned op = 0, E = I.getNumOperands(); op != E; ++op) {
+            const Value *Op = I.getOperand(op);
+            std::cout<< "\top = "<<Op<<"("<<op<<")"<<std::endl;
+            //I->setOperand(op, V);
+  }
+      }
+   }
+}
+
+void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op)
+{
+   assert(originalFunc);
+   std::cout << "injecting function originalFunc " <<originalFunc->getName() <<std::endl;
+   if (op != TGSI_OPCODE_LAST) {
+      /* in this case it's possible the function has been already
+       * injected as part of the dependency chain, which gets
+       * injected below */
+      llvm::Function *func = currentModule()->getFunction(originalFunc->getName());
+      if (func) {
+         m_functions[op] = func;
+         return;
+      }
+   }
+   llvm::Function *func = 0;
+   if (originalFunc->isDeclaration()) {
+      std::cout << "function decleration" <<std::endl;
+      func = new Function(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage,
+                          originalFunc->getName(), currentModule());
+      func->setCallingConv(CallingConv::C);
+      const ParamAttrsList *pal = 0;
+      func->setParamAttrs(pal);
+      currentModule()->dump();
+   } else {
+      DenseMap<const Value*, Value *> val;
+      val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf");
+      std::cout <<" replacing "<<m_builtins->getFunction("powf")
+                <<", with " <<currentModule()->getFunction("powf")<<std::endl;
+      func = CloneFunction(originalFunc, val);
+      std::cout<<"1111-------------------------------"<<std::endl;
+      checkFunction(originalFunc);
+      std::cout<<"2222-------------------------------"<<std::endl;
+      checkFunction(func);
+      std::cout <<"XXXX = " <<val[m_builtins->getFunction("powf")]<<std::endl;
+      currentModule()->getFunctionList().push_back(func);
+      std::cout << "Func parent is "<<func->getParent()
+                <<", cur is "<<currentModule() <<std::endl;
+   }
+   if (op != TGSI_OPCODE_LAST) {
+      m_functions[op] = func;
+   }
+}
index 3ef51dcaff7b804a0e570296dcb70d7aa6f15305..b9104ea286d0c61b8b54c8f0a840ef5568f79ac0 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef INSTRUCTIONSSOA_H
 #define INSTRUCTIONSSOA_H
 
+#include <pipe/p_shader_tokens.h>
 #include <llvm/Support/LLVMBuilder.h>
 
 #include <map>
@@ -59,6 +60,8 @@ public:
                                   const std::vector<llvm::Value*> in3);
    std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
                                  const std::vector<llvm::Value*> in2);
+   std::vector<llvm::Value*> pow(const std::vector<llvm::Value*> in1,
+                                 const std::vector<llvm::Value*> in2);
    void         end();
 
    std::vector<llvm::Value*> extractVector(llvm::Value *vector);
@@ -68,6 +71,7 @@ private:
                                llvm::Value *z, llvm::Value *w);
    void createFunctionMap();
    void createBuiltins();
+   void createDependencies();
    llvm::Function *function(int);
    llvm::Module *currentModule() const;
    llvm::Value *allocaTemp();
@@ -81,6 +85,7 @@ private:
                                          const std::vector<llvm::Value*> in1,
                                          const std::vector<llvm::Value*> in2,
                                          const std::vector<llvm::Value*> in3);
+   void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST);
 private:
    llvm::LLVMFoldingBuilder  m_builder;
    StorageSoa *m_storage;
@@ -88,6 +93,7 @@ private:
    std::map<int, std::string> m_functionsMap;
    std::map<int, llvm::Function*> m_functions;
    llvm::Module *m_builtins;
+   std::map<std::string, std::vector<std::string> > m_builtinDependencies;
 
 private:
    mutable int  m_idx;
index 24c14e1b698a913b44220f1999b2e2afb90de6be..4d658be5208bd1c18d810d488f3cb016aa163a73 100644 (file)
@@ -60,6 +60,24 @@ void dp4(float4 *res,
    res[3] = dot;
 }
 
+extern float powf(float num, float p);
+
+void pow(float4 *res,
+         float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
+         float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
+{
+   float4 p;
+   p.x = powf(tmp0x.x, tmp1x.x);
+   p.y = powf(tmp0x.y, tmp1x.y);
+   p.z = powf(tmp0x.z, tmp1x.z);
+   p.w = powf(tmp0x.w, tmp1x.w);
+
+   res[0] = p;
+   res[1] = p;
+   res[2] = p;
+   res[3] = p;
+}
+
 #if 0
 void yo(float4 *out, float4 *in)
 {
index 3f65865a5a50706090634d31b62c3a9b45028e05..d2b747ffd1c1ddf97f7192f1084741a1ae53e0c5 100644 (file)
@@ -806,6 +806,7 @@ translate_instructionir(llvm::Module *module,
    }
       break;
    case TGSI_OPCODE_POWER: {
+      out = instr->pow(inputs[0], inputs[1]);
    }
       break;
    case TGSI_OPCODE_CROSSPRODUCT: {