summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2008-03-12 22:51:57 -0400
committerZack Rusin <zack@tungstengraphics.com>2008-03-12 22:57:52 -0400
commitcac037d36d451e8cafbb4a759d0edf9fa8b1ca81 (patch)
tree5f4aa06ba9f1fa8c6091d9c164d217a245d06430
parent2366bb1baf2e9ae5b6ecf19f66ae9e0a4b0d2f36 (diff)
add code handling dependencies between generated code
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp96
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.h6
-rw-r--r--src/gallium/auxiliary/gallivm/soabuiltins.c18
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp1
4 files changed, 111 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index 89d513afd0..6f83b56a72 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -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;
+ }
+}
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h
index 3ef51dcaff..b9104ea286 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.h
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.h
@@ -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;
diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c
index 24c14e1b69..4d658be520 100644
--- a/src/gallium/auxiliary/gallivm/soabuiltins.c
+++ b/src/gallium/auxiliary/gallivm/soabuiltins.c
@@ -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)
{
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 3f65865a5a..d2b747ffd1 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -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: {