{
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"));
+ //Extract x's
+ llvm::Value *x1 = m_builder.CreateExtractElement(in[0],
+ m_storage->constantInt(0),
+ name("extractX"));
+ llvm::Value *x2 = m_builder.CreateExtractElement(in[0],
+ m_storage->constantInt(1),
+ name("extractX"));
+ llvm::Value *x3 = m_builder.CreateExtractElement(in[0],
+ m_storage->constantInt(2),
+ name("extractX"));
+ llvm::Value *x4 = m_builder.CreateExtractElement(in[0],
+ m_storage->constantInt(3),
+ name("extractX"));
//cast it to an unsigned int
- x = m_builder.CreateFPToUI(x, IntegerType::get(32), name("xIntCast"));
+ x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast"));
+ x2 = m_builder.CreateFPToUI(x2, IntegerType::get(32), name("x2IntCast"));
+ x3 = m_builder.CreateFPToUI(x3, IntegerType::get(32), name("x3IntCast"));
+ x4 = m_builder.CreateFPToUI(x4, IntegerType::get(32), name("x4IntCast"));
- res[0] = x;
+ res[0] = vectorFromVals(x1, x2, x3, x4);
//only x is valid. the others shouldn't be necessary
/*
res[1] = Constant::getNullValue(m_floatVecType);
std::vector<llvm::Value*> res = mul(in1, in2);
return add(res, in3);
}
+
+std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector)
+{
+ std::vector<llvm::Value*> res(4);
+ res[0] = m_builder.CreateExtractElement(vector,
+ m_storage->constantInt(0),
+ name("extract1X"));
+ res[1] = m_builder.CreateExtractElement(vector,
+ m_storage->constantInt(1),
+ name("extract2X"));
+ res[2] = m_builder.CreateExtractElement(vector,
+ m_storage->constantInt(2),
+ name("extract3X"));
+ res[3] = m_builder.CreateExtractElement(vector,
+ m_storage->constantInt(3),
+ name("extract4X"));
+
+ return res;
+}
{
std::vector<llvm::Value*> res(4);
- res[0] = element(m_input, idx, 0);
- res[1] = element(m_input, idx, 1);
- res[2] = element(m_input, idx, 2);
- res[3] = element(m_input, idx, 3);
+ if (!indIdx) {
+ res[0] = element(m_input, idx, 0);
+ res[1] = element(m_input, idx, 1);
+ res[2] = element(m_input, idx, 2);
+ res[3] = element(m_input, idx, 3);
+ } else {
+ res[0] = indirectElement(m_input, indIdx, 0);
+ res[1] = indirectElement(m_input, indIdx, 1);
+ res[2] = indirectElement(m_input, indIdx, 2);
+ res[3] = indirectElement(m_input, indIdx, 3);
+ }
return res;
}
std::vector<llvm::Value*> StorageSoa::constElement(int idx, llvm::Value *indIdx)
{
std::vector<llvm::Value*> res(4);
- llvm::Value *xChannel = elementPointer(m_consts, idx, 0);
- llvm::Value *yChannel = elementPointer(m_consts, idx, 1);
- llvm::Value *zChannel = elementPointer(m_consts, idx, 2);
- llvm::Value *wChannel = elementPointer(m_consts, idx, 3);
+ llvm::Value *xChannel, *yChannel, *zChannel, *wChannel;
+ if (!indIdx) {
+ xChannel = elementPointer(m_consts, idx, 0);
+ yChannel = elementPointer(m_consts, idx, 1);
+ zChannel = elementPointer(m_consts, idx, 2);
+ wChannel = elementPointer(m_consts, idx, 3);
+ } else {
+ xChannel = indirectElementPointer(m_consts, indIdx, 0);
+ yChannel = indirectElementPointer(m_consts, indIdx, 1);
+ zChannel = indirectElementPointer(m_consts, indIdx, 2);
+ wChannel = indirectElementPointer(m_consts, indIdx, 3);
+ }
res[0] = alignedArrayLoad(xChannel);
res[1] = alignedArrayLoad(yChannel);
{
std::vector<llvm::Value*> res(4);
- res[0] = element(m_output, idx, 0);
- res[1] = element(m_output, idx, 1);
- res[2] = element(m_output, idx, 2);
- res[3] = element(m_output, idx, 3);
+ if (!indIdx) {
+ res[0] = element(m_output, idx, 0);
+ res[1] = element(m_output, idx, 1);
+ res[2] = element(m_output, idx, 2);
+ res[3] = element(m_output, idx, 3);
+ } else {
+ res[0] = indirectElement(m_output, indIdx, 0);
+ res[1] = indirectElement(m_output, indIdx, 1);
+ res[2] = indirectElement(m_output, indIdx, 2);
+ res[3] = indirectElement(m_output, indIdx, 3);
+ }
return res;
}
{
std::vector<llvm::Value*> res(4);
- 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);
+ if (!indIdx) {
+ 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);
+ } else {
+ res[0] = indirectElement(m_temps, indIdx, 0);
+ res[1] = indirectElement(m_temps, indIdx, 1);
+ res[2] = indirectElement(m_temps, indIdx, 2);
+ res[3] = indirectElement(m_temps, indIdx, 3);
+ }
return res;
}
-std::vector<llvm::Value*> StorageSoa::immediateElement(int idx)
+std::vector<llvm::Value*> StorageSoa::immediateElement(int idx, llvm::Value *indIdx)
{
std::vector<llvm::Value*> res(4);
- 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);
+ if (!indIdx) {
+ 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);
+ } else {
+ res[0] = indirectElement(m_immediates, indIdx, 0);
+ res[1] = indirectElement(m_immediates, indIdx, 1);
+ res[2] = indirectElement(m_immediates, indIdx, 2);
+ res[3] = indirectElement(m_immediates, indIdx, 3);
+ }
return res;
}
val = constElement(idx, indIdx);
break;
case Immediate:
- val = immediateElement(idx);
+ val = immediateElement(idx, indIdx);
break;
case Address:
debug_printf("Address not handled in the load phase!\n");
void StorageSoa::addAddress(int idx)
{
+ VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
GlobalVariable *val = new GlobalVariable(
- /*Type=*/IntegerType::get(32),
+ /*Type=*/vectorType,
/*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));
+ //val->setInitializer(constantInt(1));
debug_printf("adding to %d\n", idx);
m_addresses[idx] = val;
}
+
+llvm::Value * StorageSoa::indirectElementPointer(llvm::Value *ptr, llvm::Value *indIdx,
+ int channel) const
+{
+ std::vector<Value*> indices;
+ if (m_immediates == ptr)
+ indices.push_back(constantInt(0));
+ indices.push_back(indIdx);
+ indices.push_back(constantInt(channel));
+
+ GetElementPtrInst *getElem = new GetElementPtrInst(ptr,
+ indices.begin(),
+ indices.end(),
+ name("ptr"),
+ m_block);
+ return getElem;
+}
+
+llvm::Value * StorageSoa::indirectElement(llvm::Value *ptr, llvm::Value *indIdx,
+ int channel) const
+{
+ llvm::Value *res = indirectElementPointer(ptr, indIdx, channel);
+ LoadInst *load = new LoadInst(res, name("element"), false, m_block);
+ //load->setAlignment(8);
+ return load;
+}