MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / FoldVectorTimesScalar

Function FoldVectorTimesScalar

source/opt/const_folding_rules.cpp:287–360  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

285}
286
287ConstantFoldingRule FoldVectorTimesScalar() {
288 return [](IRContext* context, Instruction* inst,
289 const std::vector<const analysis::Constant*>& constants)
290 -> const analysis::Constant* {
291 assert(inst->opcode() == spv::Op::OpVectorTimesScalar);
292 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
293 analysis::TypeManager* type_mgr = context->get_type_mgr();
294
295 if (!inst->IsFloatingPointFoldingAllowed()) {
296 if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) {
297 return nullptr;
298 }
299 }
300
301 const analysis::Constant* c1 = constants[0];
302 const analysis::Constant* c2 = constants[1];
303
304 if (c1 && c1->IsZero()) {
305 return c1;
306 }
307
308 if (c2 && c2->IsZero()) {
309 // Get or create the NullConstant for this type.
310 std::vector<uint32_t> ids;
311 return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), ids);
312 }
313
314 if (c1 == nullptr || c2 == nullptr) {
315 return nullptr;
316 }
317
318 // Check result type.
319 const analysis::Type* result_type = type_mgr->GetType(inst->type_id());
320 const analysis::Vector* vector_type = result_type->AsVector();
321 assert(vector_type != nullptr);
322 const analysis::Type* element_type = vector_type->element_type();
323 assert(element_type != nullptr);
324 const analysis::Float* float_type = element_type->AsFloat();
325 assert(float_type != nullptr);
326
327 // Check types of c1 and c2.
328 assert(c1->type()->AsVector() == vector_type);
329 assert(c1->type()->AsVector()->element_type() == element_type &&
330 c2->type() == element_type);
331
332 // Get a float vector that is the result of vector-times-scalar.
333 std::vector<const analysis::Constant*> c1_components =
334 c1->GetVectorComponents(const_mgr);
335 std::vector<uint32_t> ids;
336 if (float_type->width() == 32) {
337 float scalar = c2->GetFloat();
338 for (uint32_t i = 0; i < c1_components.size(); ++i) {
339 utils::FloatProxy<float> result(c1_components[i]->GetFloat() * scalar);
340 std::vector<uint32_t> words = result.GetWords();
341 const analysis::Constant* new_elem =
342 const_mgr->GetConstant(float_type, words);
343 ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id());
344 }

Callers 1

AddFoldingRulesMethod · 0.85

Calls 15

get_constant_mgrMethod · 0.80
get_type_mgrMethod · 0.80
AsVectorMethod · 0.80
AsFloatMethod · 0.80
GetVectorComponentsMethod · 0.80
GetFloatMethod · 0.80
GetWordsMethod · 0.80
GetDoubleMethod · 0.80
HasFloatingPointFunction · 0.70
opcodeMethod · 0.45

Tested by

no test coverage detected