mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
redo the way immediates are handled
implement madd start implementing arl
This commit is contained in:
parent
ae3375987f
commit
f70cc89dbc
5 changed files with 188 additions and 55 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue