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

Function CompositeExtractFeedingConstruct

source/opt/folding_rules.cpp:2396–2468  ·  view source on GitHub ↗

If the OpCompositeConstruct is simply putting back together elements that where extracted from the same source, we can simply reuse the source. This is a common code pattern because of the way that scalar replacement works.

Source from the content-addressed store, hash-verified

2394// This is a common code pattern because of the way that scalar replacement
2395// works.
2396bool CompositeExtractFeedingConstruct(
2397 IRContext* context, Instruction* inst,
2398 const std::vector<const analysis::Constant*>&) {
2399 assert(inst->opcode() == spv::Op::OpCompositeConstruct &&
2400 "Wrong opcode. Should be OpCompositeConstruct.");
2401 analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
2402 uint32_t original_id = 0;
2403
2404 if (inst->NumInOperands() == 0) {
2405 // The struct being constructed has no members.
2406 return false;
2407 }
2408
2409 // Check each element to make sure they are:
2410 // - extractions
2411 // - extracting the same position they are inserting
2412 // - all extract from the same id.
2413 Instruction* first_element_inst = nullptr;
2414 for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
2415 const uint32_t element_id = inst->GetSingleWordInOperand(i);
2416 Instruction* element_inst = def_use_mgr->GetDef(element_id);
2417 if (first_element_inst == nullptr) {
2418 first_element_inst = element_inst;
2419 }
2420
2421 if (element_inst->opcode() != spv::Op::OpCompositeExtract) {
2422 return false;
2423 }
2424
2425 if (!HaveSameIndexesExceptForLast(element_inst, first_element_inst)) {
2426 return false;
2427 }
2428
2429 if (element_inst->GetSingleWordInOperand(element_inst->NumInOperands() -
2430 1) != i) {
2431 return false;
2432 }
2433
2434 if (i == 0) {
2435 original_id =
2436 element_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
2437 } else if (original_id !=
2438 element_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx)) {
2439 return false;
2440 }
2441 }
2442 assert(first_element_inst != nullptr);
2443
2444 // The last check it to see that the object being extracted from is the
2445 // correct type.
2446 Instruction* original_inst = def_use_mgr->GetDef(original_id);
2447 uint32_t original_type_id =
2448 GetElementType(original_inst->type_id(), first_element_inst->begin() + 3,
2449 first_element_inst->end() - 1, def_use_mgr);
2450
2451 if (inst->type_id() != original_type_id) {
2452 return false;
2453 }

Callers

nothing calls this directly

Calls 12

GetElementTypeFunction · 0.85
NumInOperandsMethod · 0.80
SetOpcodeMethod · 0.80
SetInOperandsMethod · 0.80
opcodeMethod · 0.45
get_def_use_mgrMethod · 0.45
GetDefMethod · 0.45
type_idMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected