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";
147 m_functionsMap
[TGSI_OPCODE_DP4
] = "dp4";
150 llvm::Function
* InstructionsSoa::function(int op
)
152 if (m_functions
.find(op
) != m_functions
.end())
153 return m_functions
[op
];
155 std::string name
= m_functionsMap
[op
];
157 llvm::Function
*originalFunc
= m_builtins
->getFunction(name
);
158 llvm::Function
*func
= CloneFunction(originalFunc
);
159 currentModule()->getFunctionList().push_back(func
);
160 std::cout
<< "Func parent is "<<func
->getParent()
161 <<", cur is "<<currentModule() <<std::endl
;
163 //func->setParent(currentModule());
164 m_functions
[op
] = func
;
168 llvm::Module
* InstructionsSoa::currentModule() const
170 BasicBlock
*block
= m_builder
.GetInsertBlock();
171 if (!block
|| !block
->getParent())
174 return block
->getParent()->getParent();
177 void InstructionsSoa::createBuiltins()
179 m_builtins
= createSoaBuiltins();
182 std::vector
<llvm::Value
*> InstructionsSoa::dp3(const std::vector
<llvm::Value
*> in1
,
183 const std::vector
<llvm::Value
*> in2
)
185 llvm::Function
*func
= function(TGSI_OPCODE_DP3
);
186 return callBuiltin(func
, in1
, in2
);
189 llvm::Value
* InstructionsSoa::allocaTemp()
191 VectorType
*vector
= VectorType::get(Type::FloatTy
, 4);
192 ArrayType
*vecArray
= ArrayType::get(vector
, 4);
193 AllocaInst
*alloca
= new AllocaInst(vecArray
, name("tmpRes"),
194 m_builder
.GetInsertBlock());
196 std::vector
<Value
*> indices
;
197 indices
.push_back(m_storage
->constantInt(0));
198 indices
.push_back(m_storage
->constantInt(0));
199 GetElementPtrInst
*getElem
= new GetElementPtrInst(alloca
,
203 m_builder
.GetInsertBlock());
207 std::vector
<llvm::Value
*> InstructionsSoa::allocaToResult(llvm::Value
*allocaPtr
)
209 GetElementPtrInst
*xElemPtr
= new GetElementPtrInst(allocaPtr
,
210 m_storage
->constantInt(0),
212 m_builder
.GetInsertBlock());
213 GetElementPtrInst
*yElemPtr
= new GetElementPtrInst(allocaPtr
,
214 m_storage
->constantInt(1),
216 m_builder
.GetInsertBlock());
217 GetElementPtrInst
*zElemPtr
= new GetElementPtrInst(allocaPtr
,
218 m_storage
->constantInt(2),
220 m_builder
.GetInsertBlock());
221 GetElementPtrInst
*wElemPtr
= new GetElementPtrInst(allocaPtr
,
222 m_storage
->constantInt(3),
224 m_builder
.GetInsertBlock());
226 std::vector
<llvm::Value
*> res(4);
227 res
[0] = new LoadInst(xElemPtr
, name("xRes"), false, m_builder
.GetInsertBlock());
228 res
[1] = new LoadInst(yElemPtr
, name("yRes"), false, m_builder
.GetInsertBlock());
229 res
[2] = new LoadInst(zElemPtr
, name("zRes"), false, m_builder
.GetInsertBlock());
230 res
[3] = new LoadInst(wElemPtr
, name("wRes"), false, m_builder
.GetInsertBlock());
235 std::vector
<llvm::Value
*> InstructionsSoa::dp4(const std::vector
<llvm::Value
*> in1
,
236 const std::vector
<llvm::Value
*> in2
)
238 llvm::Function
*func
= function(TGSI_OPCODE_DP4
);
239 return callBuiltin(func
, in1
, in2
);
242 std::vector
<Value
*> InstructionsSoa::callBuiltin(llvm::Function
*func
, const std::vector
<llvm::Value
*> in1
)
244 std::vector
<Value
*> params
;
246 llvm::Value
*allocaPtr
= allocaTemp();
247 params
.push_back(allocaPtr
);
248 params
.push_back(in1
[0]);
249 params
.push_back(in1
[1]);
250 params
.push_back(in1
[2]);
251 params
.push_back(in1
[3]);
252 CallInst
*call
= m_builder
.CreateCall(func
, params
.begin(), params
.end());
253 call
->setCallingConv(CallingConv::C
);
254 call
->setTailCall(false);
256 return allocaToResult(allocaPtr
);
259 std::vector
<Value
*> InstructionsSoa::callBuiltin(llvm::Function
*func
, const std::vector
<llvm::Value
*> in1
,
260 const std::vector
<llvm::Value
*> in2
)
262 std::vector
<Value
*> params
;
264 llvm::Value
*allocaPtr
= allocaTemp();
265 params
.push_back(allocaPtr
);
266 params
.push_back(in1
[0]);
267 params
.push_back(in1
[1]);
268 params
.push_back(in1
[2]);
269 params
.push_back(in1
[3]);
270 params
.push_back(in2
[0]);
271 params
.push_back(in2
[1]);
272 params
.push_back(in2
[2]);
273 params
.push_back(in2
[3]);
274 CallInst
*call
= m_builder
.CreateCall(func
, params
.begin(), params
.end());
275 call
->setCallingConv(CallingConv::C
);
276 call
->setTailCall(false);
278 return allocaToResult(allocaPtr
);
281 std::vector
<Value
*> InstructionsSoa::callBuiltin(llvm::Function
*func
, const std::vector
<llvm::Value
*> in1
,
282 const std::vector
<llvm::Value
*> in2
,
283 const std::vector
<llvm::Value
*> in3
)
285 std::vector
<Value
*> params
;
287 llvm::Value
*allocaPtr
= allocaTemp();
288 params
.push_back(allocaPtr
);
289 params
.push_back(in1
[0]);
290 params
.push_back(in1
[1]);
291 params
.push_back(in1
[2]);
292 params
.push_back(in1
[3]);
293 params
.push_back(in2
[0]);
294 params
.push_back(in2
[1]);
295 params
.push_back(in2
[2]);
296 params
.push_back(in2
[3]);
297 params
.push_back(in3
[0]);
298 params
.push_back(in3
[1]);
299 params
.push_back(in3
[2]);
300 params
.push_back(in3
[3]);
301 CallInst
*call
= m_builder
.CreateCall(func
, params
.begin(), params
.end());
302 call
->setCallingConv(CallingConv::C
);
303 call
->setTailCall(false);
305 return allocaToResult(allocaPtr
);