| 1320 | } |
| 1321 | |
| 1322 | bool CanCreateConstant(opt::IRContext* ir_context, uint32_t type_id) { |
| 1323 | opt::Instruction* type_instr = ir_context->get_def_use_mgr()->GetDef(type_id); |
| 1324 | assert(type_instr != nullptr && "The type must exist."); |
| 1325 | assert(spvOpcodeGeneratesType(type_instr->opcode()) && |
| 1326 | "A type-generating opcode was expected."); |
| 1327 | switch (type_instr->opcode()) { |
| 1328 | case spv::Op::OpTypeBool: |
| 1329 | case spv::Op::OpTypeInt: |
| 1330 | case spv::Op::OpTypeFloat: |
| 1331 | case spv::Op::OpTypeMatrix: |
| 1332 | case spv::Op::OpTypeVector: |
| 1333 | return true; |
| 1334 | case spv::Op::OpTypeArray: |
| 1335 | return CanCreateConstant(ir_context, |
| 1336 | type_instr->GetSingleWordInOperand(0)); |
| 1337 | case spv::Op::OpTypeStruct: |
| 1338 | if (HasBlockOrBufferBlockDecoration(ir_context, type_id)) { |
| 1339 | return false; |
| 1340 | } |
| 1341 | for (uint32_t index = 0; index < type_instr->NumInOperands(); index++) { |
| 1342 | if (!CanCreateConstant(ir_context, |
| 1343 | type_instr->GetSingleWordInOperand(index))) { |
| 1344 | return false; |
| 1345 | } |
| 1346 | } |
| 1347 | return true; |
| 1348 | default: |
| 1349 | return false; |
| 1350 | } |
| 1351 | } |
| 1352 | |
| 1353 | uint32_t MaybeGetScalarConstant( |
| 1354 | opt::IRContext* ir_context, |
no test coverage detected