1 #include "instructionssoa.h"
3 #include "storagesoa.h"
5 #include "pipe/p_shader_tokens.h"
7 #include <llvm/CallingConv.h>
8 #include <llvm/Constants.h>
9 #include <llvm/Module.h>
10 #include <llvm/Function.h>
11 #include <llvm/Instructions.h>
12 #include <llvm/Transforms/Utils/Cloning.h>
13 #include <llvm/ParamAttrsList.h>
18 /* disable some warnings. this file is autogenerated */
20 #pragma GCC diagnostic ignored "-Wunused-variable"
23 #include "gallivmsoabuiltins.cpp"
25 #pragma GCC diagnostic warning "-Wunused-variable"
28 InstructionsSoa::InstructionsSoa(llvm::Module
*mod
, llvm::Function
*func
,
29 llvm::BasicBlock
*block
, StorageSoa
*storage
)
38 const char * InstructionsSoa::name(const char *prefix
) const
41 snprintf(m_name
, 32, "%s%d", prefix
, m_idx
);
45 llvm::Value
* InstructionsSoa::vectorFromVals(llvm::Value
*x
, llvm::Value
*y
,
46 llvm::Value
*z
, llvm::Value
*w
)
48 VectorType
*vectorType
= VectorType::get(Type::FloatTy
, 4);
49 Constant
*constVector
= Constant::getNullValue(vectorType
);
50 Value
*res
= m_builder
.CreateInsertElement(constVector
, x
,
51 m_storage
->constantInt(0),
53 res
= m_builder
.CreateInsertElement(res
, y
, m_storage
->constantInt(1),
55 res
= m_builder
.CreateInsertElement(res
, z
, m_storage
->constantInt(2),
58 res
= m_builder
.CreateInsertElement(res
, w
, m_storage
->constantInt(3),
63 std::vector
<llvm::Value
*> InstructionsSoa::arl(const std::vector
<llvm::Value
*> in
)
65 std::vector
<llvm::Value
*> res(4);
68 llvm::Value
*x1
= m_builder
.CreateExtractElement(in
[0],
69 m_storage
->constantInt(0),
71 //cast it to an unsigned int
72 x1
= m_builder
.CreateFPToUI(x1
, IntegerType::get(32), name("x1IntCast"));
74 res
[0] = x1
;//vectorFromVals(x1, x2, x3, x4);
75 //only x is valid. the others shouldn't be necessary
77 res[1] = Constant::getNullValue(m_floatVecType);
78 res[2] = Constant::getNullValue(m_floatVecType);
79 res[3] = Constant::getNullValue(m_floatVecType);
86 std::vector
<llvm::Value
*> InstructionsSoa::add(const std::vector
<llvm::Value
*> in1
,
87 const std::vector
<llvm::Value
*> in2
)
89 std::vector
<llvm::Value
*> res(4);
91 res
[0] = m_builder
.CreateAdd(in1
[0], in2
[0], name("addx"));
92 res
[1] = m_builder
.CreateAdd(in1
[1], in2
[1], name("addy"));
93 res
[2] = m_builder
.CreateAdd(in1
[2], in2
[2], name("addz"));
94 res
[3] = m_builder
.CreateAdd(in1
[3], in2
[3], name("addw"));
99 std::vector
<llvm::Value
*> InstructionsSoa::mul(const std::vector
<llvm::Value
*> in1
,
100 const std::vector
<llvm::Value
*> in2
)
102 std::vector
<llvm::Value
*> res(4);
104 res
[0] = m_builder
.CreateMul(in1
[0], in2
[0], name("mulx"));
105 res
[1] = m_builder
.CreateMul(in1
[1], in2
[1], name("muly"));
106 res
[2] = m_builder
.CreateMul(in1
[2], in2
[2], name("mulz"));
107 res
[3] = m_builder
.CreateMul(in1
[3], in2
[3], name("mulw"));
112 void InstructionsSoa::end()
114 m_builder
.CreateRetVoid();
117 std::vector
<llvm::Value
*> InstructionsSoa::madd(const std::vector
<llvm::Value
*> in1
,
118 const std::vector
<llvm::Value
*> in2
,
119 const std::vector
<llvm::Value
*> in3
)
121 std::vector
<llvm::Value
*> res
= mul(in1
, in2
);
122 return add(res
, in3
);
125 std::vector
<llvm::Value
*> InstructionsSoa::extractVector(llvm::Value
*vector
)
127 std::vector
<llvm::Value
*> res(4);
128 res
[0] = m_builder
.CreateExtractElement(vector
,
129 m_storage
->constantInt(0),
131 res
[1] = m_builder
.CreateExtractElement(vector
,
132 m_storage
->constantInt(1),
134 res
[2] = m_builder
.CreateExtractElement(vector
,
135 m_storage
->constantInt(2),
137 res
[3] = m_builder
.CreateExtractElement(vector
,
138 m_storage
->constantInt(3),
144 void InstructionsSoa::createFunctionMap()
146 m_functionsMap
[TGSI_OPCODE_DP3
] = "dp3";
149 llvm::Function
* InstructionsSoa::function(int op
)
151 if (m_functions
.find(op
) != m_functions
.end())
152 return m_functions
[op
];
154 std::string name
= m_functionsMap
[op
];
156 llvm::Function
*originalFunc
= m_builtins
->getFunction(name
);
157 llvm::Function
*func
= CloneFunction(originalFunc
);
158 currentModule()->getFunctionList().push_back(func
);
159 std::cout
<< "Func parent is "<<func
->getParent()
160 <<", cur is "<<currentModule() <<std::endl
;
161 //func->setParent(currentModule());
162 m_functions
[op
] = func
;
166 llvm::Module
* InstructionsSoa::currentModule() const
168 BasicBlock
*block
= m_builder
.GetInsertBlock();
169 if (!block
|| !block
->getParent())
172 return block
->getParent()->getParent();
175 void InstructionsSoa::createBuiltins()
177 m_builtins
= createSoaBuiltins();
180 std::vector
<llvm::Value
*> InstructionsSoa::dp3(const std::vector
<llvm::Value
*> in1
,
181 const std::vector
<llvm::Value
*> in2
)
183 llvm::Function
*func
= function(TGSI_OPCODE_DP3
);
184 std::vector
<Value
*> params
;
186 llvm::Value
*tmp
= allocaTemp();
187 params
.push_back(tmp
);
189 params
.push_back(in1
[0]);
190 params
.push_back(in1
[1]);
191 params
.push_back(in1
[2]);
192 params
.push_back(in1
[3]);
193 params
.push_back(in2
[0]);
194 params
.push_back(in2
[1]);
195 params
.push_back(in2
[2]);
196 params
.push_back(in2
[3]);
197 CallInst
*call
= m_builder
.CreateCall(func
, params
.begin(), params
.end(),
199 call
->setCallingConv(CallingConv::C
);
200 call
->setTailCall(false);
202 std::vector
<Value
*> indices
;
203 indices
.push_back(m_storage
->constantInt(0));
204 indices
.push_back(m_storage
->constantInt(0));
206 GetElementPtrInst
*getElem
= new GetElementPtrInst(tmp
,
210 m_builder
.GetInsertBlock());
211 indices
= std::vector
<Value
*>();
212 indices
.push_back(m_storage
->constantInt(0));
213 GetElementPtrInst
*xElemPtr
= new GetElementPtrInst(getElem
,
214 m_storage
->constantInt(0),
216 m_builder
.GetInsertBlock());
217 GetElementPtrInst
*yElemPtr
= new GetElementPtrInst(getElem
,
218 m_storage
->constantInt(1),
220 m_builder
.GetInsertBlock());
221 GetElementPtrInst
*zElemPtr
= new GetElementPtrInst(getElem
,
222 m_storage
->constantInt(2),
224 m_builder
.GetInsertBlock());
225 GetElementPtrInst
*wElemPtr
= new GetElementPtrInst(getElem
,
226 m_storage
->constantInt(3),
228 m_builder
.GetInsertBlock());
230 std::vector
<llvm::Value
*> res(4);
231 res
[0] = new LoadInst(xElemPtr
);
232 res
[1] = new LoadInst(yElemPtr
);
233 res
[2] = new LoadInst(zElemPtr
);
234 res
[3] = new LoadInst(wElemPtr
);