redo the way immediates are handled

implement madd
start implementing arl
This commit is contained in:
Zack Rusin 2008-02-14 22:42:57 -05:00
parent ae3375987f
commit f70cc89dbc
5 changed files with 188 additions and 55 deletions

View 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);
}

View 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];

View 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
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);
}
vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
llvm::Value *xChannel = createConstGlobalVector(vals);
void StorageSoa::declareImmediates()
{
if (m_immediatesToFlush.empty())
return;
vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
llvm::Value *yChannel = createConstGlobalVector(vals);
VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
ArrayType *vectorChannels = ArrayType::get(vectorType, 4);
ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size());
m_immediates = new GlobalVariable(
/*Type=*/arrayType,
/*isConstant=*/false,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/name("immediates"),
currentModule());
vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2];
llvm::Value *zChannel = createConstGlobalVector(vals);
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[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3];
llvm::Value *wChannel = createConstGlobalVector(vals);
vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
llvm::Constant *xChannel = createConstGlobalVector(vals);
std::vector<llvm::Value*> res(4);
res[0] = xChannel;
res[1] = yChannel;
res[2] = zChannel;
res[3] = wChannel;
vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
llvm::Constant *yChannel = createConstGlobalVector(vals);
m_immediates[m_immediates.size()] = res;
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_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;
}

View file

@ -29,12 +29,14 @@
#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, std::vector<llvm::Value*> > m_immediates;
std::map<int, llvm::Value*> m_addresses;
std::vector<std::vector<float> > m_immediatesToFlush;
mutable std::map<int, llvm::ConstantInt*> m_constInts;
mutable char m_name[32];

View 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);