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

Method IsApplicable

source/fuzz/transformation_inline_function.cpp:35–104  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

33}
34
35bool TransformationInlineFunction::IsApplicable(
36 opt::IRContext* ir_context,
37 const TransformationContext& transformation_context) const {
38 // The values in the |message_.result_id_map| must be all fresh and all
39 // distinct.
40 const auto result_id_map =
41 fuzzerutil::RepeatedUInt32PairToMap(message_.result_id_map());
42 std::set<uint32_t> ids_used_by_this_transformation;
43 for (auto& pair : result_id_map) {
44 if (!CheckIdIsFreshAndNotUsedByThisTransformation(
45 pair.second, ir_context, &ids_used_by_this_transformation)) {
46 return false;
47 }
48 }
49
50 // |function_call_instruction| must be suitable for inlining.
51 auto* function_call_instruction =
52 ir_context->get_def_use_mgr()->GetDef(message_.function_call_id());
53 if (!IsSuitableForInlining(ir_context, function_call_instruction)) {
54 return false;
55 }
56
57 // |function_call_instruction| must be the penultimate instruction in its
58 // block and its block termination instruction must be an OpBranch. This
59 // avoids the case where the penultimate instruction is an OpLoopMerge, which
60 // would make the back-edge block not branch to the loop header.
61 auto* function_call_instruction_block =
62 ir_context->get_instr_block(function_call_instruction);
63 if (function_call_instruction !=
64 &*--function_call_instruction_block->tail() ||
65 function_call_instruction_block->terminator()->opcode() !=
66 spv::Op::OpBranch) {
67 return false;
68 }
69
70 auto* called_function = fuzzerutil::FindFunction(
71 ir_context, function_call_instruction->GetSingleWordInOperand(0));
72 for (auto& block : *called_function) {
73 // Since the entry block label will not be inlined, only the remaining
74 // labels must have a corresponding value in the map.
75 if (&block != &*called_function->entry() &&
76 !result_id_map.count(block.id()) &&
77 !transformation_context.GetOverflowIdSource()->HasOverflowIds()) {
78 return false;
79 }
80
81 // |result_id_map| must have an entry for every result id in the called
82 // function.
83 for (auto& instruction : block) {
84 // If |instruction| has result id, then it must have a mapped id in
85 // |result_id_map|.
86 if (instruction.HasResultId() &&
87 !result_id_map.count(instruction.result_id()) &&
88 !transformation_context.GetOverflowIdSource()->HasOverflowIds()) {
89 return false;
90 }
91 }
92 }

Callers

nothing calls this directly

Calls 15

RepeatedUInt32PairToMapFunction · 0.85
FindFunctionFunction · 0.85
get_instr_blockMethod · 0.80
GetOverflowIdSourceMethod · 0.80
HasResultIdMethod · 0.80
ForEachParamMethod · 0.80
GetDefMethod · 0.45
get_def_use_mgrMethod · 0.45
tailMethod · 0.45
opcodeMethod · 0.45
terminatorMethod · 0.45

Tested by

no test coverage detected