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

Function LoadFeedingExtract

source/opt/folding_rules.cpp:2243–2362  ·  view source on GitHub ↗

If the input to an OpCompositeExtract is an OpLoad, we can change the load into a load of an OpAccessChain.

Source from the content-addressed store, hash-verified

2241// If the input to an OpCompositeExtract is an OpLoad, we can change the
2242// load into a load of an OpAccessChain.
2243bool LoadFeedingExtract(IRContext* context, Instruction* inst,
2244 const std::vector<const analysis::Constant*>&) {
2245 assert(inst->opcode() == spv::Op::OpCompositeExtract &&
2246 "Wrong opcode. Should be OpCompositeExtract.");
2247
2248 analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
2249 uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
2250 Instruction* cinst = def_use_mgr->GetDef(cid);
2251
2252 if (cinst->opcode() != spv::Op::OpLoad) {
2253 return false;
2254 }
2255
2256 Instruction* composite_type_inst = def_use_mgr->GetDef(cinst->type_id());
2257 if (composite_type_inst->opcode() != spv::Op::OpTypeStruct &&
2258 composite_type_inst->opcode() != spv::Op::OpTypeArray) {
2259 return false;
2260 }
2261
2262 // Check the memory operands.
2263 if (cinst->NumInOperands() > 1) {
2264 uint32_t memory_access_mask = cinst->GetSingleWordInOperand(1);
2265 if (memory_access_mask & uint32_t(spv::MemoryAccessMask::Volatile)) {
2266 return false;
2267 }
2268 }
2269
2270 uint32_t ptr_id = cinst->GetSingleWordInOperand(0);
2271 Instruction* ptr_inst = def_use_mgr->GetDef(ptr_id);
2272 Instruction* ptr_type_inst = def_use_mgr->GetDef(ptr_inst->type_id());
2273 assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer);
2274 spv::StorageClass storage_class =
2275 static_cast<spv::StorageClass>(ptr_type_inst->GetSingleWordInOperand(0));
2276
2277 // If the storage class is Function or Private, we do not want to fold.
2278 // These are the storage classes that the local-access-chain-convert pass
2279 // works on.
2280 if (storage_class == spv::StorageClass::Function ||
2281 storage_class == spv::StorageClass::Private) {
2282 return false;
2283 }
2284
2285 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
2286 analysis::TypeManager* type_mgr = context->get_type_mgr();
2287 std::vector<uint32_t> index_ids;
2288 for (uint32_t i = 1; i < inst->NumInOperands(); ++i) {
2289 uint32_t index = inst->GetSingleWordInOperand(i);
2290 const analysis::Constant* index_const =
2291 const_mgr->GetConstant(type_mgr->GetUIntType(), {index});
2292 index_ids.push_back(
2293 const_mgr->GetDefiningInstruction(index_const)->result_id());
2294 }
2295
2296 InstructionBuilder ir_builder(
2297 context, cinst,
2298 IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
2299
2300 uint32_t element_ptr_type_id =

Callers

nothing calls this directly

Calls 15

NumInOperandsMethod · 0.80
get_constant_mgrMethod · 0.80
get_type_mgrMethod · 0.80
GetUIntTypeMethod · 0.80
FindPointerToTypeMethod · 0.80
AddAccessChainMethod · 0.80
GetByteOffsetMethod · 0.80
SetOpcodeMethod · 0.80
SetInOperandsMethod · 0.80
opcodeMethod · 0.45

Tested by

no test coverage detected