From f70cc89dbc8c0f3e58d6cf8eca92e2df1677c86e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 14 Feb 2008 22:42:57 -0500 Subject: redo the way immediates are handled implement madd start implementing arl --- src/mesa/pipe/llvm/instructionssoa.cpp | 64 ++++++++++++++- src/mesa/pipe/llvm/instructionssoa.h | 9 ++- src/mesa/pipe/llvm/storagesoa.cpp | 142 +++++++++++++++++++++++---------- src/mesa/pipe/llvm/storagesoa.h | 15 +++- src/mesa/pipe/llvm/tgsitollvm.cpp | 17 ++-- 5 files changed, 190 insertions(+), 57 deletions(-) diff --git a/src/mesa/pipe/llvm/instructionssoa.cpp b/src/mesa/pipe/llvm/instructionssoa.cpp index 0c2032e56f..1e144393e0 100644 --- a/src/mesa/pipe/llvm/instructionssoa.cpp +++ b/src/mesa/pipe/llvm/instructionssoa.cpp @@ -1,12 +1,67 @@ #include "instructionssoa.h" +#include "storagesoa.h" + +#include + +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 InstructionsSoa::arl(const std::vector in) +{ + std::vector 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 InstructionsSoa::add(const std::vector in1, const std::vector in2) { @@ -38,9 +93,10 @@ void InstructionsSoa::end() m_builder.CreateRetVoid(); } -const char * InstructionsSoa::name(const char *prefix) const +std::vector InstructionsSoa::madd(const std::vector in1, + const std::vector in2, + const std::vector in3) { - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; + std::vector res = mul(in1, in2); + return add(res, in3); } diff --git a/src/mesa/pipe/llvm/instructionssoa.h b/src/mesa/pipe/llvm/instructionssoa.h index 0195501584..25ff4ac712 100644 --- a/src/mesa/pipe/llvm/instructionssoa.h +++ b/src/mesa/pipe/llvm/instructionssoa.h @@ -46,17 +46,24 @@ public: InstructionsSoa(llvm::Module *mod, llvm::Function *func, 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 madd(const std::vector in1, + const std::vector in2, + const std::vector in3); std::vector mul(const std::vector in1, const std::vector 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]; diff --git a/src/mesa/pipe/llvm/storagesoa.cpp b/src/mesa/pipe/llvm/storagesoa.cpp index 408b29417c..f8f4193fd7 100644 --- a/src/mesa/pipe/llvm/storagesoa.cpp +++ b/src/mesa/pipe/llvm/storagesoa.cpp @@ -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 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 res(4); - res[0] = xChannel; - res[1] = yChannel; - res[2] = zChannel; - res[3] = wChannel; + std::vector arrayVals; + for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { + std::vector vec = m_immediatesToFlush[i]; + std::vector vals(4); + std::vector 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::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 StorageSoa::inputElement(int idx, llvm::Value *indIdx) @@ -145,25 +187,21 @@ std::vector StorageSoa::tempElement(int idx, llvm::Value *indIdx) std::vector StorageSoa::immediateElement(int idx) { std::vector 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 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 &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 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 StorageSoa::load(Argument type, int idx, int swizzle, - llvm::Value *indIdx ) + llvm::Value *indIdx) { std::vector 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 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 & 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 & 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; +} diff --git a/src/mesa/pipe/llvm/storagesoa.h b/src/mesa/pipe/llvm/storagesoa.h index d59168f07d..ea5db2b427 100644 --- a/src/mesa/pipe/llvm/storagesoa.h +++ b/src/mesa/pipe/llvm/storagesoa.h @@ -29,12 +29,14 @@ #define STORAGESOA_H #include +#include #include 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 &vec); std::vector inputElement(int idx, llvm::Value *indIdx =0); std::vector 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 m_addresses; - std::map > m_immediates; + std::vector > m_immediatesToFlush; mutable std::map m_constInts; mutable char m_name[32]; diff --git a/src/mesa/pipe/llvm/tgsitollvm.cpp b/src/mesa/pipe/llvm/tgsitollvm.cpp index 0c2c3a9a0a..071b7d112e 100644 --- a/src/mesa/pipe/llvm/tgsitollvm.cpp +++ b/src/mesa/pipe/llvm/tgsitollvm.cpp @@ -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 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); -- cgit v1.2.3