From 3f3b09d6d86cfd277c5837d15466ee703897aa3d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 20:05:06 +0900 Subject: Rename llvm -> gallivm. Following the directory == library name policy simplifies the build system. --- src/gallium/auxiliary/gallivm/storagesoa.h | 111 +++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/gallium/auxiliary/gallivm/storagesoa.h (limited to 'src/gallium/auxiliary/gallivm/storagesoa.h') diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h new file mode 100644 index 0000000000..6443351f27 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STORAGESOA_H +#define STORAGESOA_H + +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class GlobalVariable; + class LoadInst; + class Value; + class VectorType; + class Module; +} + +class StorageSoa +{ +public: + enum Argument { + Input, + Output, + Temp, + Const, + Immediate, + Address + }; +public: + StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps); + + + std::vector load(Argument type, int idx, int swizzle, + llvm::Value *indIdx =0); + void store(Argument type, int idx, const std::vector &val, + int mask); + + void addImmediate(float *vec); + void declareImmediates(); + + void addAddress(int idx); + + llvm::Value * addrElement(int idx) const; + + llvm::ConstantInt *constantInt(int) const; +private: + llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, + int channel) const; + llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, + int channel) const; + const char *name(const char *prefix) const; + llvm::Value *alignedArrayLoad(llvm::Value *val); + llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalVector(const std::vector &vec); + + std::vector inputElement(llvm::Value *indIdx); + std::vector constElement(llvm::Value *indIdx); + std::vector outputElement(llvm::Value *indIdx); + std::vector tempElement(llvm::Value *indIdx); + std::vector immediateElement(llvm::Value *indIdx); +private: + llvm::BasicBlock *m_block; + + llvm::Value *m_input; + llvm::Value *m_output; + llvm::Value *m_consts; + llvm::Value *m_temps; + llvm::GlobalVariable *m_immediates; + + std::map m_addresses; + + std::vector > m_immediatesToFlush; + + mutable std::map m_constInts; + mutable char m_name[32]; + mutable int m_idx; +}; + +#endif -- cgit v1.2.3 From e884c7ed9a14aabaa86f6710c594d20812ed11d9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 1 Mar 2008 08:04:21 -0500 Subject: start implementing start of bultins --- src/gallium/auxiliary/gallivm/Makefile | 7 +- src/gallium/auxiliary/gallivm/instructions.cpp | 10 ++ src/gallium/auxiliary/gallivm/instructionssoa.cpp | 116 ++++++++++++++++++++++ src/gallium/auxiliary/gallivm/instructionssoa.h | 14 ++- src/gallium/auxiliary/gallivm/soabuiltins.c | 58 +++++++++++ src/gallium/auxiliary/gallivm/storagesoa.cpp | 28 +++--- src/gallium/auxiliary/gallivm/storagesoa.h | 15 +-- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 38 ++----- src/gallium/include/pipe/p_shader_tokens.h | 20 ++-- 9 files changed, 239 insertions(+), 67 deletions(-) create mode 100644 src/gallium/auxiliary/gallivm/soabuiltins.c (limited to 'src/gallium/auxiliary/gallivm/storagesoa.h') diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index 39fac6ea4a..c24e19e062 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -15,7 +15,7 @@ GALLIVM_SOURCES = \ storagesoa.cpp \ instructionssoa.cpp -INC_SOURCES = gallivm_builtins.cpp +INC_SOURCES = gallivm_builtins.cpp gallivmsoabuiltins.cpp CPP_SOURCES = \ $(GALLIVM_SOURCES) @@ -65,8 +65,10 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins +gallivmsoabuiltins.cpp: soabuiltins.c + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-module -o=$@ -f -for=shader -funcname=createSoaBuiltins # Emacs tags tags: @@ -78,6 +80,7 @@ clean: -rm -f *.o */*.o *~ *.so *~ server/*.o -rm -f depend depend.bak -rm -f gallivm_builtins.cpp + -rm -f gallivmsoabuiltins.cpp symlinks: diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 55d39fa5f1..8919491792 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,15 @@ using namespace llvm; #include "gallivm_builtins.cpp" +#if 0 + +llvm::Value *arrayFromChannels(std::vector &vals) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); +} +#endif + static inline std::string createFuncName(int label) { std::ostringstream stream; diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index a4d5046637..5739cf0cde 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -2,9 +2,28 @@ #include "storagesoa.h" +#include "pipe/p_shader_tokens.h" + +#include #include +#include +#include +#include +#include +#include + +#include + +/* disable some warnings. this file is autogenerated */ +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif using namespace llvm; +#include "gallivmsoabuiltins.cpp" +#if defined(__GNUC__) +#pragma GCC diagnostic warning "-Wunused-variable" +#endif InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, StorageSoa *storage) @@ -12,6 +31,8 @@ InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, m_storage(storage), m_idx(0) { + createFunctionMap(); + createBuiltins(); } const char * InstructionsSoa::name(const char *prefix) const @@ -119,3 +140,98 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) return res; } + +void InstructionsSoa::createFunctionMap() +{ + m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; +} + +llvm::Function * InstructionsSoa::function(int op) +{ + if (m_functions.find(op) != m_functions.end()) + return m_functions[op]; + + std::string name = m_functionsMap[op]; + + llvm::Function *originalFunc = m_builtins->getFunction(name); + llvm::Function *func = CloneFunction(originalFunc); + currentModule()->getFunctionList().push_back(func); + std::cout << "Func parent is "<getParent() + <<", cur is "<setParent(currentModule()); + m_functions[op] = func; + return func; +} + +llvm::Module * InstructionsSoa::currentModule() const +{ + BasicBlock *block = m_builder.GetInsertBlock(); + if (!block || !block->getParent()) + return 0; + + return block->getParent()->getParent(); +} + +void InstructionsSoa::createBuiltins() +{ + m_builtins = createSoaBuiltins(); +} + +std::vector InstructionsSoa::dp3(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_DP3); + std::vector params; + + llvm::Value *tmp = allocaTemp(); + params.push_back(tmp); + + params.push_back(in1[0]); + params.push_back(in1[1]); + params.push_back(in1[2]); + params.push_back(in1[3]); + params.push_back(in2[0]); + params.push_back(in2[1]); + params.push_back(in2[2]); + params.push_back(in2[3]); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), + name("dp3")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + + std::vector indices; + indices.push_back(m_storage->constantInt(0)); + indices.push_back(m_storage->constantInt(0)); + + GetElementPtrInst *getElem = new GetElementPtrInst(tmp, + indices.begin(), + indices.end(), + name("allocaPtr"), + m_builder.GetInsertBlock()); + indices = std::vector(); + indices.push_back(m_storage->constantInt(0)); + GetElementPtrInst *xElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(0), + name("xPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *yElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(1), + name("yPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *zElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(2), + name("zPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *wElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(3), + name("wPtr"), + m_builder.GetInsertBlock()); + + std::vector res(4); + res[0] = new LoadInst(xElemPtr); + res[1] = new LoadInst(yElemPtr); + res[2] = new LoadInst(zElemPtr); + res[3] = new LoadInst(wElemPtr); + + return res; +} diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 4169dcbb2e..5c26687150 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -30,6 +30,7 @@ #include +#include #include namespace llvm { @@ -47,9 +48,10 @@ public: llvm::BasicBlock *block, StorageSoa *storage); std::vector arl(const std::vector in); - std::vector add(const std::vector in1, const std::vector in2); + std::vector dp3(const std::vector in1, + const std::vector in2); std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); @@ -62,9 +64,19 @@ private: const char * name(const char *prefix) const; llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, llvm::Value *z, llvm::Value *w); + void createFunctionMap(); + void createBuiltins(); + llvm::Function *function(int); + llvm::Module *currentModule() const; + llvm::Value *allocaTemp(); private: llvm::LLVMFoldingBuilder m_builder; StorageSoa *m_storage; + + std::map m_functionsMap; + std::map m_functions; + llvm::Module *m_builtins; + private: mutable int m_idx; mutable char m_name[32]; diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c new file mode 100644 index 0000000000..0b428a750f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * This file is compiled with clang into the LLVM bitcode + * + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +void dp3(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + float4 dot = (tmp0x * tmp1x) + (tmp0y * tmp1y) + + (tmp0z * tmp1z); + + res[0] = dot; + res[1] = dot; + res[2] = dot; + res[3] = dot; +} + +#if 0 +void yo(float4 *out, float4 *in) +{ + float4 res[4]; + + dp3(res, in[0], in[1], in[2], in[3], + in[4], in[5], in[6], in[7]); + out[1] = res[1]; +} +#endif diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index ed0674a96f..bb6fe3d7e1 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -277,7 +277,7 @@ llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &v return constVector; } -std::vector StorageSoa::load(Argument type, int idx, int swizzle, +std::vector StorageSoa::load(enum tgsi_file_type type, int idx, int swizzle, llvm::Value *indIdx) { std::vector val(4); @@ -292,25 +292,29 @@ std::vector StorageSoa::load(Argument type, int idx, int swizzle, debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); switch(type) { - case Input: + case TGSI_FILE_INPUT: val = inputElement(realIndex); break; - case Output: + case TGSI_FILE_OUTPUT: val = outputElement(realIndex); break; - case Temp: + case TGSI_FILE_TEMPORARY: val = tempElement(realIndex); break; - case Const: + case TGSI_FILE_CONSTANT: val = constElement(realIndex); break; - case Immediate: + case TGSI_FILE_IMMEDIATE: val = immediateElement(realIndex); break; - case Address: + case TGSI_FILE_ADDRESS: debug_printf("Address not handled in the load phase!\n"); assert(0); break; + default: + debug_printf("Unknown load!\n"); + assert(0); + break; } if (!gallivm_is_swizzle(swizzle)) return val; @@ -324,21 +328,21 @@ std::vector StorageSoa::load(Argument type, int idx, int swizzle, return res; } -void StorageSoa::store(Argument type, int idx, const std::vector &val, +void StorageSoa::store(enum tgsi_file_type type, int idx, const std::vector &val, int mask) { llvm::Value *out = 0; switch(type) { - case Output: + case TGSI_FILE_OUTPUT: out = m_output; break; - case Temp: + case TGSI_FILE_TEMPORARY: out = m_temps; break; - case Input: + case TGSI_FILE_INPUT: out = m_input; break; - case Address: { + case TGSI_FILE_ADDRESS: { llvm::Value *addr = m_addresses[idx]; if (!addr) { addAddress(idx); diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h index 6443351f27..ae2fc7c6ae 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.h +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -28,6 +28,8 @@ #ifndef STORAGESOA_H #define STORAGESOA_H +#include + #include #include #include @@ -45,15 +47,6 @@ namespace llvm { class StorageSoa { -public: - enum Argument { - Input, - Output, - Temp, - Const, - Immediate, - Address - }; public: StorageSoa(llvm::BasicBlock *block, llvm::Value *input, @@ -62,9 +55,9 @@ public: llvm::Value *temps); - std::vector load(Argument type, int idx, int swizzle, + std::vector load(enum tgsi_file_type type, int idx, int swizzle, llvm::Value *indIdx =0); - void store(Argument type, int idx, const std::vector &val, + void store(enum tgsi_file_type type, int idx, const std::vector &val, int mask); void addImmediate(float *vec); diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 2cb4acce32..a52ee26434 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -708,25 +708,9 @@ translate_instructionir(llvm::Module *module, if (src->SrcRegister.Indirect) { indIdx = storage->addrElement(src->SrcRegisterInd.Index); } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->load(StorageSoa::Const, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->load(StorageSoa::Input, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->load(StorageSoa::Temp, - 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, indIdx); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } + + val = storage->load((enum tgsi_file_type)src->SrcRegister.File, + src->SrcRegister.Index, swizzle, indIdx); inputs[i] = val; } @@ -763,6 +747,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); } break; case TGSI_OPCODE_DP4: { @@ -1067,19 +1052,8 @@ translate_instructionir(llvm::Module *module, for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->store(StorageSoa::Output, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->store(StorageSoa::Temp, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->store(StorageSoa::Address, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } + storage->store((enum tgsi_file_type)dst->DstRegister.File, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); } } diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 0a6145a6bf..b110f01291 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -42,15 +42,17 @@ struct tgsi_token unsigned Extended : 1; /* BOOL */ }; -#define TGSI_FILE_NULL 0 -#define TGSI_FILE_CONSTANT 1 -#define TGSI_FILE_INPUT 2 -#define TGSI_FILE_OUTPUT 3 -#define TGSI_FILE_TEMPORARY 4 -#define TGSI_FILE_SAMPLER 5 -#define TGSI_FILE_ADDRESS 6 -#define TGSI_FILE_IMMEDIATE 7 -#define TGSI_FILE_COUNT 8 /**< how many TGSI_FILE_ types */ +enum tgsi_file_type { + TGSI_FILE_NULL =0, + TGSI_FILE_CONSTANT =1, + TGSI_FILE_INPUT =2, + TGSI_FILE_OUTPUT =3, + TGSI_FILE_TEMPORARY =4, + TGSI_FILE_SAMPLER =5, + TGSI_FILE_ADDRESS =6, + TGSI_FILE_IMMEDIATE =7, + TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */ +}; #define TGSI_DECLARE_RANGE 0 -- cgit v1.2.3 From 94ba48bd85ec5c62e1a303d8bb3fc25c8e153247 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 7 Oct 2008 21:11:01 +0200 Subject: Gallivm: fix the constant layout, this gets a bunch of progs/ working. Notably, gears doesn't. --- src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 5 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 5 ++ src/gallium/auxiliary/gallivm/instructionssoa.h | 1 + src/gallium/auxiliary/gallivm/storagesoa.cpp | 71 +++++++++++++++++++---- src/gallium/auxiliary/gallivm/storagesoa.h | 7 ++- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 10 ++-- 6 files changed, 78 insertions(+), 21 deletions(-) (limited to 'src/gallium/auxiliary/gallivm/storagesoa.h') diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp index 3a4a41e544..3a2f2878a3 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -158,8 +158,8 @@ void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); llvm::ExecutionEngine *ee = cpu->engine; assert(ee); - /*FIXME : remove */ - ee->DisableLazyCompilation(); + /*FIXME : why was this disabled ? we need it for pow/sqrt/... */ + ee->DisableLazyCompilation(false); ee->addModuleProvider(mp); llvm::Function *func = func_for_shader(prog); @@ -202,7 +202,6 @@ int gallivm_cpu_vs_exec(struct gallivm_prog *prog, unsigned int i, j; unsigned slot; vertex_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); for (i = 0; i < count; i += MAX_TGSI_VERTICES) { diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index a658072551..1143ee0b0b 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -171,6 +171,11 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) return res; } +llvm::IRBuilder<>* InstructionsSoa::getIRBuilder() +{ + return &m_builder; +} + void InstructionsSoa::createFunctionMap() { m_functionsMap[TGSI_OPCODE_ABS] = "abs"; diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 3817fdc904..d6831e0a6b 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -76,6 +76,7 @@ public: void end(); std::vector extractVector(llvm::Value *vector); + llvm::IRBuilder<>* getIRBuilder(); private: const char * name(const char *prefix) const; llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index 78d754371f..646b9d7ca0 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -91,19 +91,29 @@ void StorageSoa::declareImmediates() for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { std::vector vec = m_immediatesToFlush[i]; std::vector vals(4); + float val; std::vector channelArray; - vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; - llvm::Constant *xChannel = createConstGlobalVector(vals); + val = vec[0]; + llvm::Constant *xChannel = createConstGlobalFloat(val); + val = vec[1]; + llvm::Constant *yChannel = createConstGlobalFloat(val); + val = vec[2]; + llvm::Constant *zChannel = createConstGlobalFloat(val); + val = vec[3]; + llvm::Constant *wChannel = createConstGlobalFloat(val); - vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; +// vals[0] = vec[0]; vals[1] = vec[1]; vals[2] = vec[2]; vals[3] = vec[3]; +// llvm::Constant *xChannel = createConstGlobalVector(vec[0]); + +/* 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); + llvm::Constant *wChannel = createConstGlobalVector(vals);*/ channelArray.push_back(xChannel); channelArray.push_back(yChannel); channelArray.push_back(zChannel); @@ -144,22 +154,54 @@ std::vector StorageSoa::inputElement(llvm::Value *idx) return res; } -std::vector StorageSoa::constElement(llvm::Value *idx) +llvm::Value* StorageSoa::unpackConstElement(llvm::IRBuilder<>* m_builder, llvm::Value* vector, int cc) +{ + std::vector x(4); + x[0] = m_builder->CreateExtractElement(vector, + constantInt(cc), + name("x")); + + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + Constant *constVector = Constant::getNullValue(vectorType); + Value *res = m_builder->CreateInsertElement(constVector, x[0], + constantInt(0), + name("vecx")); + res = m_builder->CreateInsertElement(res, x[0], constantInt(1), + name("vecxx")); + res = m_builder->CreateInsertElement(res, x[0], constantInt(2), + name("vecxxx")); + res = m_builder->CreateInsertElement(res, x[0], constantInt(3), + name("vecxxxx")); + return res; +} + +std::vector StorageSoa::constElement(llvm::IRBuilder<>* m_builder, llvm::Value *idx) { std::vector res(4); + std::vector res2(4); llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; xChannel = elementPointer(m_consts, idx, 0); - yChannel = elementPointer(m_consts, idx, 1); +/* yChannel = elementPointer(m_consts, idx, 1); zChannel = elementPointer(m_consts, idx, 2); - wChannel = elementPointer(m_consts, idx, 3); + wChannel = elementPointer(m_consts, idx, 3);*/ res[0] = alignedArrayLoad(xChannel); +/* res[1] = alignedArrayLoad(xChannel); + res[2] = alignedArrayLoad(xChannel); + res[3] = alignedArrayLoad(xChannel);*/ + + + res2[0]=unpackConstElement(m_builder, res[0],0); + res2[1]=unpackConstElement(m_builder, res[0],1); + res2[2]=unpackConstElement(m_builder, res[0],2); + res2[3]=unpackConstElement(m_builder, res[0],3); +/*res[0] = alignedArrayLoad(xChannel); res[1] = alignedArrayLoad(yChannel); res[2] = alignedArrayLoad(zChannel); - res[3] = alignedArrayLoad(wChannel); + res[3] = alignedArrayLoad(wChannel);*/ - return res; + return res2; } std::vector StorageSoa::outputElement(llvm::Value *idx) @@ -260,6 +302,12 @@ llvm::Module * StorageSoa::currentModule() const return m_block->getParent()->getParent(); } +llvm::Constant * StorageSoa::createConstGlobalFloat(const float val) +{ + Constant*c = ConstantFP::get(APFloat(val)); + return c; +} + llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) { VectorType *vectorType = VectorType::get(Type::FloatTy, 4); @@ -278,7 +326,7 @@ llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &v } std::vector StorageSoa::load(enum tgsi_file_type type, int idx, int swizzle, - llvm::Value *indIdx) + llvm::IRBuilder<>* m_builder,llvm::Value *indIdx) { std::vector val(4); @@ -302,7 +350,8 @@ std::vector StorageSoa::load(enum tgsi_file_type type, int idx, in val = tempElement(realIndex); break; case TGSI_FILE_CONSTANT: - val = constElement(realIndex); + val = constElement(m_builder, realIndex); + printf("constant COUCOU index %d\n",realIndex); break; case TGSI_FILE_IMMEDIATE: val = immediateElement(realIndex); diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h index ae2fc7c6ae..f21ca6ec43 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.h +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -29,6 +29,7 @@ #define STORAGESOA_H #include +#include #include #include @@ -56,7 +57,7 @@ public: std::vector load(enum tgsi_file_type type, int idx, int swizzle, - llvm::Value *indIdx =0); + llvm::IRBuilder<>* m_builder, llvm::Value *indIdx =0); void store(enum tgsi_file_type type, int idx, const std::vector &val, int mask); @@ -76,10 +77,12 @@ private: const char *name(const char *prefix) const; llvm::Value *alignedArrayLoad(llvm::Value *val); llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalFloat(const float val); llvm::Constant *createConstGlobalVector(const std::vector &vec); std::vector inputElement(llvm::Value *indIdx); - std::vector constElement(llvm::Value *indIdx); + llvm::Value* unpackConstElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx, int cc); + std::vector constElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx); std::vector outputElement(llvm::Value *indIdx); std::vector tempElement(llvm::Value *indIdx); std::vector immediateElement(llvm::Value *indIdx); diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 7292c0e366..1191a6cae9 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -52,7 +52,7 @@ static inline FunctionType *vertexShaderFunctionType() // pass are castable to the following: // [4 x <4 x float>] inputs, // [4 x <4 x float>] output, - // [4 x [4 x float]] consts, + // [4 x [1 x float]] consts, // [4 x <4 x float>] temps std::vector funcArgs; @@ -61,7 +61,7 @@ static inline FunctionType *vertexShaderFunctionType() PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); - ArrayType *constsArray = ArrayType::get(floatArray, 4); + ArrayType *constsArray = ArrayType::get(floatArray, 1); PointerType *constsArrayPtr = PointerType::get(constsArray, 0); funcArgs.push_back(vectorArrayPtr);//inputs @@ -246,6 +246,7 @@ translate_instruction(llvm::Module *module, val = storage->constElement(src->SrcRegister.Index, indIdx); } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { val = storage->inputElement(src->SrcRegister.Index, indIdx); + // FIXME we should not be generating elements for temporaries, this creates useless memory writes } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { val = storage->tempElement(src->SrcRegister.Index); } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { @@ -676,6 +677,7 @@ translate_instruction(llvm::Module *module, if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + // FIXME we should not be generating elements for temporaries, this creates useless memory writes } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { @@ -707,9 +709,8 @@ translate_instructionir(llvm::Module *module, if (src->SrcRegister.Indirect) { indIdx = storage->addrElement(src->SrcRegisterInd.Index); } - val = storage->load((enum tgsi_file_type)src->SrcRegister.File, - src->SrcRegister.Index, swizzle, indIdx); + src->SrcRegister.Index, swizzle, instr->getIRBuilder(), indIdx); inputs[i] = val; } @@ -1025,7 +1026,6 @@ translate_instructionir(llvm::Module *module, /* store results */ for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - storage->store((enum tgsi_file_type)dst->DstRegister.File, dst->DstRegister.Index, out, dst->DstRegister.WriteMask); } -- cgit v1.2.3 From b81a7dc2d8ba09b48d5022cf9ff65f2fad890e11 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 30 Oct 2008 23:52:59 +0100 Subject: gallivm: replace the temp parameters of the JIT function with alloca'ed temps. This avoids useless writes of temporary results. --- src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 6 ++-- src/gallium/auxiliary/gallivm/storagesoa.cpp | 44 +++++++++++++++++++-------- src/gallium/auxiliary/gallivm/storagesoa.h | 10 +++--- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 11 ++----- 4 files changed, 41 insertions(+), 30 deletions(-) (limited to 'src/gallium/auxiliary/gallivm/storagesoa.h') diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp index 3a2f2878a3..93a9748bdb 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -179,8 +179,7 @@ struct gallivm_cpu_engine * gallivm_global_cpu_engine() typedef void (*vertex_shader_runner)(void *ainputs, void *dests, - float (*aconsts)[4], - void *temps); + float (*aconsts)[4]); #define MAX_TGSI_VERTICES 4 /*! @@ -223,8 +222,7 @@ int gallivm_cpu_vs_exec(struct gallivm_prog *prog, /* run shader */ runner(machine->Inputs, machine->Outputs, - (float (*)[4]) constants, - machine->Temps); + (float (*)[4]) constants); /* Unswizzle all output results */ diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index 4fc075cf6d..e1e5cabcf5 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -48,13 +48,11 @@ using namespace llvm; StorageSoa::StorageSoa(llvm::BasicBlock *block, llvm::Value *input, llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps) + llvm::Value *consts) : m_block(block), m_input(input), m_output(output), m_consts(consts), - m_temps(temps), m_immediates(0), m_idx(0) { @@ -169,7 +167,7 @@ std::vector StorageSoa::constElement(llvm::IRBuilder<>* m_builder, { llvm::Value* res; std::vector res2(4); - llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; + llvm::Value *xChannel; xChannel = elementPointer(m_consts, idx, 0); @@ -195,14 +193,15 @@ std::vector StorageSoa::outputElement(llvm::Value *idx) return res; } -std::vector StorageSoa::tempElement(llvm::Value *idx) +std::vector StorageSoa::tempElement(llvm::IRBuilder<>* m_builder, int idx) { std::vector res(4); + llvm::Value *temp = m_temps[idx]; - res[0] = element(m_temps, idx, 0); - res[1] = element(m_temps, idx, 1); - res[2] = element(m_temps, idx, 2); - res[3] = element(m_temps, idx, 3); + res[0] = element(temp, constantInt(0), 0); + res[1] = element(temp, constantInt(0), 1); + res[2] = element(temp, constantInt(0), 2); + res[3] = element(temp, constantInt(0), 3); return res; } @@ -326,7 +325,7 @@ std::vector StorageSoa::load(enum tgsi_file_type type, int idx, in val = outputElement(realIndex); break; case TGSI_FILE_TEMPORARY: - val = tempElement(realIndex); + val = tempElement(m_builder, idx); break; case TGSI_FILE_CONSTANT: val = constElement(m_builder, realIndex); @@ -355,19 +354,39 @@ std::vector StorageSoa::load(enum tgsi_file_type type, int idx, in return res; } +llvm::Value * StorageSoa::allocaTemp(llvm::IRBuilder<>* m_builder) +{ + VectorType *vector = VectorType::get(Type::FloatTy, 4); + ArrayType *vecArray = ArrayType::get(vector, 4); + AllocaInst *alloca = new AllocaInst(vecArray, "temp", + m_builder->GetInsertBlock()); + + return alloca; +} + + void StorageSoa::store(enum tgsi_file_type type, int idx, const std::vector &val, - int mask) + int mask, llvm::IRBuilder<>* m_builder) { llvm::Value *out = 0; + llvm::Value *realIndex = 0; switch(type) { case TGSI_FILE_OUTPUT: out = m_output; + realIndex = constantInt(idx); break; case TGSI_FILE_TEMPORARY: - out = m_temps; + // if that temp doesn't already exist, alloca it + if (m_temps.find(idx) == m_temps.end()) + m_temps[idx] = allocaTemp(m_builder); + + out = m_temps[idx]; + + realIndex = constantInt(0); break; case TGSI_FILE_INPUT: out = m_input; + realIndex = constantInt(idx); break; case TGSI_FILE_ADDRESS: { llvm::Value *addr = m_addresses[idx]; @@ -385,7 +404,6 @@ void StorageSoa::store(enum tgsi_file_type type, int idx, const std::vector load(enum tgsi_file_type type, int idx, int swizzle, llvm::IRBuilder<>* m_builder, llvm::Value *indIdx =0); void store(enum tgsi_file_type type, int idx, const std::vector &val, - int mask); + int mask, llvm::IRBuilder<>* m_builder); void addImmediate(float *vec); void declareImmediates(); @@ -84,7 +83,7 @@ private: llvm::Value* unpackConstElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx, int cc); std::vector constElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx); std::vector outputElement(llvm::Value *indIdx); - std::vector tempElement(llvm::Value *indIdx); + std::vector tempElement(llvm::IRBuilder<>* m_builder, int idx); std::vector immediateElement(llvm::Value *indIdx); private: llvm::BasicBlock *m_block; @@ -92,12 +91,13 @@ private: llvm::Value *m_input; llvm::Value *m_output; llvm::Value *m_consts; - llvm::Value *m_temps; + std::map m_temps; llvm::GlobalVariable *m_immediates; std::map m_addresses; std::vector > m_immediatesToFlush; + llvm::Value * allocaTemp(llvm::IRBuilder<>* m_builder); mutable std::map m_constInts; mutable char m_name[32]; diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 1191a6cae9..c11b88af9e 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -53,7 +53,6 @@ static inline FunctionType *vertexShaderFunctionType() // [4 x <4 x float>] inputs, // [4 x <4 x float>] output, // [4 x [1 x float]] consts, - // [4 x <4 x float>] temps std::vector funcArgs; VectorType *vectorType = VectorType::get(Type::FloatTy, 4); @@ -67,7 +66,6 @@ static inline FunctionType *vertexShaderFunctionType() funcArgs.push_back(vectorArrayPtr);//inputs funcArgs.push_back(vectorArrayPtr);//output funcArgs.push_back(constsArrayPtr);//consts - funcArgs.push_back(vectorArrayPtr);//temps FunctionType *functionType = FunctionType::get( /*Result=*/Type::VoidTy, @@ -246,7 +244,6 @@ translate_instruction(llvm::Module *module, val = storage->constElement(src->SrcRegister.Index, indIdx); } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { val = storage->inputElement(src->SrcRegister.Index, indIdx); - // FIXME we should not be generating elements for temporaries, this creates useless memory writes } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { val = storage->tempElement(src->SrcRegister.Index); } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { @@ -677,7 +674,6 @@ translate_instruction(llvm::Module *module, if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - // FIXME we should not be generating elements for temporaries, this creates useless memory writes } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { @@ -1027,7 +1023,8 @@ translate_instructionir(llvm::Module *module, for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; storage->store((enum tgsi_file_type)dst->DstRegister.File, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + dst->DstRegister.Index, out, dst->DstRegister.WriteMask, + instr->getIRBuilder() ); } } @@ -1122,8 +1119,6 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, output->setName("outputs"); Value *consts = args++; consts->setName("consts"); - Value *temps = args++; - temps->setName("temps"); BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); @@ -1132,7 +1127,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, fi = tgsi_default_full_instruction(); fd = tgsi_default_full_declaration(); - StorageSoa storage(label_entry, input, output, consts, temps); + StorageSoa storage(label_entry, input, output, consts); InstructionsSoa instr(mod, shader, label_entry, &storage); while(!tgsi_parse_end_of_tokens(&parse)) { -- cgit v1.2.3