From 8d4261bc4401fb7c40542df74c81e9506b054244 Mon Sep 17 00:00:00 2001 From: Alastair Donaldson Date: Thu, 2 Apr 2020 15:54:46 +0100 Subject: [PATCH] spirv-fuzz: Introduce TransformationContext (#3272) Some transformations (e.g. TransformationAddFunction) rely on running the validator to decide whether the transformation is applicable. A recent change allowed spirv-fuzz to take validator options, to cater for the case where a module should be considered valid under particular conditions. However, validation during the checking of transformations had no access to these validator options. This change introduced TransformationContext, which currently consists of a fact manager and a set of validator options, but could in the future have other fields corresponding to other objects that it is useful to have access to when applying transformations. Now, instead of checking and applying transformations in the context of a FactManager, a TransformationContext is used. This gives access to the fact manager as before, and also access to the validator options when they are needed. --- source/fuzz/CMakeLists.txt | 2 + source/fuzz/force_render_red.cpp | 13 +- source/fuzz/force_render_red.h | 3 +- source/fuzz/fuzzer.cpp | 153 +++--- source/fuzz/fuzzer_pass.cpp | 5 +- source/fuzz/fuzzer_pass.h | 22 +- source/fuzz/fuzzer_pass_add_access_chains.cpp | 5 +- source/fuzz/fuzzer_pass_add_access_chains.h | 2 +- .../fuzz/fuzzer_pass_add_composite_types.cpp | 5 +- source/fuzz/fuzzer_pass_add_composite_types.h | 2 +- source/fuzz/fuzzer_pass_add_dead_blocks.cpp | 10 +- source/fuzz/fuzzer_pass_add_dead_blocks.h | 3 +- source/fuzz/fuzzer_pass_add_dead_breaks.cpp | 14 +- source/fuzz/fuzzer_pass_add_dead_breaks.h | 3 +- .../fuzz/fuzzer_pass_add_dead_continues.cpp | 10 +- source/fuzz/fuzzer_pass_add_dead_continues.h | 2 +- .../fuzzer_pass_add_equation_instructions.cpp | 5 +- .../fuzzer_pass_add_equation_instructions.h | 2 +- .../fuzz/fuzzer_pass_add_function_calls.cpp | 18 +- source/fuzz/fuzzer_pass_add_function_calls.h | 2 +- .../fuzz/fuzzer_pass_add_global_variables.cpp | 5 +- .../fuzz/fuzzer_pass_add_global_variables.h | 2 +- source/fuzz/fuzzer_pass_add_loads.cpp | 5 +- source/fuzz/fuzzer_pass_add_loads.h | 3 +- .../fuzz/fuzzer_pass_add_local_variables.cpp | 5 +- source/fuzz/fuzzer_pass_add_local_variables.h | 2 +- ...er_pass_add_no_contraction_decorations.cpp | 5 +- ...zzer_pass_add_no_contraction_decorations.h | 2 +- source/fuzz/fuzzer_pass_add_stores.cpp | 15 +- source/fuzz/fuzzer_pass_add_stores.h | 3 +- .../fuzzer_pass_add_useful_constructs.cpp | 44 +- .../fuzz/fuzzer_pass_add_useful_constructs.h | 2 +- .../fuzzer_pass_adjust_function_controls.cpp | 5 +- .../fuzzer_pass_adjust_function_controls.h | 2 +- .../fuzz/fuzzer_pass_adjust_loop_controls.cpp | 5 +- .../fuzz/fuzzer_pass_adjust_loop_controls.h | 2 +- ...zzer_pass_adjust_memory_operands_masks.cpp | 5 +- ...fuzzer_pass_adjust_memory_operands_masks.h | 2 +- .../fuzzer_pass_adjust_selection_controls.cpp | 5 +- .../fuzzer_pass_adjust_selection_controls.h | 2 +- source/fuzz/fuzzer_pass_apply_id_synonyms.cpp | 12 +- source/fuzz/fuzzer_pass_apply_id_synonyms.h | 2 +- .../fuzz/fuzzer_pass_construct_composites.cpp | 10 +- .../fuzz/fuzzer_pass_construct_composites.h | 2 +- source/fuzz/fuzzer_pass_copy_objects.cpp | 5 +- source/fuzz/fuzzer_pass_copy_objects.h | 3 +- source/fuzz/fuzzer_pass_donate_modules.cpp | 9 +- source/fuzz/fuzzer_pass_donate_modules.h | 2 +- source/fuzz/fuzzer_pass_merge_blocks.cpp | 13 +- source/fuzz/fuzzer_pass_merge_blocks.h | 3 +- .../fuzz/fuzzer_pass_obfuscate_constants.cpp | 35 +- source/fuzz/fuzzer_pass_obfuscate_constants.h | 2 +- source/fuzz/fuzzer_pass_outline_functions.cpp | 10 +- source/fuzz/fuzzer_pass_outline_functions.h | 2 +- source/fuzz/fuzzer_pass_permute_blocks.cpp | 10 +- source/fuzz/fuzzer_pass_permute_blocks.h | 3 +- ...uzzer_pass_permute_function_parameters.cpp | 5 +- .../fuzzer_pass_permute_function_parameters.h | 2 +- source/fuzz/fuzzer_pass_split_blocks.cpp | 10 +- source/fuzz/fuzzer_pass_split_blocks.h | 3 +- .../fuzzer_pass_swap_commutable_operands.cpp | 5 +- .../fuzzer_pass_swap_commutable_operands.h | 2 +- ...r_pass_toggle_access_chain_instruction.cpp | 5 +- ...zer_pass_toggle_access_chain_instruction.h | 2 +- source/fuzz/fuzzer_util.cpp | 4 +- source/fuzz/fuzzer_util.h | 5 +- source/fuzz/replayer.cpp | 8 +- source/fuzz/transformation.cpp | 4 +- source/fuzz/transformation.h | 27 +- source/fuzz/transformation_access_chain.cpp | 56 ++- source/fuzz/transformation_access_chain.h | 19 +- .../transformation_add_constant_boolean.cpp | 19 +- .../transformation_add_constant_boolean.h | 10 +- .../transformation_add_constant_composite.cpp | 24 +- .../transformation_add_constant_composite.h | 10 +- .../transformation_add_constant_scalar.cpp | 20 +- .../fuzz/transformation_add_constant_scalar.h | 10 +- source/fuzz/transformation_add_dead_block.cpp | 42 +- source/fuzz/transformation_add_dead_block.h | 10 +- source/fuzz/transformation_add_dead_break.cpp | 51 +- source/fuzz/transformation_add_dead_break.h | 14 +- .../fuzz/transformation_add_dead_continue.cpp | 53 +- .../fuzz/transformation_add_dead_continue.h | 12 +- source/fuzz/transformation_add_function.cpp | 205 ++++---- source/fuzz/transformation_add_function.h | 41 +- .../fuzz/transformation_add_global_undef.cpp | 18 +- source/fuzz/transformation_add_global_undef.h | 10 +- .../transformation_add_global_variable.cpp | 34 +- .../fuzz/transformation_add_global_variable.h | 16 +- .../transformation_add_local_variable.cpp | 25 +- .../fuzz/transformation_add_local_variable.h | 14 +- ...ormation_add_no_contraction_decoration.cpp | 11 +- ...sformation_add_no_contraction_decoration.h | 10 +- source/fuzz/transformation_add_type_array.cpp | 20 +- source/fuzz/transformation_add_type_array.h | 10 +- .../fuzz/transformation_add_type_boolean.cpp | 18 +- source/fuzz/transformation_add_type_boolean.h | 9 +- source/fuzz/transformation_add_type_float.cpp | 18 +- source/fuzz/transformation_add_type_float.h | 10 +- .../fuzz/transformation_add_type_function.cpp | 22 +- .../fuzz/transformation_add_type_function.h | 10 +- source/fuzz/transformation_add_type_int.cpp | 20 +- source/fuzz/transformation_add_type_int.h | 10 +- .../fuzz/transformation_add_type_matrix.cpp | 18 +- source/fuzz/transformation_add_type_matrix.h | 10 +- .../fuzz/transformation_add_type_pointer.cpp | 19 +- source/fuzz/transformation_add_type_pointer.h | 10 +- .../fuzz/transformation_add_type_struct.cpp | 18 +- source/fuzz/transformation_add_type_struct.h | 10 +- .../fuzz/transformation_add_type_vector.cpp | 18 +- source/fuzz/transformation_add_type_vector.h | 10 +- .../transformation_composite_construct.cpp | 88 ++-- .../fuzz/transformation_composite_construct.h | 21 +- .../fuzz/transformation_composite_extract.cpp | 43 +- .../fuzz/transformation_composite_extract.h | 10 +- source/fuzz/transformation_context.cpp | 29 ++ source/fuzz/transformation_context.h | 56 +++ source/fuzz/transformation_copy_object.cpp | 42 +- source/fuzz/transformation_copy_object.h | 16 +- .../transformation_equation_instruction.cpp | 48 +- .../transformation_equation_instruction.h | 12 +- source/fuzz/transformation_function_call.cpp | 50 +- source/fuzz/transformation_function_call.h | 10 +- source/fuzz/transformation_load.cpp | 27 +- source/fuzz/transformation_load.h | 10 +- source/fuzz/transformation_merge_blocks.cpp | 29 +- source/fuzz/transformation_merge_blocks.h | 10 +- .../fuzz/transformation_move_block_down.cpp | 16 +- source/fuzz/transformation_move_block_down.h | 10 +- .../fuzz/transformation_outline_function.cpp | 263 +++++----- source/fuzz/transformation_outline_function.h | 38 +- ...sformation_permute_function_parameters.cpp | 19 +- ...ansformation_permute_function_parameters.h | 10 +- ..._boolean_constant_with_constant_binary.cpp | 34 +- ...ce_boolean_constant_with_constant_binary.h | 15 +- ...ormation_replace_constant_with_uniform.cpp | 73 +-- ...sformation_replace_constant_with_uniform.h | 12 +- ...transformation_replace_id_with_synonym.cpp | 41 +- .../transformation_replace_id_with_synonym.h | 12 +- .../transformation_set_function_control.cpp | 14 +- .../transformation_set_function_control.h | 13 +- .../fuzz/transformation_set_loop_control.cpp | 21 +- source/fuzz/transformation_set_loop_control.h | 16 +- ...ransformation_set_memory_operands_mask.cpp | 15 +- .../transformation_set_memory_operands_mask.h | 13 +- .../transformation_set_selection_control.cpp | 10 +- .../transformation_set_selection_control.h | 10 +- source/fuzz/transformation_split_block.cpp | 33 +- source/fuzz/transformation_split_block.h | 10 +- source/fuzz/transformation_store.cpp | 33 +- source/fuzz/transformation_store.h | 10 +- ...ransformation_swap_commutable_operands.cpp | 8 +- .../transformation_swap_commutable_operands.h | 10 +- ...mation_toggle_access_chain_instruction.cpp | 8 +- ...ormation_toggle_access_chain_instruction.h | 10 +- source/fuzz/transformation_vector_shuffle.cpp | 62 +-- source/fuzz/transformation_vector_shuffle.h | 17 +- .../fuzz/data_synonym_transformation_test.cpp | 385 ++++++++------ ...fuzzer_pass_add_useful_constructs_test.cpp | 12 +- test/fuzz/fuzzer_pass_donate_modules_test.cpp | 45 +- .../fuzz/transformation_access_chain_test.cpp | 128 +++-- ...ansformation_add_constant_boolean_test.cpp | 38 +- ...sformation_add_constant_composite_test.cpp | 16 +- ...ransformation_add_constant_scalar_test.cpp | 58 ++- .../transformation_add_dead_block_test.cpp | 46 +- .../transformation_add_dead_break_test.cpp | 470 +++++++++++------- .../transformation_add_dead_continue_test.cpp | 158 ++++-- .../fuzz/transformation_add_function_test.cpp | 278 +++++++---- .../transformation_add_global_undef_test.cpp | 20 +- ...ransformation_add_global_variable_test.cpp | 63 ++- ...transformation_add_local_variable_test.cpp | 57 ++- ...ion_add_no_contraction_decoration_test.cpp | 14 +- .../transformation_add_type_array_test.cpp | 24 +- .../transformation_add_type_boolean_test.cpp | 16 +- .../transformation_add_type_float_test.cpp | 16 +- .../transformation_add_type_function_test.cpp | 16 +- .../fuzz/transformation_add_type_int_test.cpp | 24 +- .../transformation_add_type_matrix_test.cpp | 16 +- .../transformation_add_type_pointer_test.cpp | 20 +- .../transformation_add_type_struct_test.cpp | 16 +- .../transformation_add_type_vector_test.cpp | 14 +- ...ransformation_composite_construct_test.cpp | 364 +++++++------- .../transformation_composite_extract_test.cpp | 104 ++-- test/fuzz/transformation_copy_object_test.cpp | 168 ++++--- ...ansformation_equation_instruction_test.cpp | 151 +++--- .../transformation_function_call_test.cpp | 115 +++-- test/fuzz/transformation_load_test.cpp | 62 ++- .../fuzz/transformation_merge_blocks_test.cpp | 81 ++- .../transformation_move_block_down_test.cpp | 326 +++++++----- .../transformation_outline_function_test.cpp | 313 +++++++++--- ...ation_permute_function_parameters_test.cpp | 29 +- ...ean_constant_with_constant_binary_test.cpp | 74 +-- ...ion_replace_constant_with_uniform_test.cpp | 302 ++++++----- ...formation_replace_id_with_synonym_test.cpp | 243 +++++---- ...ansformation_set_function_control_test.cpp | 29 +- .../transformation_set_loop_control_test.cpp | 224 +++++---- ...ormation_set_memory_operands_mask_test.cpp | 79 +-- ...nsformation_set_selection_control_test.cpp | 29 +- test/fuzz/transformation_split_block_test.cpp | 95 ++-- test/fuzz/transformation_store_test.cpp | 83 ++-- ...ormation_swap_commutable_operands_test.cpp | 92 ++-- ...n_toggle_access_chain_instruction_test.cpp | 62 ++- .../transformation_vector_shuffle_test.cpp | 287 ++++++----- tools/fuzz/fuzz.cpp | 3 +- 204 files changed, 4879 insertions(+), 3344 deletions(-) create mode 100644 source/fuzz/transformation_context.cpp create mode 100644 source/fuzz/transformation_context.h diff --git a/source/fuzz/CMakeLists.txt b/source/fuzz/CMakeLists.txt index 3a9d604c..cd53aea8 100644 --- a/source/fuzz/CMakeLists.txt +++ b/source/fuzz/CMakeLists.txt @@ -99,6 +99,7 @@ if(SPIRV_BUILD_FUZZER) transformation_add_type_vector.h transformation_composite_construct.h transformation_composite_extract.h + transformation_context.h transformation_copy_object.h transformation_equation_instruction.h transformation_function_call.h @@ -190,6 +191,7 @@ if(SPIRV_BUILD_FUZZER) transformation_add_type_vector.cpp transformation_composite_construct.cpp transformation_composite_extract.cpp + transformation_context.cpp transformation_copy_object.cpp transformation_equation_instruction.cpp transformation_function_call.cpp diff --git a/source/fuzz/force_render_red.cpp b/source/fuzz/force_render_red.cpp index 46e23e80..5bf28798 100644 --- a/source/fuzz/force_render_red.cpp +++ b/source/fuzz/force_render_red.cpp @@ -17,6 +17,7 @@ #include "source/fuzz/fact_manager.h" #include "source/fuzz/instruction_descriptor.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" +#include "source/fuzz/transformation_context.h" #include "source/fuzz/transformation_replace_constant_with_uniform.h" #include "source/fuzz/uniform_buffer_element_descriptor.h" #include "source/opt/build_module.h" @@ -159,7 +160,8 @@ MakeConstantUniformReplacement(opt::IRContext* ir_context, } // namespace bool ForceRenderRed( - const spv_target_env& target_env, const std::vector& binary_in, + const spv_target_env& target_env, spv_validator_options validator_options, + const std::vector& binary_in, const spvtools::fuzz::protobufs::FactSequence& initial_facts, std::vector* binary_out) { auto message_consumer = spvtools::utils::CLIMessageConsumer; @@ -171,7 +173,7 @@ bool ForceRenderRed( } // Initial binary should be valid. - if (!tools.Validate(&binary_in[0], binary_in.size())) { + if (!tools.Validate(&binary_in[0], binary_in.size(), validator_options)) { message_consumer(SPV_MSG_ERROR, nullptr, {}, "Initial binary is invalid; stopping."); return false; @@ -187,6 +189,8 @@ bool ForceRenderRed( for (auto& fact : initial_facts.fact()) { fact_manager.AddFact(fact, ir_context.get()); } + TransformationContext transformation_context(&fact_manager, + validator_options); auto entry_point_function = FindFragmentShaderEntryPoint(ir_context.get(), message_consumer); @@ -355,8 +359,9 @@ bool ForceRenderRed( for (auto& replacement : {first_greater_then_operand_replacement.get(), second_greater_then_operand_replacement.get()}) { if (replacement) { - assert(replacement->IsApplicable(ir_context.get(), fact_manager)); - replacement->Apply(ir_context.get(), &fact_manager); + assert(replacement->IsApplicable(ir_context.get(), + transformation_context)); + replacement->Apply(ir_context.get(), &transformation_context); } } } diff --git a/source/fuzz/force_render_red.h b/source/fuzz/force_render_red.h index 2484d278..b51c72b4 100644 --- a/source/fuzz/force_render_red.h +++ b/source/fuzz/force_render_red.h @@ -38,7 +38,8 @@ namespace fuzz { // instead become: 'u > v', where 'u' and 'v' are pieces of uniform data for // which it is known that 'u < v' holds. bool ForceRenderRed( - const spv_target_env& target_env, const std::vector& binary_in, + const spv_target_env& target_env, spv_validator_options validator_options, + const std::vector& binary_in, const spvtools::fuzz::protobufs::FactSequence& initial_facts, std::vector* binary_out); diff --git a/source/fuzz/fuzzer.cpp b/source/fuzz/fuzzer.cpp index 3a4fa0ec..6524c217 100644 --- a/source/fuzz/fuzzer.cpp +++ b/source/fuzz/fuzzer.cpp @@ -51,6 +51,7 @@ #include "source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/pseudo_random_generator.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/build_module.h" #include "source/spirv_fuzzer_options.h" #include "source/util/make_unique.h" @@ -66,19 +67,19 @@ const uint32_t kTransformationLimit = 500; const uint32_t kChanceOfApplyingAnotherPass = 85; // A convenience method to add a fuzzer pass to |passes| with probability 0.5. -// All fuzzer passes take |ir_context|, |fact_manager|, |fuzzer_context| and -// |transformation_sequence_out| as parameters. Extra arguments can be provided -// via |extra_args|. +// All fuzzer passes take |ir_context|, |transformation_context|, +// |fuzzer_context| and |transformation_sequence_out| as parameters. Extra +// arguments can be provided via |extra_args|. template void MaybeAddPass( std::vector>* passes, - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformation_sequence_out, Args&&... extra_args) { if (fuzzer_context->ChooseEven()) { - passes->push_back(MakeUnique(ir_context, fact_manager, fuzzer_context, - transformation_sequence_out, + passes->push_back(MakeUnique(ir_context, transformation_context, + fuzzer_context, transformation_sequence_out, std::forward(extra_args)...)); } } @@ -182,11 +183,13 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run( FactManager fact_manager; fact_manager.AddFacts(impl_->consumer, initial_facts, ir_context.get()); + TransformationContext transformation_context(&fact_manager, + impl_->validator_options); // Add some essential ingredients to the module if they are not already // present, such as boolean constants. FuzzerPassAddUsefulConstructs add_useful_constructs( - ir_context.get(), &fact_manager, &fuzzer_context, + ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); if (!impl_->ApplyPassAndCheckValidity(&add_useful_constructs, *ir_context, tools)) { @@ -196,69 +199,69 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run( // Apply some semantics-preserving passes. std::vector> passes; while (passes.empty()) { - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); MaybeAddPass( - &passes, ir_context.get(), &fact_manager, &fuzzer_context, + &passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), &fact_manager, - &fuzzer_context, + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass(&passes, ir_context.get(), + &transformation_context, &fuzzer_context, transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), &fact_manager, - &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass( - &passes, ir_context.get(), &fact_manager, &fuzzer_context, - transformation_sequence_out, donor_suppliers); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); - MaybeAddPass( - &passes, ir_context.get(), &fact_manager, &fuzzer_context, + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass(&passes, ir_context.get(), + &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out, donor_suppliers); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); - MaybeAddPass(&passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); } bool is_first = true; @@ -279,25 +282,25 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run( // as they do not unlock other passes. std::vector> final_passes; MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, + transformation_sequence_out); + MaybeAddPass( + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); - MaybeAddPass(&final_passes, ir_context.get(), - &fact_manager, &fuzzer_context, - transformation_sequence_out); MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); MaybeAddPass( - &final_passes, ir_context.get(), &fact_manager, &fuzzer_context, + &final_passes, ir_context.get(), &transformation_context, &fuzzer_context, transformation_sequence_out); for (auto& pass : final_passes) { if (!impl_->ApplyPassAndCheckValidity(pass.get(), *ir_context, tools)) { diff --git a/source/fuzz/fuzzer_pass.cpp b/source/fuzz/fuzzer_pass.cpp index a76f10d3..4ab29466 100644 --- a/source/fuzz/fuzzer_pass.cpp +++ b/source/fuzz/fuzzer_pass.cpp @@ -31,11 +31,12 @@ namespace spvtools { namespace fuzz { -FuzzerPass::FuzzerPass(opt::IRContext* ir_context, FactManager* fact_manager, +FuzzerPass::FuzzerPass(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) : ir_context_(ir_context), - fact_manager_(fact_manager), + transformation_context_(transformation_context), fuzzer_context_(fuzzer_context), transformations_(transformations) {} diff --git a/source/fuzz/fuzzer_pass.h b/source/fuzz/fuzzer_pass.h index 46ee4080..436fd778 100644 --- a/source/fuzz/fuzzer_pass.h +++ b/source/fuzz/fuzzer_pass.h @@ -18,9 +18,9 @@ #include #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/fuzzer_context.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -29,22 +29,25 @@ namespace fuzz { // Interface for applying a pass of transformations to a module. class FuzzerPass { public: - FuzzerPass(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPass(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); virtual ~FuzzerPass(); // Applies the pass to the module |ir_context_|, assuming and updating - // facts from |fact_manager_|, and using |fuzzer_context_| to guide the - // process. Appends to |transformations_| all transformations that were - // applied during the pass. + // information from |transformation_context_|, and using |fuzzer_context_| to + // guide the process. Appends to |transformations_| all transformations that + // were applied during the pass. virtual void Apply() = 0; protected: opt::IRContext* GetIRContext() const { return ir_context_; } - FactManager* GetFactManager() const { return fact_manager_; } + TransformationContext* GetTransformationContext() const { + return transformation_context_; + } FuzzerContext* GetFuzzerContext() const { return fuzzer_context_; } @@ -93,9 +96,10 @@ class FuzzerPass { // by construction, and adding it to the sequence of applied transformations. template void ApplyTransformation(const TransformationType& transformation) { - assert(transformation.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(transformation.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Transformation should be applicable by construction."); - transformation.Apply(GetIRContext(), GetFactManager()); + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } @@ -230,7 +234,7 @@ class FuzzerPass { const std::vector& constant_ids); opt::IRContext* ir_context_; - FactManager* fact_manager_; + TransformationContext* transformation_context_; FuzzerContext* fuzzer_context_; protobufs::TransformationSequence* transformations_; }; diff --git a/source/fuzz/fuzzer_pass_add_access_chains.cpp b/source/fuzz/fuzzer_pass_add_access_chains.cpp index cfc2812b..b9c1eed3 100644 --- a/source/fuzz/fuzzer_pass_add_access_chains.cpp +++ b/source/fuzz/fuzzer_pass_add_access_chains.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddAccessChains::FuzzerPassAddAccessChains( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddAccessChains::~FuzzerPassAddAccessChains() = default; diff --git a/source/fuzz/fuzzer_pass_add_access_chains.h b/source/fuzz/fuzzer_pass_add_access_chains.h index 7e8ed612..8649296f 100644 --- a/source/fuzz/fuzzer_pass_add_access_chains.h +++ b/source/fuzz/fuzzer_pass_add_access_chains.h @@ -26,7 +26,7 @@ namespace fuzz { class FuzzerPassAddAccessChains : public FuzzerPass { public: FuzzerPassAddAccessChains(opt::IRContext* ir_context, - FactManager* fact_manager, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_composite_types.cpp b/source/fuzz/fuzzer_pass_add_composite_types.cpp index 32c720e1..9b0dda88 100644 --- a/source/fuzz/fuzzer_pass_add_composite_types.cpp +++ b/source/fuzz/fuzzer_pass_add_composite_types.cpp @@ -22,10 +22,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddCompositeTypes::FuzzerPassAddCompositeTypes( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddCompositeTypes::~FuzzerPassAddCompositeTypes() = default; diff --git a/source/fuzz/fuzzer_pass_add_composite_types.h b/source/fuzz/fuzzer_pass_add_composite_types.h index 29d4bb89..87bc0ff3 100644 --- a/source/fuzz/fuzzer_pass_add_composite_types.h +++ b/source/fuzz/fuzzer_pass_add_composite_types.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAddCompositeTypes : public FuzzerPass { public: FuzzerPassAddCompositeTypes( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_dead_blocks.cpp b/source/fuzz/fuzzer_pass_add_dead_blocks.cpp index c9bc9c48..4e9db1f3 100644 --- a/source/fuzz/fuzzer_pass_add_dead_blocks.cpp +++ b/source/fuzz/fuzzer_pass_add_dead_blocks.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddDeadBlocks::FuzzerPassAddDeadBlocks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddDeadBlocks::~FuzzerPassAddDeadBlocks() = default; @@ -53,8 +54,9 @@ void FuzzerPassAddDeadBlocks::Apply() { } // Apply all those transformations that are in fact applicable. for (auto& transformation : candidate_transformations) { - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { - transformation.Apply(GetIRContext(), GetFactManager()); + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } } diff --git a/source/fuzz/fuzzer_pass_add_dead_blocks.h b/source/fuzz/fuzzer_pass_add_dead_blocks.h index 01e3843d..d78f0883 100644 --- a/source/fuzz/fuzzer_pass_add_dead_blocks.h +++ b/source/fuzz/fuzzer_pass_add_dead_blocks.h @@ -24,7 +24,8 @@ namespace fuzz { // passes can then manipulate such blocks. class FuzzerPassAddDeadBlocks : public FuzzerPass { public: - FuzzerPassAddDeadBlocks(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassAddDeadBlocks(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_dead_breaks.cpp b/source/fuzz/fuzzer_pass_add_dead_breaks.cpp index aefc2fcd..6b171dcd 100644 --- a/source/fuzz/fuzzer_pass_add_dead_breaks.cpp +++ b/source/fuzz/fuzzer_pass_add_dead_breaks.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddDeadBreaks::FuzzerPassAddDeadBreaks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddDeadBreaks::~FuzzerPassAddDeadBreaks() = default; @@ -79,8 +80,8 @@ void FuzzerPassAddDeadBreaks::Apply() { auto candidate_transformation = TransformationAddDeadBreak( block.id(), merge_block->id(), GetFuzzerContext()->ChooseEven(), std::move(phi_ids)); - if (candidate_transformation.IsApplicable(GetIRContext(), - *GetFactManager())) { + if (candidate_transformation.IsApplicable( + GetIRContext(), *GetTransformationContext())) { // Only consider a transformation as a candidate if it is applicable. candidate_transformations.push_back( std::move(candidate_transformation)); @@ -109,10 +110,11 @@ void FuzzerPassAddDeadBreaks::Apply() { candidate_transformations.erase(candidate_transformations.begin() + index); // Probabilistically decide whether to try to apply it vs. ignore it, in the // case that it is applicable. - if (transformation.IsApplicable(GetIRContext(), *GetFactManager()) && + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext()) && GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfAddingDeadBreak())) { - transformation.Apply(GetIRContext(), GetFactManager()); + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } } diff --git a/source/fuzz/fuzzer_pass_add_dead_breaks.h b/source/fuzz/fuzzer_pass_add_dead_breaks.h index 12a5095f..c379eed5 100644 --- a/source/fuzz/fuzzer_pass_add_dead_breaks.h +++ b/source/fuzz/fuzzer_pass_add_dead_breaks.h @@ -23,7 +23,8 @@ namespace fuzz { // A fuzzer pass for adding dead break edges to the module. class FuzzerPassAddDeadBreaks : public FuzzerPass { public: - FuzzerPassAddDeadBreaks(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassAddDeadBreaks(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_dead_continues.cpp b/source/fuzz/fuzzer_pass_add_dead_continues.cpp index 852df3de..b8f07fbe 100644 --- a/source/fuzz/fuzzer_pass_add_dead_continues.cpp +++ b/source/fuzz/fuzzer_pass_add_dead_continues.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddDeadContinues::FuzzerPassAddDeadContinues( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddDeadContinues::~FuzzerPassAddDeadContinues() = default; @@ -75,10 +76,11 @@ void FuzzerPassAddDeadContinues::Apply() { // Probabilistically decide whether to apply the transformation in the // case that it is applicable. if (candidate_transformation.IsApplicable(GetIRContext(), - *GetFactManager()) && + *GetTransformationContext()) && GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfAddingDeadContinue())) { - candidate_transformation.Apply(GetIRContext(), GetFactManager()); + candidate_transformation.Apply(GetIRContext(), + GetTransformationContext()); *GetTransformations()->add_transformation() = candidate_transformation.ToMessage(); } diff --git a/source/fuzz/fuzzer_pass_add_dead_continues.h b/source/fuzz/fuzzer_pass_add_dead_continues.h index d067f1c4..b2acb935 100644 --- a/source/fuzz/fuzzer_pass_add_dead_continues.h +++ b/source/fuzz/fuzzer_pass_add_dead_continues.h @@ -24,7 +24,7 @@ namespace fuzz { class FuzzerPassAddDeadContinues : public FuzzerPass { public: FuzzerPassAddDeadContinues( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp index 7f34344c..49c4a8aa 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp @@ -23,10 +23,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddEquationInstructions::FuzzerPassAddEquationInstructions( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddEquationInstructions::~FuzzerPassAddEquationInstructions() = default; diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.h b/source/fuzz/fuzzer_pass_add_equation_instructions.h index 84229c05..6e649773 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.h +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.h @@ -27,7 +27,7 @@ namespace fuzz { class FuzzerPassAddEquationInstructions : public FuzzerPass { public: FuzzerPassAddEquationInstructions( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_function_calls.cpp b/source/fuzz/fuzzer_pass_add_function_calls.cpp index 545aa169..f666eb25 100644 --- a/source/fuzz/fuzzer_pass_add_function_calls.cpp +++ b/source/fuzz/fuzzer_pass_add_function_calls.cpp @@ -24,10 +24,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddFunctionCalls::FuzzerPassAddFunctionCalls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddFunctionCalls::~FuzzerPassAddFunctionCalls() = default; @@ -74,8 +75,9 @@ void FuzzerPassAddFunctionCalls::Apply() { while (!candidate_functions.empty()) { opt::Function* candidate_function = GetFuzzerContext()->RemoveAtRandomIndex(&candidate_functions); - if (!GetFactManager()->BlockIsDead(block->id()) && - !GetFactManager()->FunctionIsLivesafe( + if (!GetTransformationContext()->GetFactManager()->BlockIsDead( + block->id()) && + !GetTransformationContext()->GetFactManager()->FunctionIsLivesafe( candidate_function->result_id())) { // Unless in a dead block, only livesafe functions can be invoked continue; @@ -132,9 +134,11 @@ FuzzerPassAddFunctionCalls::GetAvailableInstructionsSuitableForActualParameters( default: return false; } - if (!GetFactManager()->BlockIsDead(block->id()) && - !GetFactManager()->PointeeValueIsIrrelevant( - inst->result_id())) { + if (!GetTransformationContext()->GetFactManager()->BlockIsDead( + block->id()) && + !GetTransformationContext() + ->GetFactManager() + ->PointeeValueIsIrrelevant(inst->result_id())) { // We can only pass a pointer as an actual parameter // if the pointee value for the pointer is irrelevant, // or if the block from which we would make the diff --git a/source/fuzz/fuzzer_pass_add_function_calls.h b/source/fuzz/fuzzer_pass_add_function_calls.h index 5d184fd1..8f75e8cf 100644 --- a/source/fuzz/fuzzer_pass_add_function_calls.h +++ b/source/fuzz/fuzzer_pass_add_function_calls.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAddFunctionCalls : public FuzzerPass { public: FuzzerPassAddFunctionCalls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_global_variables.cpp b/source/fuzz/fuzzer_pass_add_global_variables.cpp index 1371f46c..ce2b8eb1 100644 --- a/source/fuzz/fuzzer_pass_add_global_variables.cpp +++ b/source/fuzz/fuzzer_pass_add_global_variables.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddGlobalVariables::FuzzerPassAddGlobalVariables( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddGlobalVariables::~FuzzerPassAddGlobalVariables() = default; diff --git a/source/fuzz/fuzzer_pass_add_global_variables.h b/source/fuzz/fuzzer_pass_add_global_variables.h index c71d1477..a907d360 100644 --- a/source/fuzz/fuzzer_pass_add_global_variables.h +++ b/source/fuzz/fuzzer_pass_add_global_variables.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAddGlobalVariables : public FuzzerPass { public: FuzzerPassAddGlobalVariables( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_loads.cpp b/source/fuzz/fuzzer_pass_add_loads.cpp index 851787fe..16d88e3b 100644 --- a/source/fuzz/fuzzer_pass_add_loads.cpp +++ b/source/fuzz/fuzzer_pass_add_loads.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddLoads::FuzzerPassAddLoads( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddLoads::~FuzzerPassAddLoads() = default; diff --git a/source/fuzz/fuzzer_pass_add_loads.h b/source/fuzz/fuzzer_pass_add_loads.h index 125bc5db..c4d5b27e 100644 --- a/source/fuzz/fuzzer_pass_add_loads.h +++ b/source/fuzz/fuzzer_pass_add_loads.h @@ -23,7 +23,8 @@ namespace fuzz { // Fuzzer pass that adds stores, at random, from pointers in the module. class FuzzerPassAddLoads : public FuzzerPass { public: - FuzzerPassAddLoads(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassAddLoads(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_local_variables.cpp b/source/fuzz/fuzzer_pass_add_local_variables.cpp index 8d6d80d6..ace9be26 100644 --- a/source/fuzz/fuzzer_pass_add_local_variables.cpp +++ b/source/fuzz/fuzzer_pass_add_local_variables.cpp @@ -22,10 +22,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddLocalVariables::FuzzerPassAddLocalVariables( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddLocalVariables::~FuzzerPassAddLocalVariables() = default; diff --git a/source/fuzz/fuzzer_pass_add_local_variables.h b/source/fuzz/fuzzer_pass_add_local_variables.h index eed36657..08d26d8c 100644 --- a/source/fuzz/fuzzer_pass_add_local_variables.h +++ b/source/fuzz/fuzzer_pass_add_local_variables.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAddLocalVariables : public FuzzerPass { public: FuzzerPassAddLocalVariables( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_no_contraction_decorations.cpp b/source/fuzz/fuzzer_pass_add_no_contraction_decorations.cpp index 82fb5399..09627d09 100644 --- a/source/fuzz/fuzzer_pass_add_no_contraction_decorations.cpp +++ b/source/fuzz/fuzzer_pass_add_no_contraction_decorations.cpp @@ -20,10 +20,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddNoContractionDecorations::FuzzerPassAddNoContractionDecorations( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddNoContractionDecorations:: ~FuzzerPassAddNoContractionDecorations() = default; diff --git a/source/fuzz/fuzzer_pass_add_no_contraction_decorations.h b/source/fuzz/fuzzer_pass_add_no_contraction_decorations.h index abe5bd7a..f32e5bc6 100644 --- a/source/fuzz/fuzzer_pass_add_no_contraction_decorations.h +++ b/source/fuzz/fuzzer_pass_add_no_contraction_decorations.h @@ -24,7 +24,7 @@ namespace fuzz { class FuzzerPassAddNoContractionDecorations : public FuzzerPass { public: FuzzerPassAddNoContractionDecorations( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_stores.cpp b/source/fuzz/fuzzer_pass_add_stores.cpp index 794ddc3d..e8871be8 100644 --- a/source/fuzz/fuzzer_pass_add_stores.cpp +++ b/source/fuzz/fuzzer_pass_add_stores.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddStores::FuzzerPassAddStores( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddStores::~FuzzerPassAddStores() = default; @@ -82,9 +83,13 @@ void FuzzerPassAddStores::Apply() { default: break; } - return GetFactManager()->BlockIsDead(block->id()) || - GetFactManager()->PointeeValueIsIrrelevant( - instruction->result_id()); + return GetTransformationContext() + ->GetFactManager() + ->BlockIsDead(block->id()) || + GetTransformationContext() + ->GetFactManager() + ->PointeeValueIsIrrelevant( + instruction->result_id()); }); // At this point, |relevant_pointers| contains all the pointers we might diff --git a/source/fuzz/fuzzer_pass_add_stores.h b/source/fuzz/fuzzer_pass_add_stores.h index 9daa9e0f..55ec67f2 100644 --- a/source/fuzz/fuzzer_pass_add_stores.h +++ b/source/fuzz/fuzzer_pass_add_stores.h @@ -25,7 +25,8 @@ namespace fuzz { // are known not to affect the module's overall behaviour. class FuzzerPassAddStores : public FuzzerPass { public: - FuzzerPassAddStores(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassAddStores(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_add_useful_constructs.cpp b/source/fuzz/fuzzer_pass_add_useful_constructs.cpp index 8552dfd2..a267612b 100644 --- a/source/fuzz/fuzzer_pass_add_useful_constructs.cpp +++ b/source/fuzz/fuzzer_pass_add_useful_constructs.cpp @@ -25,10 +25,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAddUsefulConstructs::FuzzerPassAddUsefulConstructs( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAddUsefulConstructs::~FuzzerPassAddUsefulConstructs() = default; @@ -49,9 +50,10 @@ void FuzzerPassAddUsefulConstructs::MaybeAddIntConstant( TransformationAddConstantScalar add_constant_int = TransformationAddConstantScalar(GetFuzzerContext()->GetFreshId(), int_type_id, data); - assert(add_constant_int.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_constant_int.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_constant_int.Apply(GetIRContext(), GetFactManager()); + add_constant_int.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_constant_int.ToMessage(); } } @@ -75,9 +77,10 @@ void FuzzerPassAddUsefulConstructs::MaybeAddFloatConstant( TransformationAddConstantScalar add_constant_float = TransformationAddConstantScalar(GetFuzzerContext()->GetFreshId(), float_type_id, data); - assert(add_constant_float.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_constant_float.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_constant_float.Apply(GetIRContext(), GetFactManager()); + add_constant_float.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_constant_float.ToMessage(); } @@ -90,9 +93,10 @@ void FuzzerPassAddUsefulConstructs::Apply() { if (!GetIRContext()->get_type_mgr()->GetId(&temp_bool_type)) { auto add_type_boolean = TransformationAddTypeBoolean(GetFuzzerContext()->GetFreshId()); - assert(add_type_boolean.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_type_boolean.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_type_boolean.Apply(GetIRContext(), GetFactManager()); + add_type_boolean.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_type_boolean.ToMessage(); } @@ -105,9 +109,10 @@ void FuzzerPassAddUsefulConstructs::Apply() { if (!GetIRContext()->get_type_mgr()->GetId(&temp_int_type)) { TransformationAddTypeInt add_type_int = TransformationAddTypeInt( GetFuzzerContext()->GetFreshId(), 32, is_signed); - assert(add_type_int.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_type_int.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_type_int.Apply(GetIRContext(), GetFactManager()); + add_type_int.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_type_int.ToMessage(); } } @@ -119,9 +124,10 @@ void FuzzerPassAddUsefulConstructs::Apply() { if (!GetIRContext()->get_type_mgr()->GetId(&temp_float_type)) { TransformationAddTypeFloat add_type_float = TransformationAddTypeFloat(GetFuzzerContext()->GetFreshId(), 32); - assert(add_type_float.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_type_float.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_type_float.Apply(GetIRContext(), GetFactManager()); + add_type_float.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_type_float.ToMessage(); } } @@ -139,9 +145,9 @@ void FuzzerPassAddUsefulConstructs::Apply() { TransformationAddConstantBoolean add_constant_boolean( GetFuzzerContext()->GetFreshId(), boolean_value); assert(add_constant_boolean.IsApplicable(GetIRContext(), - *GetFactManager()) && + *GetTransformationContext()) && "Should be applicable by construction."); - add_constant_boolean.Apply(GetIRContext(), GetFactManager()); + add_constant_boolean.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_constant_boolean.ToMessage(); } @@ -168,8 +174,9 @@ void FuzzerPassAddUsefulConstructs::Apply() { // of the element // - a signed integer constant for each index required to access the element // - a constant for the constant value itself - for (auto& fact_and_type_id : - GetFactManager()->GetConstantUniformFactsAndTypes()) { + for (auto& fact_and_type_id : GetTransformationContext() + ->GetFactManager() + ->GetConstantUniformFactsAndTypes()) { uint32_t element_type_id = fact_and_type_id.second; assert(element_type_id); auto element_type = @@ -183,9 +190,10 @@ void FuzzerPassAddUsefulConstructs::Apply() { auto add_pointer = TransformationAddTypePointer(GetFuzzerContext()->GetFreshId(), SpvStorageClassUniform, element_type_id); - assert(add_pointer.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(add_pointer.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "Should be applicable by construction."); - add_pointer.Apply(GetIRContext(), GetFactManager()); + add_pointer.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = add_pointer.ToMessage(); } std::vector words; diff --git a/source/fuzz/fuzzer_pass_add_useful_constructs.h b/source/fuzz/fuzzer_pass_add_useful_constructs.h index 7dc00f13..17e87a82 100644 --- a/source/fuzz/fuzzer_pass_add_useful_constructs.h +++ b/source/fuzz/fuzzer_pass_add_useful_constructs.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAddUsefulConstructs : public FuzzerPass { public: FuzzerPassAddUsefulConstructs( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_adjust_function_controls.cpp b/source/fuzz/fuzzer_pass_adjust_function_controls.cpp index fe229bca..aa62d2f8 100644 --- a/source/fuzz/fuzzer_pass_adjust_function_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_function_controls.cpp @@ -20,10 +20,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAdjustFunctionControls::FuzzerPassAdjustFunctionControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAdjustFunctionControls::~FuzzerPassAdjustFunctionControls() = default; diff --git a/source/fuzz/fuzzer_pass_adjust_function_controls.h b/source/fuzz/fuzzer_pass_adjust_function_controls.h index 02d36004..e20541b1 100644 --- a/source/fuzz/fuzzer_pass_adjust_function_controls.h +++ b/source/fuzz/fuzzer_pass_adjust_function_controls.h @@ -24,7 +24,7 @@ namespace fuzz { class FuzzerPassAdjustFunctionControls : public FuzzerPass { public: FuzzerPassAdjustFunctionControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp b/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp index c9843d0a..f7addffe 100644 --- a/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp @@ -20,10 +20,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAdjustLoopControls::FuzzerPassAdjustLoopControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAdjustLoopControls::~FuzzerPassAdjustLoopControls() = default; diff --git a/source/fuzz/fuzzer_pass_adjust_loop_controls.h b/source/fuzz/fuzzer_pass_adjust_loop_controls.h index e9456067..ee5cd483 100644 --- a/source/fuzz/fuzzer_pass_adjust_loop_controls.h +++ b/source/fuzz/fuzzer_pass_adjust_loop_controls.h @@ -24,7 +24,7 @@ namespace fuzz { class FuzzerPassAdjustLoopControls : public FuzzerPass { public: FuzzerPassAdjustLoopControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp index 2d3d6765..32f5ea5f 100644 --- a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp +++ b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAdjustMemoryOperandsMasks::FuzzerPassAdjustMemoryOperandsMasks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAdjustMemoryOperandsMasks::~FuzzerPassAdjustMemoryOperandsMasks() = default; diff --git a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h index c3d71185..699dcb5a 100644 --- a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h +++ b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassAdjustMemoryOperandsMasks : public FuzzerPass { public: FuzzerPassAdjustMemoryOperandsMasks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp b/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp index 397dfedb..83b1854e 100644 --- a/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp @@ -20,10 +20,11 @@ namespace spvtools { namespace fuzz { FuzzerPassAdjustSelectionControls::FuzzerPassAdjustSelectionControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassAdjustSelectionControls::~FuzzerPassAdjustSelectionControls() = default; diff --git a/source/fuzz/fuzzer_pass_adjust_selection_controls.h b/source/fuzz/fuzzer_pass_adjust_selection_controls.h index b5b255ce..820b30d4 100644 --- a/source/fuzz/fuzzer_pass_adjust_selection_controls.h +++ b/source/fuzz/fuzzer_pass_adjust_selection_controls.h @@ -24,7 +24,7 @@ namespace fuzz { class FuzzerPassAdjustSelectionControls : public FuzzerPass { public: FuzzerPassAdjustSelectionControls( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp b/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp index 5711f358..30884a60 100644 --- a/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp +++ b/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp @@ -25,16 +25,19 @@ namespace spvtools { namespace fuzz { FuzzerPassApplyIdSynonyms::FuzzerPassApplyIdSynonyms( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassApplyIdSynonyms::~FuzzerPassApplyIdSynonyms() = default; void FuzzerPassApplyIdSynonyms::Apply() { for (auto id_with_known_synonyms : - GetFactManager()->GetIdsForWhichSynonymsAreKnown(GetIRContext())) { + GetTransformationContext() + ->GetFactManager() + ->GetIdsForWhichSynonymsAreKnown(GetIRContext())) { // Gather up all uses of |id_with_known_synonym|, and then subsequently // iterate over these uses. We use this separation because, when // considering a given use, we might apply a transformation that will @@ -70,7 +73,8 @@ void FuzzerPassApplyIdSynonyms::Apply() { } std::vector synonyms_to_try; - for (auto& data_descriptor : GetFactManager()->GetSynonymsForId( + for (auto& data_descriptor : + GetTransformationContext()->GetFactManager()->GetSynonymsForId( id_with_known_synonyms, GetIRContext())) { protobufs::DataDescriptor descriptor_for_this_id = MakeDataDescriptor(id_with_known_synonyms, {}); diff --git a/source/fuzz/fuzzer_pass_apply_id_synonyms.h b/source/fuzz/fuzzer_pass_apply_id_synonyms.h index 1a0748eb..1a9213db 100644 --- a/source/fuzz/fuzzer_pass_apply_id_synonyms.h +++ b/source/fuzz/fuzzer_pass_apply_id_synonyms.h @@ -27,7 +27,7 @@ namespace fuzz { class FuzzerPassApplyIdSynonyms : public FuzzerPass { public: FuzzerPassApplyIdSynonyms(opt::IRContext* ir_context, - FactManager* fact_manager, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_construct_composites.cpp b/source/fuzz/fuzzer_pass_construct_composites.cpp index 330b9cfc..b1b08230 100644 --- a/source/fuzz/fuzzer_pass_construct_composites.cpp +++ b/source/fuzz/fuzzer_pass_construct_composites.cpp @@ -25,10 +25,11 @@ namespace spvtools { namespace fuzz { FuzzerPassConstructComposites::FuzzerPassConstructComposites( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassConstructComposites::~FuzzerPassConstructComposites() = default; @@ -143,9 +144,10 @@ void FuzzerPassConstructComposites::Apply() { TransformationCompositeConstruct transformation( chosen_composite_type, *constructor_arguments, instruction_descriptor, GetFuzzerContext()->GetFreshId()); - assert(transformation.IsApplicable(GetIRContext(), *GetFactManager()) && + assert(transformation.IsApplicable(GetIRContext(), + *GetTransformationContext()) && "This transformation should be applicable by construction."); - transformation.Apply(GetIRContext(), GetFactManager()); + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); }); diff --git a/source/fuzz/fuzzer_pass_construct_composites.h b/source/fuzz/fuzzer_pass_construct_composites.h index 99ef31ff..d293514d 100644 --- a/source/fuzz/fuzzer_pass_construct_composites.h +++ b/source/fuzz/fuzzer_pass_construct_composites.h @@ -27,7 +27,7 @@ namespace fuzz { class FuzzerPassConstructComposites : public FuzzerPass { public: FuzzerPassConstructComposites( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_copy_objects.cpp b/source/fuzz/fuzzer_pass_copy_objects.cpp index 588cfb60..f055b598 100644 --- a/source/fuzz/fuzzer_pass_copy_objects.cpp +++ b/source/fuzz/fuzzer_pass_copy_objects.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace fuzz { FuzzerPassCopyObjects::FuzzerPassCopyObjects( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassCopyObjects::~FuzzerPassCopyObjects() = default; diff --git a/source/fuzz/fuzzer_pass_copy_objects.h b/source/fuzz/fuzzer_pass_copy_objects.h index 5419459e..8de382e7 100644 --- a/source/fuzz/fuzzer_pass_copy_objects.h +++ b/source/fuzz/fuzzer_pass_copy_objects.h @@ -23,7 +23,8 @@ namespace fuzz { // A fuzzer pass for adding adding copies of objects to the module. class FuzzerPassCopyObjects : public FuzzerPass { public: - FuzzerPassCopyObjects(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassCopyObjects(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_donate_modules.cpp b/source/fuzz/fuzzer_pass_donate_modules.cpp index 27d8a6e5..63ce7a64 100644 --- a/source/fuzz/fuzzer_pass_donate_modules.cpp +++ b/source/fuzz/fuzzer_pass_donate_modules.cpp @@ -40,11 +40,12 @@ namespace spvtools { namespace fuzz { FuzzerPassDonateModules::FuzzerPassDonateModules( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations, const std::vector& donor_suppliers) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations), + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations), donor_suppliers_(donor_suppliers) {} FuzzerPassDonateModules::~FuzzerPassDonateModules() = default; @@ -62,7 +63,9 @@ void FuzzerPassDonateModules::Apply() { std::unique_ptr donor_ir_context = donor_suppliers_.at( GetFuzzerContext()->RandomIndex(donor_suppliers_))(); assert(donor_ir_context != nullptr && "Supplying of donor failed"); - assert(fuzzerutil::IsValid(donor_ir_context.get()) && + assert(fuzzerutil::IsValid( + donor_ir_context.get(), + GetTransformationContext()->GetValidatorOptions()) && "The donor module must be valid"); // Donate the supplied module. // diff --git a/source/fuzz/fuzzer_pass_donate_modules.h b/source/fuzz/fuzzer_pass_donate_modules.h index ef529db7..9087daf2 100644 --- a/source/fuzz/fuzzer_pass_donate_modules.h +++ b/source/fuzz/fuzzer_pass_donate_modules.h @@ -28,7 +28,7 @@ namespace fuzz { class FuzzerPassDonateModules : public FuzzerPass { public: FuzzerPassDonateModules( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations, const std::vector& donor_suppliers); diff --git a/source/fuzz/fuzzer_pass_merge_blocks.cpp b/source/fuzz/fuzzer_pass_merge_blocks.cpp index ca1bfb33..49778aea 100644 --- a/source/fuzz/fuzzer_pass_merge_blocks.cpp +++ b/source/fuzz/fuzzer_pass_merge_blocks.cpp @@ -22,10 +22,11 @@ namespace spvtools { namespace fuzz { FuzzerPassMergeBlocks::FuzzerPassMergeBlocks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassMergeBlocks::~FuzzerPassMergeBlocks() = default; @@ -44,7 +45,8 @@ void FuzzerPassMergeBlocks::Apply() { // For other blocks, we add a transformation to merge the block into its // predecessor if that transformation would be applicable. TransformationMergeBlocks transformation(block.id()); - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { potential_transformations.push_back(transformation); } } @@ -54,8 +56,9 @@ void FuzzerPassMergeBlocks::Apply() { uint32_t index = GetFuzzerContext()->RandomIndex(potential_transformations); auto transformation = potential_transformations.at(index); potential_transformations.erase(potential_transformations.begin() + index); - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { - transformation.Apply(GetIRContext(), GetFactManager()); + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } } diff --git a/source/fuzz/fuzzer_pass_merge_blocks.h b/source/fuzz/fuzzer_pass_merge_blocks.h index 457e5913..1a6c2c27 100644 --- a/source/fuzz/fuzzer_pass_merge_blocks.h +++ b/source/fuzz/fuzzer_pass_merge_blocks.h @@ -23,7 +23,8 @@ namespace fuzz { // A fuzzer pass for merging blocks in the module. class FuzzerPassMergeBlocks : public FuzzerPass { public: - FuzzerPassMergeBlocks(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassMergeBlocks(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_obfuscate_constants.cpp b/source/fuzz/fuzzer_pass_obfuscate_constants.cpp index 2caf0c6b..4ced507f 100644 --- a/source/fuzz/fuzzer_pass_obfuscate_constants.cpp +++ b/source/fuzz/fuzzer_pass_obfuscate_constants.cpp @@ -25,10 +25,11 @@ namespace spvtools { namespace fuzz { FuzzerPassObfuscateConstants::FuzzerPassObfuscateConstants( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassObfuscateConstants::~FuzzerPassObfuscateConstants() = default; @@ -83,12 +84,13 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair( bool_constant_use, lhs_id, rhs_id, comparison_opcode, GetFuzzerContext()->GetFreshId()); // The transformation should be applicable by construction. - assert(transformation.IsApplicable(GetIRContext(), *GetFactManager())); + assert( + transformation.IsApplicable(GetIRContext(), *GetTransformationContext())); // Applying this transformation yields a pointer to the new instruction that // computes the result of the binary expression. - auto binary_operator_instruction = - transformation.ApplyWithResult(GetIRContext(), GetFactManager()); + auto binary_operator_instruction = transformation.ApplyWithResult( + GetIRContext(), GetTransformationContext()); // Add this transformation to the sequence of transformations that have been // applied. @@ -245,7 +247,9 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant( // with uniforms of the same value. auto available_types_with_uniforms = - GetFactManager()->GetTypesForWhichUniformValuesAreKnown(); + GetTransformationContext() + ->GetFactManager() + ->GetTypesForWhichUniformValuesAreKnown(); if (available_types_with_uniforms.empty()) { // Do not try to obfuscate if we do not have access to any uniform // elements with known values. @@ -254,9 +258,10 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant( auto chosen_type_id = available_types_with_uniforms[GetFuzzerContext()->RandomIndex( available_types_with_uniforms)]; - auto available_constants = - GetFactManager()->GetConstantsAvailableFromUniformsForType( - GetIRContext(), chosen_type_id); + auto available_constants = GetTransformationContext() + ->GetFactManager() + ->GetConstantsAvailableFromUniformsForType( + GetIRContext(), chosen_type_id); if (available_constants.size() == 1) { // TODO(afd): for now we only obfuscate a boolean if there are at least // two constants available from uniforms, so that we can do a @@ -308,8 +313,11 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant( // Check whether we know that any uniforms are guaranteed to be equal to the // scalar constant associated with |constant_use|. - auto uniform_descriptors = GetFactManager()->GetUniformDescriptorsForConstant( - GetIRContext(), constant_use.id_of_interest()); + auto uniform_descriptors = + GetTransformationContext() + ->GetFactManager() + ->GetUniformDescriptorsForConstant(GetIRContext(), + constant_use.id_of_interest()); if (uniform_descriptors.empty()) { // No relevant uniforms, so do not obfuscate. return; @@ -324,8 +332,9 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant( constant_use, uniform_descriptor, GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId()); // Transformation should be applicable by construction. - assert(transformation.IsApplicable(GetIRContext(), *GetFactManager())); - transformation.Apply(GetIRContext(), GetFactManager()); + assert( + transformation.IsApplicable(GetIRContext(), *GetTransformationContext())); + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } diff --git a/source/fuzz/fuzzer_pass_obfuscate_constants.h b/source/fuzz/fuzzer_pass_obfuscate_constants.h index f34717b2..7755d211 100644 --- a/source/fuzz/fuzzer_pass_obfuscate_constants.h +++ b/source/fuzz/fuzzer_pass_obfuscate_constants.h @@ -28,7 +28,7 @@ namespace fuzz { class FuzzerPassObfuscateConstants : public FuzzerPass { public: FuzzerPassObfuscateConstants( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_outline_functions.cpp b/source/fuzz/fuzzer_pass_outline_functions.cpp index d59c195d..1665d050 100644 --- a/source/fuzz/fuzzer_pass_outline_functions.cpp +++ b/source/fuzz/fuzzer_pass_outline_functions.cpp @@ -23,10 +23,11 @@ namespace spvtools { namespace fuzz { FuzzerPassOutlineFunctions::FuzzerPassOutlineFunctions( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassOutlineFunctions::~FuzzerPassOutlineFunctions() = default; @@ -88,8 +89,9 @@ void FuzzerPassOutlineFunctions::Apply() { /*new_callee_result_id*/ GetFuzzerContext()->GetFreshId(), /*input_id_to_fresh_id*/ std::move(input_id_to_fresh_id), /*output_id_to_fresh_id*/ std::move(output_id_to_fresh_id)); - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { - transformation.Apply(GetIRContext(), GetFactManager()); + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } } diff --git a/source/fuzz/fuzzer_pass_outline_functions.h b/source/fuzz/fuzzer_pass_outline_functions.h index 5448e7df..6532ed9a 100644 --- a/source/fuzz/fuzzer_pass_outline_functions.h +++ b/source/fuzz/fuzzer_pass_outline_functions.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassOutlineFunctions : public FuzzerPass { public: FuzzerPassOutlineFunctions( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_permute_blocks.cpp b/source/fuzz/fuzzer_pass_permute_blocks.cpp index af6d2a5d..27a2d671 100644 --- a/source/fuzz/fuzzer_pass_permute_blocks.cpp +++ b/source/fuzz/fuzzer_pass_permute_blocks.cpp @@ -20,10 +20,11 @@ namespace spvtools { namespace fuzz { FuzzerPassPermuteBlocks::FuzzerPassPermuteBlocks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassPermuteBlocks::~FuzzerPassPermuteBlocks() = default; @@ -66,8 +67,9 @@ void FuzzerPassPermuteBlocks::Apply() { // down indefinitely. while (true) { TransformationMoveBlockDown transformation(*id); - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { - transformation.Apply(GetIRContext(), GetFactManager()); + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } else { diff --git a/source/fuzz/fuzzer_pass_permute_blocks.h b/source/fuzz/fuzzer_pass_permute_blocks.h index 6735e952..f2d3b398 100644 --- a/source/fuzz/fuzzer_pass_permute_blocks.h +++ b/source/fuzz/fuzzer_pass_permute_blocks.h @@ -24,7 +24,8 @@ namespace fuzz { // manner. class FuzzerPassPermuteBlocks : public FuzzerPass { public: - FuzzerPassPermuteBlocks(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassPermuteBlocks(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_permute_function_parameters.cpp b/source/fuzz/fuzzer_pass_permute_function_parameters.cpp index 2c49860e..57d9cabb 100644 --- a/source/fuzz/fuzzer_pass_permute_function_parameters.cpp +++ b/source/fuzz/fuzzer_pass_permute_function_parameters.cpp @@ -25,10 +25,11 @@ namespace spvtools { namespace fuzz { FuzzerPassPermuteFunctionParameters::FuzzerPassPermuteFunctionParameters( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassPermuteFunctionParameters::~FuzzerPassPermuteFunctionParameters() = default; diff --git a/source/fuzz/fuzzer_pass_permute_function_parameters.h b/source/fuzz/fuzzer_pass_permute_function_parameters.h index bc798049..3f328642 100644 --- a/source/fuzz/fuzzer_pass_permute_function_parameters.h +++ b/source/fuzz/fuzzer_pass_permute_function_parameters.h @@ -30,7 +30,7 @@ namespace fuzz { class FuzzerPassPermuteFunctionParameters : public FuzzerPass { public: FuzzerPassPermuteFunctionParameters( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_split_blocks.cpp b/source/fuzz/fuzzer_pass_split_blocks.cpp index 6a2ea4dc..15c67901 100644 --- a/source/fuzz/fuzzer_pass_split_blocks.cpp +++ b/source/fuzz/fuzzer_pass_split_blocks.cpp @@ -23,10 +23,11 @@ namespace spvtools { namespace fuzz { FuzzerPassSplitBlocks::FuzzerPassSplitBlocks( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassSplitBlocks::~FuzzerPassSplitBlocks() = default; @@ -95,8 +96,9 @@ void FuzzerPassSplitBlocks::Apply() { // If the position we have chosen turns out to be a valid place to split // the block, we apply the split. Otherwise the block just doesn't get // split. - if (transformation.IsApplicable(GetIRContext(), *GetFactManager())) { - transformation.Apply(GetIRContext(), GetFactManager()); + if (transformation.IsApplicable(GetIRContext(), + *GetTransformationContext())) { + transformation.Apply(GetIRContext(), GetTransformationContext()); *GetTransformations()->add_transformation() = transformation.ToMessage(); } } diff --git a/source/fuzz/fuzzer_pass_split_blocks.h b/source/fuzz/fuzzer_pass_split_blocks.h index 6e56dde9..278ec6dc 100644 --- a/source/fuzz/fuzzer_pass_split_blocks.h +++ b/source/fuzz/fuzzer_pass_split_blocks.h @@ -24,7 +24,8 @@ namespace fuzz { // can be very useful for giving other passes a chance to apply. class FuzzerPassSplitBlocks : public FuzzerPass { public: - FuzzerPassSplitBlocks(opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerPassSplitBlocks(opt::IRContext* ir_context, + TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_swap_commutable_operands.cpp b/source/fuzz/fuzzer_pass_swap_commutable_operands.cpp index 4df97c94..321e8efd 100644 --- a/source/fuzz/fuzzer_pass_swap_commutable_operands.cpp +++ b/source/fuzz/fuzzer_pass_swap_commutable_operands.cpp @@ -22,10 +22,11 @@ namespace spvtools { namespace fuzz { FuzzerPassSwapCommutableOperands::FuzzerPassSwapCommutableOperands( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassSwapCommutableOperands::~FuzzerPassSwapCommutableOperands() = default; diff --git a/source/fuzz/fuzzer_pass_swap_commutable_operands.h b/source/fuzz/fuzzer_pass_swap_commutable_operands.h index b0206de7..74d937d8 100644 --- a/source/fuzz/fuzzer_pass_swap_commutable_operands.h +++ b/source/fuzz/fuzzer_pass_swap_commutable_operands.h @@ -26,7 +26,7 @@ namespace fuzz { class FuzzerPassSwapCommutableOperands : public FuzzerPass { public: FuzzerPassSwapCommutableOperands( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp index 9fb175ba..4f26cba3 100644 --- a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp +++ b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp @@ -22,10 +22,11 @@ namespace spvtools { namespace fuzz { FuzzerPassToggleAccessChainInstruction::FuzzerPassToggleAccessChainInstruction( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations) - : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + : FuzzerPass(ir_context, transformation_context, fuzzer_context, + transformations) {} FuzzerPassToggleAccessChainInstruction:: ~FuzzerPassToggleAccessChainInstruction() = default; diff --git a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h index ec8c3f78..d77c7cbe 100644 --- a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h +++ b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h @@ -25,7 +25,7 @@ namespace fuzz { class FuzzerPassToggleAccessChainInstruction : public FuzzerPass { public: FuzzerPassToggleAccessChainInstruction( - opt::IRContext* ir_context, FactManager* fact_manager, + opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, protobufs::TransformationSequence* transformations); diff --git a/source/fuzz/fuzzer_util.cpp b/source/fuzz/fuzzer_util.cpp index 4bfa1950..90cf9fe5 100644 --- a/source/fuzz/fuzzer_util.cpp +++ b/source/fuzz/fuzzer_util.cpp @@ -329,11 +329,11 @@ uint32_t GetArraySize(const opt::Instruction& array_type_instruction, return array_length_constant->GetU32(); } -bool IsValid(opt::IRContext* context) { +bool IsValid(opt::IRContext* context, spv_validator_options validator_options) { std::vector binary; context->module()->ToBinary(&binary, false); SpirvTools tools(context->grammar().target_env()); - return tools.Validate(binary); + return tools.Validate(binary.data(), binary.size(), validator_options); } std::unique_ptr CloneIRContext(opt::IRContext* context) { diff --git a/source/fuzz/fuzzer_util.h b/source/fuzz/fuzzer_util.h index 7be0d59e..08edfc58 100644 --- a/source/fuzz/fuzzer_util.h +++ b/source/fuzz/fuzzer_util.h @@ -132,8 +132,9 @@ uint32_t GetNumberOfStructMembers( uint32_t GetArraySize(const opt::Instruction& array_type_instruction, opt::IRContext* context); -// Returns true if and only if |context| is valid, according to the validator. -bool IsValid(opt::IRContext* context); +// Returns true if and only if |context| is valid, according to the validator +// instantiated with |validator_options|. +bool IsValid(opt::IRContext* context, spv_validator_options validator_options); // Returns a clone of |context|, by writing |context| to a binary and then // parsing it again. diff --git a/source/fuzz/replayer.cpp b/source/fuzz/replayer.cpp index 07dfe728..6312cbaf 100644 --- a/source/fuzz/replayer.cpp +++ b/source/fuzz/replayer.cpp @@ -26,6 +26,7 @@ #include "source/fuzz/transformation_add_type_float.h" #include "source/fuzz/transformation_add_type_int.h" #include "source/fuzz/transformation_add_type_pointer.h" +#include "source/fuzz/transformation_context.h" #include "source/fuzz/transformation_move_block_down.h" #include "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h" #include "source/fuzz/transformation_replace_constant_with_uniform.h" @@ -99,16 +100,19 @@ Replayer::ReplayerResultStatus Replayer::Run( FactManager fact_manager; fact_manager.AddFacts(impl_->consumer, initial_facts, ir_context.get()); + TransformationContext transformation_context(&fact_manager, + impl_->validator_options); // Consider the transformation proto messages in turn. for (auto& message : transformation_sequence_in.transformation()) { auto transformation = Transformation::FromMessage(message); // Check whether the transformation can be applied. - if (transformation->IsApplicable(ir_context.get(), fact_manager)) { + if (transformation->IsApplicable(ir_context.get(), + transformation_context)) { // The transformation is applicable, so apply it, and copy it to the // sequence of transformations that were applied. - transformation->Apply(ir_context.get(), &fact_manager); + transformation->Apply(ir_context.get(), &transformation_context); *transformation_sequence_out->add_transformation() = message; if (impl_->validate_during_replay) { diff --git a/source/fuzz/transformation.cpp b/source/fuzz/transformation.cpp index f18c86bd..6f008fcd 100644 --- a/source/fuzz/transformation.cpp +++ b/source/fuzz/transformation.cpp @@ -195,9 +195,9 @@ std::unique_ptr Transformation::FromMessage( } bool Transformation::CheckIdIsFreshAndNotUsedByThisTransformation( - uint32_t id, opt::IRContext* context, + uint32_t id, opt::IRContext* ir_context, std::set* ids_used_by_this_transformation) { - if (!fuzzerutil::IsFreshId(context, id)) { + if (!fuzzerutil::IsFreshId(ir_context, id)) { return false; } if (ids_used_by_this_transformation->count(id) != 0) { diff --git a/source/fuzz/transformation.h b/source/fuzz/transformation.h index dbe803f3..dbd0fe28 100644 --- a/source/fuzz/transformation.h +++ b/source/fuzz/transformation.h @@ -17,8 +17,8 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -60,19 +60,22 @@ class Transformation { public: // A precondition that determines whether the transformation can be cleanly // applied in a semantics-preserving manner to the SPIR-V module given by - // |context|, in the presence of facts captured by |fact_manager|. + // |ir_context|, in the presence of facts and other contextual information + // captured by |transformation_context|. + // // Preconditions for individual transformations must be documented in the - // associated header file using precise English. The fact manager is used to - // provide access to facts about the module that are known to be true, on + // associated header file using precise English. The transformation context + // provides access to facts about the module that are known to be true, on // which the precondition may depend. - virtual bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const = 0; + virtual bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const = 0; - // Requires that IsApplicable(context, fact_manager) holds. Applies the - // transformation, mutating |context| and possibly updating |fact_manager| - // with new facts established by the transformation. - virtual void Apply(opt::IRContext* context, - FactManager* fact_manager) const = 0; + // Requires that IsApplicable(ir_context, *transformation_context) holds. + // Applies the transformation, mutating |ir_context| and possibly updating + // |transformation_context| with new facts established by the transformation. + virtual void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const = 0; // Turns the transformation into a protobuf message for serialization. virtual protobufs::Transformation ToMessage() const = 0; @@ -90,7 +93,7 @@ class Transformation { // checking id freshness for a transformation that uses many ids, all of which // must be distinct. static bool CheckIdIsFreshAndNotUsedByThisTransformation( - uint32_t id, opt::IRContext* context, + uint32_t id, opt::IRContext* ir_context, std::set* ids_used_by_this_transformation); }; diff --git a/source/fuzz/transformation_access_chain.cpp b/source/fuzz/transformation_access_chain.cpp index 8c310064..ff17c368 100644 --- a/source/fuzz/transformation_access_chain.cpp +++ b/source/fuzz/transformation_access_chain.cpp @@ -40,19 +40,18 @@ TransformationAccessChain::TransformationAccessChain( } bool TransformationAccessChain::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The pointer id must exist and have a type. - auto pointer = context->get_def_use_mgr()->GetDef(message_.pointer_id()); + auto pointer = ir_context->get_def_use_mgr()->GetDef(message_.pointer_id()); if (!pointer || !pointer->type_id()) { return false; } // The type must indeed be a pointer - auto pointer_type = context->get_def_use_mgr()->GetDef(pointer->type_id()); + auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); if (pointer_type->opcode() != SpvOpTypePointer) { return false; } @@ -60,7 +59,7 @@ bool TransformationAccessChain::IsApplicable( // The described instruction to insert before must exist and be a suitable // point where an OpAccessChain instruction could be inserted. auto instruction_to_insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!instruction_to_insert_before) { return false; } @@ -86,7 +85,7 @@ bool TransformationAccessChain::IsApplicable( // The pointer on which the access chain is to be based needs to be available // (according to dominance rules) at the insertion point. if (!fuzzerutil::IdIsAvailableBeforeInstruction( - context, instruction_to_insert_before, message_.pointer_id())) { + ir_context, instruction_to_insert_before, message_.pointer_id())) { return false; } @@ -104,7 +103,7 @@ bool TransformationAccessChain::IsApplicable( // integer. Otherwise, the integer with which the id is associated is the // second component. std::pair maybe_index_value = - GetIndexValue(context, index_id); + GetIndexValue(ir_context, index_id); if (!maybe_index_value.first) { // There was no integer: this index is no good. return false; @@ -113,7 +112,7 @@ bool TransformationAccessChain::IsApplicable( // type is not a composite or the index is out of bounds, and the id of // the next type otherwise. subobject_type_id = fuzzerutil::WalkOneCompositeTypeIndex( - context, subobject_type_id, maybe_index_value.second); + ir_context, subobject_type_id, maybe_index_value.second); if (!subobject_type_id) { // Either the type was not a composite (so that too many indices were // provided), or the index was out of bounds. @@ -128,13 +127,14 @@ bool TransformationAccessChain::IsApplicable( // We do not use the type manager to look up this type, due to problems // associated with pointers to isomorphic structs being regarded as the same. return fuzzerutil::MaybeGetPointerType( - context, subobject_type_id, + ir_context, subobject_type_id, static_cast( pointer_type->GetSingleWordInOperand(0))) != 0; } void TransformationAccessChain::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // The operands to the access chain are the pointer followed by the indices. // The result type of the access chain is determined by where the indices // lead. We thus push the pointer to a sequence of operands, and then follow @@ -148,8 +148,8 @@ void TransformationAccessChain::Apply( operands.push_back({SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}); // Start walking the indices, starting with the pointer's base type. - auto pointer_type = context->get_def_use_mgr()->GetDef( - context->get_def_use_mgr()->GetDef(message_.pointer_id())->type_id()); + auto pointer_type = ir_context->get_def_use_mgr()->GetDef( + ir_context->get_def_use_mgr()->GetDef(message_.pointer_id())->type_id()); uint32_t subobject_type_id = pointer_type->GetSingleWordInOperand(1); // Go through the index ids in turn. @@ -157,33 +157,35 @@ void TransformationAccessChain::Apply( // Add the index id to the operands. operands.push_back({SPV_OPERAND_TYPE_ID, {index_id}}); // Get the integer value associated with the index id. - uint32_t index_value = GetIndexValue(context, index_id).second; + uint32_t index_value = GetIndexValue(ir_context, index_id).second; // Walk to the next type in the composite object using this index. subobject_type_id = fuzzerutil::WalkOneCompositeTypeIndex( - context, subobject_type_id, index_value); + ir_context, subobject_type_id, index_value); } // The access chain's result type is a pointer to the composite component that // was reached after following all indices. The storage class is that of the // original pointer. uint32_t result_type = fuzzerutil::MaybeGetPointerType( - context, subobject_type_id, + ir_context, subobject_type_id, static_cast(pointer_type->GetSingleWordInOperand(0))); // Add the access chain instruction to the module, and update the module's id // bound. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - FindInstruction(message_.instruction_to_insert_before(), context) - ->InsertBefore( - MakeUnique(context, SpvOpAccessChain, result_type, - message_.fresh_id(), operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + FindInstruction(message_.instruction_to_insert_before(), ir_context) + ->InsertBefore(MakeUnique( + ir_context, SpvOpAccessChain, result_type, message_.fresh_id(), + operands)); // Conservatively invalidate all analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); // If the base pointer's pointee value was irrelevant, the same is true of the // pointee value of the result of this access chain. - if (fact_manager->PointeeValueIsIrrelevant(message_.pointer_id())) { - fact_manager->AddFactValueOfPointeeIsIrrelevant(message_.fresh_id()); + if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant( + message_.pointer_id())) { + transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + message_.fresh_id()); } } @@ -194,8 +196,8 @@ protobufs::Transformation TransformationAccessChain::ToMessage() const { } std::pair TransformationAccessChain::GetIndexValue( - opt::IRContext* context, uint32_t index_id) const { - auto index_instruction = context->get_def_use_mgr()->GetDef(index_id); + opt::IRContext* ir_context, uint32_t index_id) const { + auto index_instruction = ir_context->get_def_use_mgr()->GetDef(index_id); if (!index_instruction || !spvOpcodeIsConstant(index_instruction->opcode())) { // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3179) We could // allow non-constant indices when looking up non-structs, using clamping @@ -203,7 +205,7 @@ std::pair TransformationAccessChain::GetIndexValue( return {false, 0}; } auto index_type = - context->get_def_use_mgr()->GetDef(index_instruction->type_id()); + ir_context->get_def_use_mgr()->GetDef(index_instruction->type_id()); if (index_type->opcode() != SpvOpTypeInt || index_type->GetSingleWordInOperand(0) != 32) { return {false, 0}; diff --git a/source/fuzz/transformation_access_chain.h b/source/fuzz/transformation_access_chain.h index 92d9e6a6..9306a596 100644 --- a/source/fuzz/transformation_access_chain.h +++ b/source/fuzz/transformation_access_chain.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -47,8 +47,9 @@ class TransformationAccessChain : public Transformation { // - If type t is the final type reached by walking these indices, the module // must include an instruction "OpTypePointer SC %t" where SC is the storage // class associated with |message_.pointer_id| - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction of the form: // |message_.fresh_id| = OpAccessChain %ptr |message_.index_id| @@ -57,10 +58,12 @@ class TransformationAccessChain : public Transformation { // the indices in |message_.index_id|, and with the same storage class as // |message_.pointer_id|. // - // If |fact_manager| reports that |message_.pointer_id| has an irrelevant - // pointee value, then the fact that |message_.fresh_id| (the result of the - // access chain) also has an irrelevant pointee value is also recorded. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + // If the fact manager in |transformation_context| reports that + // |message_.pointer_id| has an irrelevant pointee value, then the fact that + // |message_.fresh_id| (the result of the access chain) also has an irrelevant + // pointee value is also recorded. + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -68,7 +71,7 @@ class TransformationAccessChain : public Transformation { // Returns {false, 0} if |index_id| does not correspond to a 32-bit integer // constant. Otherwise, returns {true, value}, where value is the value of // the 32-bit integer constant to which |index_id| corresponds. - std::pair GetIndexValue(opt::IRContext* context, + std::pair GetIndexValue(opt::IRContext* ir_context, uint32_t index_id) const; protobufs::TransformationAccessChain message_; diff --git a/source/fuzz/transformation_add_constant_boolean.cpp b/source/fuzz/transformation_add_constant_boolean.cpp index 21c8ed3f..1930f7ef 100644 --- a/source/fuzz/transformation_add_constant_boolean.cpp +++ b/source/fuzz/transformation_add_constant_boolean.cpp @@ -31,27 +31,28 @@ TransformationAddConstantBoolean::TransformationAddConstantBoolean( } bool TransformationAddConstantBoolean::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { opt::analysis::Bool bool_type; - if (!context->get_type_mgr()->GetId(&bool_type)) { + if (!ir_context->get_type_mgr()->GetId(&bool_type)) { // No OpTypeBool is present. return false; } - return fuzzerutil::IsFreshId(context, message_.fresh_id()); + return fuzzerutil::IsFreshId(ir_context, message_.fresh_id()); } -void TransformationAddConstantBoolean::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { +void TransformationAddConstantBoolean::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::analysis::Bool bool_type; // Add the boolean constant to the module, ensuring the module's id bound is // high enough. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - context->module()->AddGlobalValue( + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + ir_context->module()->AddGlobalValue( message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse, - message_.fresh_id(), context->get_type_mgr()->GetId(&bool_type)); + message_.fresh_id(), ir_context->get_type_mgr()->GetId(&bool_type)); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddConstantBoolean::ToMessage() const { diff --git a/source/fuzz/transformation_add_constant_boolean.h b/source/fuzz/transformation_add_constant_boolean.h index 79df1cda..5d876cf6 100644 --- a/source/fuzz/transformation_add_constant_boolean.h +++ b/source/fuzz/transformation_add_constant_boolean.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_BOOLEAN_CONSTANT_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_BOOLEAN_CONSTANT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -32,12 +32,14 @@ class TransformationAddConstantBoolean : public Transformation { // - |message_.fresh_id| must not be used by the module. // - The module must already contain OpTypeBool. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - Adds OpConstantTrue (OpConstantFalse) to the module with id // |message_.fresh_id| if |message_.is_true| holds (does not hold). - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_constant_composite.cpp b/source/fuzz/transformation_add_constant_composite.cpp index 7ba1ea4d..ae34b262 100644 --- a/source/fuzz/transformation_add_constant_composite.cpp +++ b/source/fuzz/transformation_add_constant_composite.cpp @@ -37,15 +37,14 @@ TransformationAddConstantComposite::TransformationAddConstantComposite( } bool TransformationAddConstantComposite::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // Check that the given id is fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // Check that the composite type id is an instruction id. auto composite_type_instruction = - context->get_def_use_mgr()->GetDef(message_.type_id()); + ir_context->get_def_use_mgr()->GetDef(message_.type_id()); if (!composite_type_instruction) { return false; } @@ -56,7 +55,7 @@ bool TransformationAddConstantComposite::IsApplicable( case SpvOpTypeArray: for (uint32_t index = 0; index < - fuzzerutil::GetArraySize(*composite_type_instruction, context); + fuzzerutil::GetArraySize(*composite_type_instruction, ir_context); index++) { constituent_type_ids.push_back( composite_type_instruction->GetSingleWordInOperand(0)); @@ -93,7 +92,7 @@ bool TransformationAddConstantComposite::IsApplicable( // corresponding constituent type. for (uint32_t index = 0; index < constituent_type_ids.size(); index++) { auto constituent_instruction = - context->get_def_use_mgr()->GetDef(message_.constituent_id(index)); + ir_context->get_def_use_mgr()->GetDef(message_.constituent_id(index)); if (!constituent_instruction) { return false; } @@ -105,18 +104,19 @@ bool TransformationAddConstantComposite::IsApplicable( } void TransformationAddConstantComposite::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; for (auto constituent_id : message_.constituent_id()) { in_operands.push_back({SPV_OPERAND_TYPE_ID, {constituent_id}}); } - context->module()->AddGlobalValue(MakeUnique( - context, SpvOpConstantComposite, message_.type_id(), message_.fresh_id(), - in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddGlobalValue(MakeUnique( + ir_context, SpvOpConstantComposite, message_.type_id(), + message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddConstantComposite::ToMessage() diff --git a/source/fuzz/transformation_add_constant_composite.h b/source/fuzz/transformation_add_constant_composite.h index 9a824a04..4fec561f 100644 --- a/source/fuzz/transformation_add_constant_composite.h +++ b/source/fuzz/transformation_add_constant_composite.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -38,13 +38,15 @@ class TransformationAddConstantComposite : public Transformation { // - |message_.type_id| must be the id of a composite type // - |message_.constituent_id| must refer to ids that match the constituent // types of this composite type - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpConstantComposite instruction defining a constant of type // |message_.type_id|, using |message_.constituent_id| as constituents, with // result id |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_constant_scalar.cpp b/source/fuzz/transformation_add_constant_scalar.cpp index 36af5e01..e13d08f7 100644 --- a/source/fuzz/transformation_add_constant_scalar.cpp +++ b/source/fuzz/transformation_add_constant_scalar.cpp @@ -33,14 +33,13 @@ TransformationAddConstantScalar::TransformationAddConstantScalar( } bool TransformationAddConstantScalar::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id needs to be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The type id for the scalar must exist and be a type. - auto type = context->get_type_mgr()->GetType(message_.type_id()); + auto type = ir_context->get_type_mgr()->GetType(message_.type_id()); if (!type) { return false; } @@ -61,20 +60,21 @@ bool TransformationAddConstantScalar::IsApplicable( } void TransformationAddConstantScalar::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList operand_list; for (auto word : message_.word()) { operand_list.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {word}}); } - context->module()->AddGlobalValue( - MakeUnique(context, SpvOpConstant, message_.type_id(), - message_.fresh_id(), operand_list)); + ir_context->module()->AddGlobalValue(MakeUnique( + ir_context, SpvOpConstant, message_.type_id(), message_.fresh_id(), + operand_list)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddConstantScalar::ToMessage() const { diff --git a/source/fuzz/transformation_add_constant_scalar.h b/source/fuzz/transformation_add_constant_scalar.h index 914cfe62..e0ed39fa 100644 --- a/source/fuzz/transformation_add_constant_scalar.h +++ b/source/fuzz/transformation_add_constant_scalar.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -37,11 +37,13 @@ class TransformationAddConstantScalar : public Transformation { // - |message_.type_id| must be the id of a floating-point or integer type // - The size of |message_.word| must be compatible with the width of this // type - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds a new OpConstant instruction with the given type and words. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_dead_block.cpp b/source/fuzz/transformation_add_dead_block.cpp index b58f75e5..b246c3fc 100644 --- a/source/fuzz/transformation_add_dead_block.cpp +++ b/source/fuzz/transformation_add_dead_block.cpp @@ -32,16 +32,15 @@ TransformationAddDeadBlock::TransformationAddDeadBlock(uint32_t fresh_id, } bool TransformationAddDeadBlock::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The new block's id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // First, we check that a constant with the same value as // |message_.condition_value| is present. - if (!fuzzerutil::MaybeGetBoolConstantId(context, + if (!fuzzerutil::MaybeGetBoolConstantId(ir_context, message_.condition_value())) { // The required constant is not present, so the transformation cannot be // applied. @@ -50,7 +49,7 @@ bool TransformationAddDeadBlock::IsApplicable( // The existing block must indeed exist. auto existing_block = - fuzzerutil::MaybeFindBlock(context, message_.existing_block()); + fuzzerutil::MaybeFindBlock(ir_context, message_.existing_block()); if (!existing_block) { return false; } @@ -68,13 +67,13 @@ bool TransformationAddDeadBlock::IsApplicable( // Its successor must not be a merge block nor continue target. auto successor_block_id = existing_block->terminator()->GetSingleWordInOperand(0); - if (fuzzerutil::IsMergeOrContinue(context, successor_block_id)) { + if (fuzzerutil::IsMergeOrContinue(ir_context, successor_block_id)) { return false; } // The successor must not be a loop header (i.e., |message_.existing_block| // must not be a back-edge block. - if (context->cfg()->block(successor_block_id)->IsLoopHeader()) { + if (ir_context->cfg()->block(successor_block_id)->IsLoopHeader()) { return false; } @@ -82,34 +81,36 @@ bool TransformationAddDeadBlock::IsApplicable( } void TransformationAddDeadBlock::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // Update the module id bound so that it is at least the id of the new block. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // Get the existing block and its successor. - auto existing_block = context->cfg()->block(message_.existing_block()); + auto existing_block = ir_context->cfg()->block(message_.existing_block()); auto successor_block_id = existing_block->terminator()->GetSingleWordInOperand(0); // Get the id of the boolean value that will be used as the branch condition. - auto bool_id = - fuzzerutil::MaybeGetBoolConstantId(context, message_.condition_value()); + auto bool_id = fuzzerutil::MaybeGetBoolConstantId(ir_context, + message_.condition_value()); // Make a new block that unconditionally branches to the original successor // block. auto enclosing_function = existing_block->GetParent(); - std::unique_ptr new_block = MakeUnique( - MakeUnique(context, SpvOpLabel, 0, message_.fresh_id(), - opt::Instruction::OperandList())); + std::unique_ptr new_block = + MakeUnique(MakeUnique( + ir_context, SpvOpLabel, 0, message_.fresh_id(), + opt::Instruction::OperandList())); new_block->AddInstruction(MakeUnique( - context, SpvOpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {successor_block_id}}}))); // Turn the original block into a selection merge, with its original successor // as the merge block. existing_block->terminator()->InsertBefore(MakeUnique( - context, SpvOpSelectionMerge, 0, 0, + ir_context, SpvOpSelectionMerge, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {successor_block_id}}, {SPV_OPERAND_TYPE_SELECTION_CONTROL, @@ -135,7 +136,8 @@ void TransformationAddDeadBlock::Apply( existing_block); // Record the fact that the new block is dead. - fact_manager->AddFactBlockIsDead(message_.fresh_id()); + transformation_context->GetFactManager()->AddFactBlockIsDead( + message_.fresh_id()); // Fix up OpPhi instructions in the successor block, so that the values they // yield when control has transferred from the new block are the same as if @@ -143,7 +145,7 @@ void TransformationAddDeadBlock::Apply( // to be valid since |message_.existing_block| dominates the new block by // construction. Other transformations can change these phi operands to more // interesting values. - context->cfg() + ir_context->cfg() ->block(successor_block_id) ->ForEachPhiInst([this](opt::Instruction* phi_inst) { // Copy the operand that provides the phi value for the first of any @@ -156,7 +158,7 @@ void TransformationAddDeadBlock::Apply( // Do not rely on any existing analysis results since the control flow graph // of the module has changed. - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationAddDeadBlock::ToMessage() const { diff --git a/source/fuzz/transformation_add_dead_block.h b/source/fuzz/transformation_add_dead_block.h index 059daca9..7d076164 100644 --- a/source/fuzz/transformation_add_dead_block.h +++ b/source/fuzz/transformation_add_dead_block.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_DEAD_BLOCK_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_DEAD_BLOCK_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -41,15 +41,17 @@ class TransformationAddDeadBlock : public Transformation { // - |message_.existing_block| must not be a back-edge block, since in this // case the newly-added block would lead to another back-edge to the // associated loop header - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Changes the OpBranch from |message_.existing_block| to its successor 's' // to an OpBranchConditional to either 's' or a new block, // |message_.fresh_id|, which itself unconditionally branches to 's'. The // conditional branch uses |message.condition_value| as its condition, and is // arranged so that control will pass to 's' at runtime. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_dead_break.cpp b/source/fuzz/transformation_add_dead_break.cpp index 43847fad..db9de7d2 100644 --- a/source/fuzz/transformation_add_dead_break.cpp +++ b/source/fuzz/transformation_add_dead_break.cpp @@ -14,8 +14,8 @@ #include "source/fuzz/transformation_add_dead_break.h" -#include "source/fuzz/fact_manager.h" #include "source/fuzz/fuzzer_util.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/basic_block.h" #include "source/opt/ir_context.h" #include "source/opt/struct_cfg_analysis.h" @@ -39,7 +39,7 @@ TransformationAddDeadBreak::TransformationAddDeadBreak( } bool TransformationAddDeadBreak::AddingBreakRespectsStructuredControlFlow( - opt::IRContext* context, opt::BasicBlock* bb_from) const { + opt::IRContext* ir_context, opt::BasicBlock* bb_from) const { // Look at the structured control flow associated with |from_block| and // check whether it is contained in an appropriate construct with merge id // |to_block| such that a break from |from_block| to |to_block| is legal. @@ -70,7 +70,7 @@ bool TransformationAddDeadBreak::AddingBreakRespectsStructuredControlFlow( // structured control flow construct. auto containing_construct = - context->GetStructuredCFGAnalysis()->ContainingConstruct( + ir_context->GetStructuredCFGAnalysis()->ContainingConstruct( message_.from_block()); if (!containing_construct) { // |from_block| is not in a construct from which we can break. @@ -79,7 +79,7 @@ bool TransformationAddDeadBreak::AddingBreakRespectsStructuredControlFlow( // Consider case (2) if (message_.to_block() == - context->cfg()->block(containing_construct)->MergeBlockId()) { + ir_context->cfg()->block(containing_construct)->MergeBlockId()) { // This looks like an instance of case (2). // However, the structured CFG analysis regards the continue construct of a // loop as part of the loop, but it is not legal to jump from a loop's @@ -90,28 +90,29 @@ bool TransformationAddDeadBreak::AddingBreakRespectsStructuredControlFlow( // currently allow a dead break from a back edge block, but we could and // ultimately should. return !fuzzerutil::BlockIsInLoopContinueConstruct( - context, message_.from_block(), containing_construct); + ir_context, message_.from_block(), containing_construct); } // Case (3) holds if and only if |to_block| is the merge block for this // innermost loop that contains |from_block| auto containing_loop_header = - context->GetStructuredCFGAnalysis()->ContainingLoop( + ir_context->GetStructuredCFGAnalysis()->ContainingLoop( message_.from_block()); if (containing_loop_header && message_.to_block() == - context->cfg()->block(containing_loop_header)->MergeBlockId()) { + ir_context->cfg()->block(containing_loop_header)->MergeBlockId()) { return !fuzzerutil::BlockIsInLoopContinueConstruct( - context, message_.from_block(), containing_loop_header); + ir_context, message_.from_block(), containing_loop_header); } return false; } bool TransformationAddDeadBreak::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // First, we check that a constant with the same value as // |message_.break_condition_value| is present. - if (!fuzzerutil::MaybeGetBoolConstantId(context, + if (!fuzzerutil::MaybeGetBoolConstantId(ir_context, message_.break_condition_value())) { // The required constant is not present, so the transformation cannot be // applied. @@ -121,17 +122,17 @@ bool TransformationAddDeadBreak::IsApplicable( // Check that |message_.from_block| and |message_.to_block| really are block // ids opt::BasicBlock* bb_from = - fuzzerutil::MaybeFindBlock(context, message_.from_block()); + fuzzerutil::MaybeFindBlock(ir_context, message_.from_block()); if (bb_from == nullptr) { return false; } opt::BasicBlock* bb_to = - fuzzerutil::MaybeFindBlock(context, message_.to_block()); + fuzzerutil::MaybeFindBlock(ir_context, message_.to_block()); if (bb_to == nullptr) { return false; } - if (!fuzzerutil::BlockIsReachableInItsFunction(context, bb_to)) { + if (!fuzzerutil::BlockIsReachableInItsFunction(ir_context, bb_to)) { // If the target of the break is unreachable, we conservatively do not // allow adding a dead break, to avoid the compilations that arise due to // the lack of sensible dominance information for unreachable blocks. @@ -157,14 +158,14 @@ bool TransformationAddDeadBreak::IsApplicable( "The id of the block we found should match the target id for the break."); // Check whether the data passed to extend OpPhi instructions is appropriate. - if (!fuzzerutil::PhiIdsOkForNewEdge(context, bb_from, bb_to, + if (!fuzzerutil::PhiIdsOkForNewEdge(ir_context, bb_from, bb_to, message_.phi_id())) { return false; } // Check that adding the break would respect the rules of structured // control flow. - if (!AddingBreakRespectsStructuredControlFlow(context, bb_from)) { + if (!AddingBreakRespectsStructuredControlFlow(ir_context, bb_from)) { return false; } @@ -177,16 +178,18 @@ bool TransformationAddDeadBreak::IsApplicable( // being places on the validator. This should be revisited if we are sure // the validator is complete with respect to checking structured control flow // rules. - auto cloned_context = fuzzerutil::CloneIRContext(context); + auto cloned_context = fuzzerutil::CloneIRContext(ir_context); ApplyImpl(cloned_context.get()); - return fuzzerutil::IsValid(cloned_context.get()); + return fuzzerutil::IsValid(cloned_context.get(), + transformation_context.GetValidatorOptions()); } -void TransformationAddDeadBreak::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { - ApplyImpl(context); +void TransformationAddDeadBreak::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { + ApplyImpl(ir_context); // Invalidate all analyses - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddDeadBreak::ToMessage() const { @@ -196,10 +199,10 @@ protobufs::Transformation TransformationAddDeadBreak::ToMessage() const { } void TransformationAddDeadBreak::ApplyImpl( - spvtools::opt::IRContext* context) const { + spvtools::opt::IRContext* ir_context) const { fuzzerutil::AddUnreachableEdgeAndUpdateOpPhis( - context, context->cfg()->block(message_.from_block()), - context->cfg()->block(message_.to_block()), + ir_context, ir_context->cfg()->block(message_.from_block()), + ir_context->cfg()->block(message_.to_block()), message_.break_condition_value(), message_.phi_id()); } diff --git a/source/fuzz/transformation_add_dead_break.h b/source/fuzz/transformation_add_dead_break.h index 81a2c991..0ea92104 100644 --- a/source/fuzz/transformation_add_dead_break.h +++ b/source/fuzz/transformation_add_dead_break.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -50,21 +50,23 @@ class TransformationAddDeadBreak : public Transformation { // maintain validity of the module. // In particular, the new branch must not lead to violations of the rule // that a use must be dominated by its definition. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Replaces the terminator of a with a conditional branch to b or c. // The boolean constant associated with |message_.break_condition_value| is // used as the condition, and the order of b and c is arranged such that // control is guaranteed to jump to c. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; private: // Returns true if and only if adding an edge from |bb_from| to // |message_.to_block| respects structured control flow. - bool AddingBreakRespectsStructuredControlFlow(opt::IRContext* context, + bool AddingBreakRespectsStructuredControlFlow(opt::IRContext* ir_context, opt::BasicBlock* bb_from) const; // Used by 'Apply' to actually apply the transformation to the module of @@ -73,7 +75,7 @@ class TransformationAddDeadBreak : public Transformation { // module. This is only invoked by 'IsApplicable' after certain basic // applicability checks have been made, ensuring that the invocation of this // method is legal. - void ApplyImpl(opt::IRContext* context) const; + void ApplyImpl(opt::IRContext* ir_context) const; protobufs::TransformationAddDeadBreak message_; }; diff --git a/source/fuzz/transformation_add_dead_continue.cpp b/source/fuzz/transformation_add_dead_continue.cpp index 3a4875e3..1fc6d671 100644 --- a/source/fuzz/transformation_add_dead_continue.cpp +++ b/source/fuzz/transformation_add_dead_continue.cpp @@ -34,11 +34,12 @@ TransformationAddDeadContinue::TransformationAddDeadContinue( } bool TransformationAddDeadContinue::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // First, we check that a constant with the same value as // |message_.continue_condition_value| is present. if (!fuzzerutil::MaybeGetBoolConstantId( - context, message_.continue_condition_value())) { + ir_context, message_.continue_condition_value())) { // The required constant is not present, so the transformation cannot be // applied. return false; @@ -46,7 +47,7 @@ bool TransformationAddDeadContinue::IsApplicable( // Check that |message_.from_block| really is a block id. opt::BasicBlock* bb_from = - fuzzerutil::MaybeFindBlock(context, message_.from_block()); + fuzzerutil::MaybeFindBlock(ir_context, message_.from_block()); if (bb_from == nullptr) { return false; } @@ -68,31 +69,33 @@ bool TransformationAddDeadContinue::IsApplicable( // Because the structured CFG analysis does not regard a loop header as part // of the loop it heads, we check first whether bb_from is a loop header // before using the structured CFG analysis. - auto loop_header = bb_from->IsLoopHeader() - ? message_.from_block() - : context->GetStructuredCFGAnalysis()->ContainingLoop( - message_.from_block()); + auto loop_header = + bb_from->IsLoopHeader() + ? message_.from_block() + : ir_context->GetStructuredCFGAnalysis()->ContainingLoop( + message_.from_block()); if (!loop_header) { return false; } - auto continue_block = context->cfg()->block(loop_header)->ContinueBlockId(); + auto continue_block = + ir_context->cfg()->block(loop_header)->ContinueBlockId(); if (!fuzzerutil::BlockIsReachableInItsFunction( - context, context->cfg()->block(continue_block))) { + ir_context, ir_context->cfg()->block(continue_block))) { // If the loop's continue block is unreachable, we conservatively do not // allow adding a dead continue, to avoid the compilations that arise due to // the lack of sensible dominance information for unreachable blocks. return false; } - if (fuzzerutil::BlockIsInLoopContinueConstruct(context, message_.from_block(), - loop_header)) { + if (fuzzerutil::BlockIsInLoopContinueConstruct( + ir_context, message_.from_block(), loop_header)) { // We cannot jump to the continue target from the continue construct. return false; } - if (context->GetStructuredCFGAnalysis()->IsMergeBlock(continue_block)) { + if (ir_context->GetStructuredCFGAnalysis()->IsMergeBlock(continue_block)) { // A branch straight to the continue target that is also a merge block might // break the property that a construct header must dominate its merge block // (if the merge block is reachable). @@ -100,8 +103,8 @@ bool TransformationAddDeadContinue::IsApplicable( } // Check whether the data passed to extend OpPhi instructions is appropriate. - if (!fuzzerutil::PhiIdsOkForNewEdge(context, bb_from, - context->cfg()->block(continue_block), + if (!fuzzerutil::PhiIdsOkForNewEdge(ir_context, bb_from, + ir_context->cfg()->block(continue_block), message_.phi_id())) { return false; } @@ -115,16 +118,18 @@ bool TransformationAddDeadContinue::IsApplicable( // being placed on the validator. This should be revisited if we are sure // the validator is complete with respect to checking structured control flow // rules. - auto cloned_context = fuzzerutil::CloneIRContext(context); + auto cloned_context = fuzzerutil::CloneIRContext(ir_context); ApplyImpl(cloned_context.get()); - return fuzzerutil::IsValid(cloned_context.get()); + return fuzzerutil::IsValid(cloned_context.get(), + transformation_context.GetValidatorOptions()); } -void TransformationAddDeadContinue::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { - ApplyImpl(context); +void TransformationAddDeadContinue::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { + ApplyImpl(ir_context); // Invalidate all analyses - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddDeadContinue::ToMessage() const { @@ -134,16 +139,16 @@ protobufs::Transformation TransformationAddDeadContinue::ToMessage() const { } void TransformationAddDeadContinue::ApplyImpl( - spvtools::opt::IRContext* context) const { - auto bb_from = context->cfg()->block(message_.from_block()); + spvtools::opt::IRContext* ir_context) const { + auto bb_from = ir_context->cfg()->block(message_.from_block()); auto continue_block = bb_from->IsLoopHeader() ? bb_from->ContinueBlockId() - : context->GetStructuredCFGAnalysis()->LoopContinueBlock( + : ir_context->GetStructuredCFGAnalysis()->LoopContinueBlock( message_.from_block()); assert(continue_block && "message_.from_block must be in a loop."); fuzzerutil::AddUnreachableEdgeAndUpdateOpPhis( - context, bb_from, context->cfg()->block(continue_block), + ir_context, bb_from, ir_context->cfg()->block(continue_block), message_.continue_condition_value(), message_.phi_id()); } diff --git a/source/fuzz/transformation_add_dead_continue.h b/source/fuzz/transformation_add_dead_continue.h index 86b4c93b..1053c165 100644 --- a/source/fuzz/transformation_add_dead_continue.h +++ b/source/fuzz/transformation_add_dead_continue.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -52,14 +52,16 @@ class TransformationAddDeadContinue : public Transformation { // In particular, adding an edge from somewhere in the loop to the continue // target must not prevent uses of ids in the continue target from being // dominated by the definitions of those ids. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Replaces the terminator of a with a conditional branch to b or c. // The boolean constant associated with |message_.continue_condition_value| is // used as the condition, and the order of b and c is arranged such that // control is guaranteed to jump to c. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -70,7 +72,7 @@ class TransformationAddDeadContinue : public Transformation { // module. This is only invoked by 'IsApplicable' after certain basic // applicability checks have been made, ensuring that the invocation of this // method is legal. - void ApplyImpl(opt::IRContext* context) const; + void ApplyImpl(opt::IRContext* ir_context) const; protobufs::TransformationAddDeadContinue message_; }; diff --git a/source/fuzz/transformation_add_function.cpp b/source/fuzz/transformation_add_function.cpp index 8f0d3c92..45fe342d 100644 --- a/source/fuzz/transformation_add_function.cpp +++ b/source/fuzz/transformation_add_function.cpp @@ -56,8 +56,8 @@ TransformationAddFunction::TransformationAddFunction( } bool TransformationAddFunction::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // This transformation may use a lot of ids, all of which need to be fresh // and distinct. This set tracks them. std::set ids_used_by_this_transformation; @@ -66,7 +66,7 @@ bool TransformationAddFunction::IsApplicable( for (auto& instruction : message_.instruction()) { if (instruction.result_id()) { if (!CheckIdIsFreshAndNotUsedByThisTransformation( - instruction.result_id(), context, + instruction.result_id(), ir_context, &ids_used_by_this_transformation)) { return false; } @@ -77,28 +77,28 @@ bool TransformationAddFunction::IsApplicable( // Ensure that all ids provided for making the function livesafe are fresh // and distinct. if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.loop_limiter_variable_id(), context, + message_.loop_limiter_variable_id(), ir_context, &ids_used_by_this_transformation)) { return false; } for (auto& loop_limiter_info : message_.loop_limiter_info()) { if (!CheckIdIsFreshAndNotUsedByThisTransformation( - loop_limiter_info.load_id(), context, + loop_limiter_info.load_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - loop_limiter_info.increment_id(), context, + loop_limiter_info.increment_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - loop_limiter_info.compare_id(), context, + loop_limiter_info.compare_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - loop_limiter_info.logical_op_id(), context, + loop_limiter_info.logical_op_id(), ir_context, &ids_used_by_this_transformation)) { return false; } @@ -107,11 +107,11 @@ bool TransformationAddFunction::IsApplicable( message_.access_chain_clamping_info()) { for (auto& pair : access_chain_clamping_info.compare_and_select_ids()) { if (!CheckIdIsFreshAndNotUsedByThisTransformation( - pair.first(), context, &ids_used_by_this_transformation)) { + pair.first(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - pair.second(), context, &ids_used_by_this_transformation)) { + pair.second(), ir_context, &ids_used_by_this_transformation)) { return false; } } @@ -123,8 +123,8 @@ bool TransformationAddFunction::IsApplicable( // is taken here. // We first clone the current module, so that we can try adding the new - // function without risking wrecking |context|. - auto cloned_module = fuzzerutil::CloneIRContext(context); + // function without risking wrecking |ir_context|. + auto cloned_module = fuzzerutil::CloneIRContext(ir_context); // We try to add a function to the cloned module, which may fail if // |message_.instruction| is not sufficiently well-formed. @@ -134,12 +134,14 @@ bool TransformationAddFunction::IsApplicable( // Check whether the cloned module is still valid after adding the function. // If it is not, the transformation is not applicable. - if (!fuzzerutil::IsValid(cloned_module.get())) { + if (!fuzzerutil::IsValid(cloned_module.get(), + transformation_context.GetValidatorOptions())) { return false; } if (message_.is_livesafe()) { - if (!TryToMakeFunctionLivesafe(cloned_module.get(), fact_manager)) { + if (!TryToMakeFunctionLivesafe(cloned_module.get(), + transformation_context)) { return false; } // After making the function livesafe, we check validity of the module @@ -148,7 +150,8 @@ bool TransformationAddFunction::IsApplicable( // has the potential to make the module invalid when it was otherwise valid. // It is simpler to rely on the validator to guard against this than to // consider all scenarios when making a function livesafe. - if (!fuzzerutil::IsValid(cloned_module.get())) { + if (!fuzzerutil::IsValid(cloned_module.get(), + transformation_context.GetValidatorOptions())) { return false; } } @@ -156,10 +159,11 @@ bool TransformationAddFunction::IsApplicable( } void TransformationAddFunction::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // Add the function to the module. As the transformation is applicable, this // should succeed. - bool success = TryToAddFunction(context); + bool success = TryToAddFunction(ir_context); assert(success && "The function should be successfully added."); (void)(success); // Keep release builds happy (otherwise they may complain // that |success| is not used). @@ -172,16 +176,16 @@ void TransformationAddFunction::Apply( for (auto& instruction : message_.instruction()) { switch (instruction.opcode()) { case SpvOpFunctionParameter: - if (context->get_def_use_mgr() + if (ir_context->get_def_use_mgr() ->GetDef(instruction.result_type_id()) ->opcode() == SpvOpTypePointer) { - fact_manager->AddFactValueOfPointeeIsIrrelevant( - instruction.result_id()); + transformation_context->GetFactManager() + ->AddFactValueOfPointeeIsIrrelevant(instruction.result_id()); } break; case SpvOpVariable: - fact_manager->AddFactValueOfPointeeIsIrrelevant( - instruction.result_id()); + transformation_context->GetFactManager() + ->AddFactValueOfPointeeIsIrrelevant(instruction.result_id()); break; default: break; @@ -190,7 +194,7 @@ void TransformationAddFunction::Apply( if (message_.is_livesafe()) { // Make the function livesafe, which also should succeed. - success = TryToMakeFunctionLivesafe(context, *fact_manager); + success = TryToMakeFunctionLivesafe(ir_context, *transformation_context); assert(success && "It should be possible to make the function livesafe."); (void)(success); // Keep release builds happy. @@ -198,17 +202,18 @@ void TransformationAddFunction::Apply( assert(message_.instruction(0).opcode() == SpvOpFunction && "The first instruction of an 'add function' transformation must be " "OpFunction."); - fact_manager->AddFactFunctionIsLivesafe( + transformation_context->GetFactManager()->AddFactFunctionIsLivesafe( message_.instruction(0).result_id()); } else { // Inform the fact manager that all blocks in the function are dead. for (auto& inst : message_.instruction()) { if (inst.opcode() == SpvOpLabel) { - fact_manager->AddFactBlockIsDead(inst.result_id()); + transformation_context->GetFactManager()->AddFactBlockIsDead( + inst.result_id()); } } } - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationAddFunction::ToMessage() const { @@ -218,9 +223,9 @@ protobufs::Transformation TransformationAddFunction::ToMessage() const { } bool TransformationAddFunction::TryToAddFunction( - opt::IRContext* context) const { + opt::IRContext* ir_context) const { // This function returns false if |message_.instruction| was not well-formed - // enough to actually create a function and add it to |context|. + // enough to actually create a function and add it to |ir_context|. // A function must have at least some instructions. if (message_.instruction().empty()) { @@ -235,7 +240,7 @@ bool TransformationAddFunction::TryToAddFunction( // Make a function, headed by the OpFunction instruction. std::unique_ptr new_function = MakeUnique( - InstructionFromMessage(context, function_begin)); + InstructionFromMessage(ir_context, function_begin)); // Keeps track of which instruction protobuf message we are currently // considering. @@ -249,7 +254,7 @@ bool TransformationAddFunction::TryToAddFunction( message_.instruction(instruction_index).opcode() == SpvOpFunctionParameter) { new_function->AddParameter(InstructionFromMessage( - context, message_.instruction(instruction_index))); + ir_context, message_.instruction(instruction_index))); instruction_index++; } @@ -270,7 +275,7 @@ bool TransformationAddFunction::TryToAddFunction( // as its parent. std::unique_ptr block = MakeUnique(InstructionFromMessage( - context, message_.instruction(instruction_index))); + ir_context, message_.instruction(instruction_index))); block->SetParent(new_function.get()); // Consider successive instructions until we hit another label or the end @@ -281,7 +286,7 @@ bool TransformationAddFunction::TryToAddFunction( SpvOpFunctionEnd && message_.instruction(instruction_index).opcode() != SpvOpLabel) { block->AddInstruction(InstructionFromMessage( - context, message_.instruction(instruction_index))); + ir_context, message_.instruction(instruction_index))); instruction_index++; } // Add the block to the new function. @@ -295,22 +300,23 @@ bool TransformationAddFunction::TryToAddFunction( } // Set the function's final instruction, add the function to the module and // report success. - new_function->SetFunctionEnd( - InstructionFromMessage(context, message_.instruction(instruction_index))); - context->AddFunction(std::move(new_function)); + new_function->SetFunctionEnd(InstructionFromMessage( + ir_context, message_.instruction(instruction_index))); + ir_context->AddFunction(std::move(new_function)); - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); return true; } bool TransformationAddFunction::TryToMakeFunctionLivesafe( - opt::IRContext* context, const FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { assert(message_.is_livesafe() && "Precondition: is_livesafe must hold."); // Get a pointer to the added function. opt::Function* added_function = nullptr; - for (auto& function : *context->module()) { + for (auto& function : *ir_context->module()) { if (function.result_id() == message_.instruction(0).result_id()) { added_function = &function; break; @@ -318,7 +324,7 @@ bool TransformationAddFunction::TryToMakeFunctionLivesafe( } assert(added_function && "The added function should have been found."); - if (!TryToAddLoopLimiters(context, added_function)) { + if (!TryToAddLoopLimiters(ir_context, added_function)) { // Adding loop limiters did not work; bail out. return false; } @@ -332,20 +338,20 @@ bool TransformationAddFunction::TryToMakeFunctionLivesafe( switch (inst.opcode()) { case SpvOpKill: case SpvOpUnreachable: - if (!TryToTurnKillOrUnreachableIntoReturn(context, added_function, + if (!TryToTurnKillOrUnreachableIntoReturn(ir_context, added_function, &inst)) { return false; } break; case SpvOpAccessChain: case SpvOpInBoundsAccessChain: - if (!TryToClampAccessChainIndices(context, &inst)) { + if (!TryToClampAccessChainIndices(ir_context, &inst)) { return false; } break; case SpvOpFunctionCall: // A livesafe function my only call other livesafe functions. - if (!fact_manager.FunctionIsLivesafe( + if (!transformation_context.GetFactManager()->FunctionIsLivesafe( inst.GetSingleWordInOperand(0))) { return false; } @@ -358,7 +364,7 @@ bool TransformationAddFunction::TryToMakeFunctionLivesafe( } bool TransformationAddFunction::TryToAddLoopLimiters( - opt::IRContext* context, opt::Function* added_function) const { + opt::IRContext* ir_context, opt::Function* added_function) const { // Collect up all the loop headers so that we can subsequently add loop // limiting logic. std::vector loop_headers; @@ -377,7 +383,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // manipulating a loop limiter. auto loop_limit_constant_id_instr = - context->get_def_use_mgr()->GetDef(message_.loop_limit_constant_id()); + ir_context->get_def_use_mgr()->GetDef(message_.loop_limit_constant_id()); if (!loop_limit_constant_id_instr || loop_limit_constant_id_instr->opcode() != SpvOpConstant) { // The loop limit constant id instruction must exist and have an @@ -385,7 +391,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( return false; } - auto loop_limit_type = context->get_def_use_mgr()->GetDef( + auto loop_limit_type = ir_context->get_def_use_mgr()->GetDef( loop_limit_constant_id_instr->type_id()); if (loop_limit_type->opcode() != SpvOpTypeInt || loop_limit_type->GetSingleWordInOperand(0) != 32) { @@ -397,36 +403,36 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Find the id of the "unsigned int" type. opt::analysis::Integer unsigned_int_type(32, false); uint32_t unsigned_int_type_id = - context->get_type_mgr()->GetId(&unsigned_int_type); + ir_context->get_type_mgr()->GetId(&unsigned_int_type); if (!unsigned_int_type_id) { // Unsigned int is not available; we need this type in order to add loop // limiters. return false; } auto registered_unsigned_int_type = - context->get_type_mgr()->GetRegisteredType(&unsigned_int_type); + ir_context->get_type_mgr()->GetRegisteredType(&unsigned_int_type); // Look for 0 of type unsigned int. opt::analysis::IntConstant zero(registered_unsigned_int_type->AsInteger(), {0}); - auto registered_zero = context->get_constant_mgr()->FindConstant(&zero); + auto registered_zero = ir_context->get_constant_mgr()->FindConstant(&zero); if (!registered_zero) { // We need 0 in order to be able to initialize loop limiters. return false; } - uint32_t zero_id = context->get_constant_mgr() + uint32_t zero_id = ir_context->get_constant_mgr() ->GetDefiningInstruction(registered_zero) ->result_id(); // Look for 1 of type unsigned int. opt::analysis::IntConstant one(registered_unsigned_int_type->AsInteger(), {1}); - auto registered_one = context->get_constant_mgr()->FindConstant(&one); + auto registered_one = ir_context->get_constant_mgr()->FindConstant(&one); if (!registered_one) { // We need 1 in order to be able to increment loop limiters. return false; } - uint32_t one_id = context->get_constant_mgr() + uint32_t one_id = ir_context->get_constant_mgr() ->GetDefiningInstruction(registered_one) ->result_id(); @@ -434,7 +440,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( opt::analysis::Pointer pointer_to_unsigned_int_type( registered_unsigned_int_type, SpvStorageClassFunction); uint32_t pointer_to_unsigned_int_type_id = - context->get_type_mgr()->GetId(&pointer_to_unsigned_int_type); + ir_context->get_type_mgr()->GetId(&pointer_to_unsigned_int_type); if (!pointer_to_unsigned_int_type_id) { // We need pointer-to-unsigned int in order to declare the loop limiter // variable. @@ -443,7 +449,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Look for bool type. opt::analysis::Bool bool_type; - uint32_t bool_type_id = context->get_type_mgr()->GetId(&bool_type); + uint32_t bool_type_id = ir_context->get_type_mgr()->GetId(&bool_type); if (!bool_type_id) { // We need bool in order to compare the loop limiter's value with the loop // limit constant. @@ -454,22 +460,23 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // block, via an instruction of the form: // %loop_limiter_var = SpvOpVariable %ptr_to_uint Function %zero added_function->begin()->begin()->InsertBefore(MakeUnique( - context, SpvOpVariable, pointer_to_unsigned_int_type_id, + ir_context, SpvOpVariable, pointer_to_unsigned_int_type_id, message_.loop_limiter_variable_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, {SPV_OPERAND_TYPE_ID, {zero_id}}}))); // Update the module's id bound since we have added the loop limiter // variable id. - fuzzerutil::UpdateModuleIdBound(context, message_.loop_limiter_variable_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, + message_.loop_limiter_variable_id()); // Consider each loop in turn. for (auto loop_header : loop_headers) { // Look for the loop's back-edge block. This is a predecessor of the loop // header that is dominated by the loop header. uint32_t back_edge_block_id = 0; - for (auto pred : context->cfg()->preds(loop_header->id())) { - if (context->GetDominatorAnalysis(added_function) + for (auto pred : ir_context->cfg()->preds(loop_header->id())) { + if (ir_context->GetDominatorAnalysis(added_function) ->Dominates(loop_header->id(), pred)) { back_edge_block_id = pred; break; @@ -481,7 +488,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // move on from this loop. continue; } - auto back_edge_block = context->cfg()->block(back_edge_block_id); + auto back_edge_block = ir_context->cfg()->block(back_edge_block_id); // Go through the sequence of loop limiter infos and find the one // corresponding to this loop. @@ -579,14 +586,15 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Add a load from the loop limiter variable, of the form: // %t1 = OpLoad %uint32 %loop_limiter new_instructions.push_back(MakeUnique( - context, SpvOpLoad, unsigned_int_type_id, loop_limiter_info.load_id(), + ir_context, SpvOpLoad, unsigned_int_type_id, + loop_limiter_info.load_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}}}))); // Increment the loaded value: // %t2 = OpIAdd %uint32 %t1 %one new_instructions.push_back(MakeUnique( - context, SpvOpIAdd, unsigned_int_type_id, + ir_context, SpvOpIAdd, unsigned_int_type_id, loop_limiter_info.increment_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {loop_limiter_info.load_id()}}, @@ -595,7 +603,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Store the incremented value back to the loop limiter variable: // OpStore %loop_limiter %t2 new_instructions.push_back(MakeUnique( - context, SpvOpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}}, {SPV_OPERAND_TYPE_ID, {loop_limiter_info.increment_id()}}}))); @@ -605,7 +613,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // or // %t3 = OpULessThan %bool %t1 %loop_limit new_instructions.push_back(MakeUnique( - context, + ir_context, compare_using_greater_than_equal ? SpvOpUGreaterThanEqual : SpvOpULessThan, bool_type_id, loop_limiter_info.compare_id(), @@ -615,7 +623,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( if (back_edge_block_terminator->opcode() == SpvOpBranchConditional) { new_instructions.push_back(MakeUnique( - context, + ir_context, compare_using_greater_than_equal ? SpvOpLogicalOr : SpvOpLogicalAnd, bool_type_id, loop_limiter_info.logical_op_id(), opt::Instruction::OperandList( @@ -644,8 +652,9 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Check that, if the merge block starts with OpPhi instructions, suitable // ids have been provided to give these instructions a value corresponding // to the new incoming edge from the back edge block. - auto merge_block = context->cfg()->block(loop_header->MergeBlockId()); - if (!fuzzerutil::PhiIdsOkForNewEdge(context, back_edge_block, merge_block, + auto merge_block = ir_context->cfg()->block(loop_header->MergeBlockId()); + if (!fuzzerutil::PhiIdsOkForNewEdge(ir_context, back_edge_block, + merge_block, loop_limiter_info.phi_id())) { return false; } @@ -681,16 +690,18 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Update the module's id bound with respect to the various ids that // have been used for loop limiter manipulation. - fuzzerutil::UpdateModuleIdBound(context, loop_limiter_info.load_id()); - fuzzerutil::UpdateModuleIdBound(context, loop_limiter_info.increment_id()); - fuzzerutil::UpdateModuleIdBound(context, loop_limiter_info.compare_id()); - fuzzerutil::UpdateModuleIdBound(context, loop_limiter_info.logical_op_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, loop_limiter_info.load_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, + loop_limiter_info.increment_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, loop_limiter_info.compare_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, + loop_limiter_info.logical_op_id()); } return true; } bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( - opt::IRContext* context, opt::Function* added_function, + opt::IRContext* ir_context, opt::Function* added_function, opt::Instruction* kill_or_unreachable_inst) const { assert((kill_or_unreachable_inst->opcode() == SpvOpKill || kill_or_unreachable_inst->opcode() == SpvOpUnreachable) && @@ -698,7 +709,7 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( // Get the function's return type. auto function_return_type_inst = - context->get_def_use_mgr()->GetDef(added_function->type_id()); + ir_context->get_def_use_mgr()->GetDef(added_function->type_id()); if (function_return_type_inst->opcode() == SpvOpTypeVoid) { // The function has void return type, so change this instruction to @@ -712,7 +723,7 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( // We first check that the id, %id, provided with the transformation // specifically to turn OpKill and OpUnreachable instructions into // OpReturnValue %id has the same type as the function's return type. - if (context->get_def_use_mgr() + if (ir_context->get_def_use_mgr() ->GetDef(message_.kill_unreachable_return_value_id()) ->type_id() != function_return_type_inst->result_id()) { return false; @@ -725,7 +736,7 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( } bool TransformationAddFunction::TryToClampAccessChainIndices( - opt::IRContext* context, opt::Instruction* access_chain_inst) const { + opt::IRContext* ir_context, opt::Instruction* access_chain_inst) const { assert((access_chain_inst->opcode() == SpvOpAccessChain || access_chain_inst->opcode() == SpvOpInBoundsAccessChain) && "Precondition: instruction must be OpAccessChain or " @@ -756,14 +767,14 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Walk the access chain, clamping each index to be within bounds if it is // not a constant. - auto base_object = context->get_def_use_mgr()->GetDef( + auto base_object = ir_context->get_def_use_mgr()->GetDef( access_chain_inst->GetSingleWordInOperand(0)); assert(base_object && "The base object must exist."); auto pointer_type = - context->get_def_use_mgr()->GetDef(base_object->type_id()); + ir_context->get_def_use_mgr()->GetDef(base_object->type_id()); assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer && "The base object must have pointer type."); - auto should_be_composite_type = context->get_def_use_mgr()->GetDef( + auto should_be_composite_type = ir_context->get_def_use_mgr()->GetDef( pointer_type->GetSingleWordInOperand(1)); // Consider each index input operand in turn (operand 0 is the base object). @@ -784,18 +795,18 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Get the bound for the composite being indexed into; e.g. the number of // columns of matrix or the size of an array. uint32_t bound = - GetBoundForCompositeIndex(context, *should_be_composite_type); + GetBoundForCompositeIndex(ir_context, *should_be_composite_type); // Get the instruction associated with the index and figure out its integer // type. const uint32_t index_id = access_chain_inst->GetSingleWordInOperand(index); - auto index_inst = context->get_def_use_mgr()->GetDef(index_id); + auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id); auto index_type_inst = - context->get_def_use_mgr()->GetDef(index_inst->type_id()); + ir_context->get_def_use_mgr()->GetDef(index_inst->type_id()); assert(index_type_inst->opcode() == SpvOpTypeInt); assert(index_type_inst->GetSingleWordInOperand(0) == 32); opt::analysis::Integer* index_int_type = - context->get_type_mgr() + ir_context->get_type_mgr() ->GetType(index_type_inst->result_id()) ->AsInteger(); @@ -805,20 +816,20 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( "Access chain indices into structures are required to be " "constants."); opt::analysis::IntConstant bound_minus_one(index_int_type, {bound - 1}); - if (!context->get_constant_mgr()->FindConstant(&bound_minus_one)) { + if (!ir_context->get_constant_mgr()->FindConstant(&bound_minus_one)) { // We do not have an integer constant whose value is |bound| -1. return false; } opt::analysis::Bool bool_type; - uint32_t bool_type_id = context->get_type_mgr()->GetId(&bool_type); + uint32_t bool_type_id = ir_context->get_type_mgr()->GetId(&bool_type); if (!bool_type_id) { // Bool type is not declared; we cannot do a comparison. return false; } uint32_t bound_minus_one_id = - context->get_constant_mgr() + ir_context->get_constant_mgr() ->GetDefiningInstruction(&bound_minus_one) ->result_id(); @@ -832,7 +843,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Compare the index with the bound via an instruction of the form: // %t1 = OpULessThanEqual %bool %index %bound_minus_one new_instructions.push_back(MakeUnique( - context, SpvOpULessThanEqual, bool_type_id, compare_id, + ir_context, SpvOpULessThanEqual, bool_type_id, compare_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {index_inst->result_id()}}, {SPV_OPERAND_TYPE_ID, {bound_minus_one_id}}}))); @@ -840,7 +851,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Select the index if in-bounds, otherwise one less than the bound: // %t2 = OpSelect %int_type %t1 %index %bound_minus_one new_instructions.push_back(MakeUnique( - context, SpvOpSelect, index_type_inst->result_id(), select_id, + ir_context, SpvOpSelect, index_type_inst->result_id(), select_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {compare_id}}, {SPV_OPERAND_TYPE_ID, {index_inst->result_id()}}, @@ -851,8 +862,8 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Replace %index with %t2. access_chain_inst->SetInOperand(index, {select_id}); - fuzzerutil::UpdateModuleIdBound(context, compare_id); - fuzzerutil::UpdateModuleIdBound(context, select_id); + fuzzerutil::UpdateModuleIdBound(ir_context, compare_id); + fuzzerutil::UpdateModuleIdBound(ir_context, select_id); } else { // TODO(afd): At present the SPIR-V spec is not clear on whether // statically out-of-bounds indices mean that a module is invalid (so @@ -870,16 +881,16 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( } } should_be_composite_type = - FollowCompositeIndex(context, *should_be_composite_type, index_id); + FollowCompositeIndex(ir_context, *should_be_composite_type, index_id); } return true; } uint32_t TransformationAddFunction::GetBoundForCompositeIndex( - opt::IRContext* context, const opt::Instruction& composite_type_inst) { + opt::IRContext* ir_context, const opt::Instruction& composite_type_inst) { switch (composite_type_inst.opcode()) { case SpvOpTypeArray: - return fuzzerutil::GetArraySize(composite_type_inst, context); + return fuzzerutil::GetArraySize(composite_type_inst, ir_context); case SpvOpTypeMatrix: case SpvOpTypeVector: return composite_type_inst.GetSingleWordInOperand(1); @@ -893,7 +904,7 @@ uint32_t TransformationAddFunction::GetBoundForCompositeIndex( } opt::Instruction* TransformationAddFunction::FollowCompositeIndex( - opt::IRContext* context, const opt::Instruction& composite_type_inst, + opt::IRContext* ir_context, const opt::Instruction& composite_type_inst, uint32_t index_id) { uint32_t sub_object_type_id; switch (composite_type_inst.opcode()) { @@ -905,12 +916,12 @@ opt::Instruction* TransformationAddFunction::FollowCompositeIndex( sub_object_type_id = composite_type_inst.GetSingleWordInOperand(0); break; case SpvOpTypeStruct: { - auto index_inst = context->get_def_use_mgr()->GetDef(index_id); + auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id); assert(index_inst->opcode() == SpvOpConstant); - assert( - context->get_def_use_mgr()->GetDef(index_inst->type_id())->opcode() == - SpvOpTypeInt); - assert(context->get_def_use_mgr() + assert(ir_context->get_def_use_mgr() + ->GetDef(index_inst->type_id()) + ->opcode() == SpvOpTypeInt); + assert(ir_context->get_def_use_mgr() ->GetDef(index_inst->type_id()) ->GetSingleWordInOperand(0) == 32); uint32_t index_value = index_inst->GetSingleWordInOperand(0); @@ -924,7 +935,7 @@ opt::Instruction* TransformationAddFunction::FollowCompositeIndex( break; } assert(sub_object_type_id && "No sub-object found."); - return context->get_def_use_mgr()->GetDef(sub_object_type_id); + return ir_context->get_def_use_mgr()->GetDef(sub_object_type_id); } } // namespace fuzz diff --git a/source/fuzz/transformation_add_function.h b/source/fuzz/transformation_add_function.h index 848b799f..5af197b6 100644 --- a/source/fuzz/transformation_add_function.h +++ b/source/fuzz/transformation_add_function.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_FUNCTION_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_FUNCTION_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -47,12 +47,14 @@ class TransformationAddFunction : public Transformation { // ingredients to make the function livesafe, and the function must only // invoke other livesafe functions // - Adding the created function to the module must lead to a valid module. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds the function defined by |message_.instruction| to the module, making // it livesafe if |message_.is_livesafe| holds. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -61,26 +63,26 @@ class TransformationAddFunction : public Transformation { // an array, the number of components of a vector, or the number of columns of // a matrix. static uint32_t GetBoundForCompositeIndex( - opt::IRContext* context, const opt::Instruction& composite_type_inst); + opt::IRContext* ir_context, const opt::Instruction& composite_type_inst); // Helper method that, given composite type |composite_type_inst|, returns the // type of the sub-object at index |index_id|, which is required to be in- // bounds. static opt::Instruction* FollowCompositeIndex( - opt::IRContext* context, const opt::Instruction& composite_type_inst, + opt::IRContext* ir_context, const opt::Instruction& composite_type_inst, uint32_t index_id); private: // Attempts to create a function from the series of instructions in - // |message_.instruction| and add it to |context|. + // |message_.instruction| and add it to |ir_context|. // // Returns false if adding the function is not possible due to the messages // not respecting the basic structure of a function, e.g. if there is no - // OpFunction instruction or no blocks; in this case |context| is left in an - // indeterminate state. + // OpFunction instruction or no blocks; in this case |ir_context| is left in + // an indeterminate state. // - // Otherwise returns true. Whether |context| is valid after addition of the - // function depends on the contents of |message_.instruction|. + // Otherwise returns true. Whether |ir_context| is valid after addition of + // the function depends on the contents of |message_.instruction|. // // Intended usage: // - Perform a dry run of this method on a clone of a module, and use @@ -89,30 +91,31 @@ class TransformationAddFunction : public Transformation { // added, or leads to an invalid module. // - If the dry run succeeds, run the method on the real module of interest, // to add the function. - bool TryToAddFunction(opt::IRContext* context) const; + bool TryToAddFunction(opt::IRContext* ir_context) const; // Should only be called if |message_.is_livesafe| holds. Attempts to make // the function livesafe (see FactFunctionIsLivesafe for a definition). - // Returns false if this is not possible, due to |message_| or |context| not - // containing sufficient ingredients (such as types and fresh ids) to add + // Returns false if this is not possible, due to |message_| or |ir_context| + // not containing sufficient ingredients (such as types and fresh ids) to add // the instrumentation necessary to make the function livesafe. - bool TryToMakeFunctionLivesafe(opt::IRContext* context, - const FactManager& fact_manager) const; + bool TryToMakeFunctionLivesafe( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const; // A helper for TryToMakeFunctionLivesafe that tries to add loop-limiting // logic. - bool TryToAddLoopLimiters(opt::IRContext* context, + bool TryToAddLoopLimiters(opt::IRContext* ir_context, opt::Function* added_function) const; // A helper for TryToMakeFunctionLivesafe that tries to replace OpKill and // OpUnreachable instructions into return instructions. bool TryToTurnKillOrUnreachableIntoReturn( - opt::IRContext* context, opt::Function* added_function, + opt::IRContext* ir_context, opt::Function* added_function, opt::Instruction* kill_or_unreachable_inst) const; // A helper for TryToMakeFunctionLivesafe that tries to clamp access chain // indices so that they are guaranteed to be in-bounds. - bool TryToClampAccessChainIndices(opt::IRContext* context, + bool TryToClampAccessChainIndices(opt::IRContext* ir_context, opt::Instruction* access_chain_inst) const; protobufs::TransformationAddFunction message_; diff --git a/source/fuzz/transformation_add_global_undef.cpp b/source/fuzz/transformation_add_global_undef.cpp index f9585b3b..ba45f220 100644 --- a/source/fuzz/transformation_add_global_undef.cpp +++ b/source/fuzz/transformation_add_global_undef.cpp @@ -30,26 +30,26 @@ TransformationAddGlobalUndef::TransformationAddGlobalUndef(uint32_t fresh_id, } bool TransformationAddGlobalUndef::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // A fresh id is required. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } - auto type = context->get_type_mgr()->GetType(message_.type_id()); + auto type = ir_context->get_type_mgr()->GetType(message_.type_id()); // The type must exist, and must not be a function type. return type && !type->AsFunction(); } void TransformationAddGlobalUndef::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { - context->module()->AddGlobalValue(MakeUnique( - context, SpvOpUndef, message_.type_id(), message_.fresh_id(), + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { + ir_context->module()->AddGlobalValue(MakeUnique( + ir_context, SpvOpUndef, message_.type_id(), message_.fresh_id(), opt::Instruction::OperandList())); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddGlobalUndef::ToMessage() const { diff --git a/source/fuzz/transformation_add_global_undef.h b/source/fuzz/transformation_add_global_undef.h index 550d9f68..c89fe9d5 100644 --- a/source/fuzz/transformation_add_global_undef.h +++ b/source/fuzz/transformation_add_global_undef.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_GLOBAL_UNDEF_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_GLOBAL_UNDEF_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -32,12 +32,14 @@ class TransformationAddGlobalUndef : public Transformation { // - |message_.fresh_id| must be fresh // - |message_.type_id| must be the id of a non-function type - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpUndef instruction to the module, with |message_.type_id| as its // type. The instruction has result id |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_global_variable.cpp b/source/fuzz/transformation_add_global_variable.cpp index e4f9f7ad..c0164280 100644 --- a/source/fuzz/transformation_add_global_variable.cpp +++ b/source/fuzz/transformation_add_global_variable.cpp @@ -33,14 +33,13 @@ TransformationAddGlobalVariable::TransformationAddGlobalVariable( } bool TransformationAddGlobalVariable::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The type id must correspond to a type. - auto type = context->get_type_mgr()->GetType(message_.type_id()); + auto type = ir_context->get_type_mgr()->GetType(message_.type_id()); if (!type) { return false; } @@ -55,7 +54,7 @@ bool TransformationAddGlobalVariable::IsApplicable( } // The initializer id must be the id of a constant. Check this with the // constant manager. - auto constant_id = context->get_constant_mgr()->GetConstantsFromIds( + auto constant_id = ir_context->get_constant_mgr()->GetConstantsFromIds( {message_.initializer_id()}); if (constant_id.empty()) { return false; @@ -71,7 +70,8 @@ bool TransformationAddGlobalVariable::IsApplicable( } void TransformationAddGlobalVariable::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { opt::Instruction::OperandList input_operands; input_operands.push_back( {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassPrivate}}); @@ -79,12 +79,12 @@ void TransformationAddGlobalVariable::Apply( input_operands.push_back( {SPV_OPERAND_TYPE_ID, {message_.initializer_id()}}); } - context->module()->AddGlobalValue( - MakeUnique(context, SpvOpVariable, message_.type_id(), - message_.fresh_id(), input_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddGlobalValue(MakeUnique( + ir_context, SpvOpVariable, message_.type_id(), message_.fresh_id(), + input_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); - if (PrivateGlobalsMustBeDeclaredInEntryPointInterfaces(context)) { + if (PrivateGlobalsMustBeDeclaredInEntryPointInterfaces(ir_context)) { // Conservatively add this global to the interface of every entry point in // the module. This means that the global is available for other // transformations to use. @@ -94,18 +94,20 @@ void TransformationAddGlobalVariable::Apply( // // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3111) revisit // this if a more thorough approach to entry point interfaces is taken. - for (auto& entry_point : context->module()->entry_points()) { + for (auto& entry_point : ir_context->module()->entry_points()) { entry_point.AddOperand({SPV_OPERAND_TYPE_ID, {message_.fresh_id()}}); } } if (message_.value_is_irrelevant()) { - fact_manager->AddFactValueOfPointeeIsIrrelevant(message_.fresh_id()); + transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + message_.fresh_id()); } // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddGlobalVariable::ToMessage() const { @@ -116,11 +118,11 @@ protobufs::Transformation TransformationAddGlobalVariable::ToMessage() const { bool TransformationAddGlobalVariable:: PrivateGlobalsMustBeDeclaredInEntryPointInterfaces( - opt::IRContext* context) { + opt::IRContext* ir_context) { // TODO(afd): We capture the universal environments for which this requirement // holds. The check should be refined on demand for other target // environments. - switch (context->grammar().target_env()) { + switch (ir_context->grammar().target_env()) { case SPV_ENV_UNIVERSAL_1_0: case SPV_ENV_UNIVERSAL_1_1: case SPV_ENV_UNIVERSAL_1_2: diff --git a/source/fuzz/transformation_add_global_variable.h b/source/fuzz/transformation_add_global_variable.h index 920ac45d..f28af445 100644 --- a/source/fuzz/transformation_add_global_variable.h +++ b/source/fuzz/transformation_add_global_variable.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_GLOBAL_VARIABLE_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_GLOBAL_VARIABLE_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -37,23 +37,25 @@ class TransformationAddGlobalVariable : public Transformation { // class // - |message_.initializer_id| must either be 0 or the id of a constant whose // type is the pointee type of |message_.type_id| - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds a global variable with Private storage class to the module, with type // |message_.type_id| and either no initializer or |message_.initializer_id| // as an initializer, depending on whether |message_.initializer_id| is 0. // The global variable has result id |message_.fresh_id|. // - // If |message_.value_is_irrelevant| holds, adds a corresponding fact to - // |fact_manager|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + // If |message_.value_is_irrelevant| holds, adds a corresponding fact to the + // fact manager in |transformation_context|. + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; private: static bool PrivateGlobalsMustBeDeclaredInEntryPointInterfaces( - opt::IRContext* context); + opt::IRContext* ir_context); protobufs::TransformationAddGlobalVariable message_; }; diff --git a/source/fuzz/transformation_add_local_variable.cpp b/source/fuzz/transformation_add_local_variable.cpp index 69e536df..51362495 100644 --- a/source/fuzz/transformation_add_local_variable.cpp +++ b/source/fuzz/transformation_add_local_variable.cpp @@ -34,23 +34,22 @@ TransformationAddLocalVariable::TransformationAddLocalVariable( } bool TransformationAddLocalVariable::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The provided id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The pointer type id must indeed correspond to a pointer, and it must have // function storage class. auto type_instruction = - context->get_def_use_mgr()->GetDef(message_.type_id()); + ir_context->get_def_use_mgr()->GetDef(message_.type_id()); if (!type_instruction || type_instruction->opcode() != SpvOpTypePointer || type_instruction->GetSingleWordInOperand(0) != SpvStorageClassFunction) { return false; } // The initializer must... auto initializer_instruction = - context->get_def_use_mgr()->GetDef(message_.initializer_id()); + ir_context->get_def_use_mgr()->GetDef(message_.initializer_id()); // ... exist, ... if (!initializer_instruction) { return false; @@ -65,17 +64,18 @@ bool TransformationAddLocalVariable::IsApplicable( return false; } // The function to which the local variable is to be added must exist. - return fuzzerutil::FindFunction(context, message_.function_id()); + return fuzzerutil::FindFunction(ir_context, message_.function_id()); } void TransformationAddLocalVariable::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - fuzzerutil::FindFunction(context, message_.function_id()) + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + fuzzerutil::FindFunction(ir_context, message_.function_id()) ->begin() ->begin() ->InsertBefore(MakeUnique( - context, SpvOpVariable, message_.type_id(), message_.fresh_id(), + ir_context, SpvOpVariable, message_.type_id(), message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_STORAGE_CLASS, { @@ -83,9 +83,10 @@ void TransformationAddLocalVariable::Apply( SpvStorageClassFunction}}, {SPV_OPERAND_TYPE_ID, {message_.initializer_id()}}}))); if (message_.value_is_irrelevant()) { - fact_manager->AddFactValueOfPointeeIsIrrelevant(message_.fresh_id()); + transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + message_.fresh_id()); } - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationAddLocalVariable::ToMessage() const { diff --git a/source/fuzz/transformation_add_local_variable.h b/source/fuzz/transformation_add_local_variable.h index b8e00ddf..64609041 100644 --- a/source/fuzz/transformation_add_local_variable.h +++ b/source/fuzz/transformation_add_local_variable.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_LOCAL_VARIABLE_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_LOCAL_VARIABLE_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -38,15 +38,17 @@ class TransformationAddLocalVariable : public Transformation { // - |message_.initializer_id| must be the id of a constant with the same // type as the pointer's pointee type // - |message_.function_id| must be the id of a function - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction to the start of |message_.function_id|, of the form: // |message_.fresh_id| = OpVariable |message_.type_id| Function // |message_.initializer_id| - // If |message_.value_is_irrelevant| holds, adds a corresponding fact to - // |fact_manager|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + // If |message_.value_is_irrelevant| holds, adds a corresponding fact to the + // fact manager in |transformation_context|. + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_no_contraction_decoration.cpp b/source/fuzz/transformation_add_no_contraction_decoration.cpp index 7f22cc22..4668534b 100644 --- a/source/fuzz/transformation_add_no_contraction_decoration.cpp +++ b/source/fuzz/transformation_add_no_contraction_decoration.cpp @@ -31,10 +31,9 @@ TransformationAddNoContractionDecoration:: } bool TransformationAddNoContractionDecoration::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // |message_.result_id| must be the id of an instruction. - auto instr = context->get_def_use_mgr()->GetDef(message_.result_id()); + auto instr = ir_context->get_def_use_mgr()->GetDef(message_.result_id()); if (!instr) { return false; } @@ -43,10 +42,10 @@ bool TransformationAddNoContractionDecoration::IsApplicable( } void TransformationAddNoContractionDecoration::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Add a NoContraction decoration targeting |message_.result_id|. - context->get_decoration_mgr()->AddDecoration(message_.result_id(), - SpvDecorationNoContraction); + ir_context->get_decoration_mgr()->AddDecoration(message_.result_id(), + SpvDecorationNoContraction); } protobufs::Transformation TransformationAddNoContractionDecoration::ToMessage() diff --git a/source/fuzz/transformation_add_no_contraction_decoration.h b/source/fuzz/transformation_add_no_contraction_decoration.h index cec1b2cd..27c3a802 100644 --- a/source/fuzz/transformation_add_no_contraction_decoration.h +++ b/source/fuzz/transformation_add_no_contraction_decoration.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_NO_CONTRACTION_DECORATION_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_NO_CONTRACTION_DECORATION_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -34,13 +34,15 @@ class TransformationAddNoContractionDecoration : public Transformation { // as defined by the SPIR-V specification. // - It does not matter whether this instruction is already annotated with the // NoContraction decoration. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds a decoration of the form: // 'OpDecoration |message_.result_id| NoContraction' // to the module. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_array.cpp b/source/fuzz/transformation_add_type_array.cpp index 2074e98a..8f5af07f 100644 --- a/source/fuzz/transformation_add_type_array.cpp +++ b/source/fuzz/transformation_add_type_array.cpp @@ -32,21 +32,20 @@ TransformationAddTypeArray::TransformationAddTypeArray(uint32_t fresh_id, } bool TransformationAddTypeArray::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // A fresh id is required. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } auto element_type = - context->get_type_mgr()->GetType(message_.element_type_id()); + ir_context->get_type_mgr()->GetType(message_.element_type_id()); if (!element_type || element_type->AsFunction()) { // The element type id either does not refer to a type, or refers to a // function type; both are illegal. return false; } auto constant = - context->get_constant_mgr()->GetConstantsFromIds({message_.size_id()}); + ir_context->get_constant_mgr()->GetConstantsFromIds({message_.size_id()}); if (constant.empty()) { // The size id does not refer to a constant. return false; @@ -66,16 +65,17 @@ bool TransformationAddTypeArray::IsApplicable( } void TransformationAddTypeArray::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.element_type_id()}}); in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.size_id()}}); - context->module()->AddType(MakeUnique( - context, SpvOpTypeArray, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeArray, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeArray::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_array.h b/source/fuzz/transformation_add_type_array.h index b6e07182..5e9b8aaf 100644 --- a/source/fuzz/transformation_add_type_array.h +++ b/source/fuzz/transformation_add_type_array.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_ARRAY_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_ARRAY_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -35,13 +35,15 @@ class TransformationAddTypeArray : public Transformation { // - |message_.element_type_id| must be the id of a non-function type // - |message_.size_id| must be the id of a 32-bit integer constant that is // positive when interpreted as signed. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeArray instruction to the module, with element type given by // |message_.element_type_id| and size given by |message_.size_id|. The // result id of the instruction is |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_boolean.cpp b/source/fuzz/transformation_add_type_boolean.cpp index b55028a6..77409a8c 100644 --- a/source/fuzz/transformation_add_type_boolean.cpp +++ b/source/fuzz/transformation_add_type_boolean.cpp @@ -28,27 +28,27 @@ TransformationAddTypeBoolean::TransformationAddTypeBoolean(uint32_t fresh_id) { } bool TransformationAddTypeBoolean::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // Applicable if there is no bool type already declared in the module. opt::analysis::Bool bool_type; - return context->get_type_mgr()->GetId(&bool_type) == 0; + return ir_context->get_type_mgr()->GetId(&bool_type) == 0; } void TransformationAddTypeBoolean::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList empty_operands; - context->module()->AddType(MakeUnique( - context, SpvOpTypeBool, 0, message_.fresh_id(), empty_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeBool, 0, message_.fresh_id(), empty_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeBoolean::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_boolean.h b/source/fuzz/transformation_add_type_boolean.h index 98c1e639..5ce5b9a4 100644 --- a/source/fuzz/transformation_add_type_boolean.h +++ b/source/fuzz/transformation_add_type_boolean.h @@ -15,7 +15,6 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_BOOLEAN_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_BOOLEAN_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" #include "source/opt/ir_context.h" @@ -32,11 +31,13 @@ class TransformationAddTypeBoolean : public Transformation { // - |message_.fresh_id| must not be used by the module. // - The module must not yet declare OpTypeBoolean - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds OpTypeBoolean with |message_.fresh_id| as result id. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_float.cpp b/source/fuzz/transformation_add_type_float.cpp index d2af5f88..80716e14 100644 --- a/source/fuzz/transformation_add_type_float.cpp +++ b/source/fuzz/transformation_add_type_float.cpp @@ -30,29 +30,29 @@ TransformationAddTypeFloat::TransformationAddTypeFloat( : message_(message) {} bool TransformationAddTypeFloat::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // Applicable if there is no float type with this width already declared in // the module. opt::analysis::Float float_type(message_.width()); - return context->get_type_mgr()->GetId(&float_type) == 0; + return ir_context->get_type_mgr()->GetId(&float_type) == 0; } void TransformationAddTypeFloat::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList width = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}}}; - context->module()->AddType(MakeUnique( - context, SpvOpTypeFloat, 0, message_.fresh_id(), width)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeFloat, 0, message_.fresh_id(), width)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeFloat::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_float.h b/source/fuzz/transformation_add_type_float.h index 0fdc8314..a8fa0e10 100644 --- a/source/fuzz/transformation_add_type_float.h +++ b/source/fuzz/transformation_add_type_float.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_FLOAT_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_FLOAT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,11 +33,13 @@ class TransformationAddTypeFloat : public Transformation { // - |message_.fresh_id| must not be used by the module // - The module must not contain an OpTypeFloat instruction with width // |message_.width| - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeFloat instruction to the module with the given width - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_function.cpp b/source/fuzz/transformation_add_type_function.cpp index 4b6717b8..991a28b0 100644 --- a/source/fuzz/transformation_add_type_function.cpp +++ b/source/fuzz/transformation_add_type_function.cpp @@ -36,19 +36,18 @@ TransformationAddTypeFunction::TransformationAddTypeFunction( } bool TransformationAddTypeFunction::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The return and argument types must be type ids but not not be function // type ids. - if (!fuzzerutil::IsNonFunctionTypeId(context, message_.return_type_id())) { + if (!fuzzerutil::IsNonFunctionTypeId(ir_context, message_.return_type_id())) { return false; } for (auto argument_type_id : message_.argument_type_id()) { - if (!fuzzerutil::IsNonFunctionTypeId(context, argument_type_id)) { + if (!fuzzerutil::IsNonFunctionTypeId(ir_context, argument_type_id)) { return false; } } @@ -56,7 +55,7 @@ bool TransformationAddTypeFunction::IsApplicable( // exactly the same return and argument type ids. (Note that the type manager // does not allow us to check this, as it does not distinguish between // function types with different but isomorphic pointer argument types.) - for (auto& inst : context->module()->types_values()) { + for (auto& inst : ir_context->module()->types_values()) { if (inst.opcode() != SpvOpTypeFunction) { // Consider only OpTypeFunction instructions. continue; @@ -89,18 +88,19 @@ bool TransformationAddTypeFunction::IsApplicable( } void TransformationAddTypeFunction::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.return_type_id()}}); for (auto argument_type_id : message_.argument_type_id()) { in_operands.push_back({SPV_OPERAND_TYPE_ID, {argument_type_id}}); } - context->module()->AddType(MakeUnique( - context, SpvOpTypeFunction, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeFunction, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeFunction::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_function.h b/source/fuzz/transformation_add_type_function.h index 3880963d..f26b2501 100644 --- a/source/fuzz/transformation_add_type_function.h +++ b/source/fuzz/transformation_add_type_function.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -39,13 +39,15 @@ class TransformationAddTypeFunction : public Transformation { // - The module must not contain an OpTypeFunction instruction defining a // function type with the signature provided by the given return and // argument types - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeFunction instruction to the module, with signature given by // |message_.return_type_id| and |message_.argument_type_id|. The result id // for the instruction is |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_int.cpp b/source/fuzz/transformation_add_type_int.cpp index 6f592709..a932a5f9 100644 --- a/source/fuzz/transformation_add_type_int.cpp +++ b/source/fuzz/transformation_add_type_int.cpp @@ -32,30 +32,30 @@ TransformationAddTypeInt::TransformationAddTypeInt(uint32_t fresh_id, } bool TransformationAddTypeInt::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // Applicable if there is no int type with this width and signedness already // declared in the module. opt::analysis::Integer int_type(message_.width(), message_.is_signed()); - return context->get_type_mgr()->GetId(&int_type) == 0; + return ir_context->get_type_mgr()->GetId(&int_type) == 0; } -void TransformationAddTypeInt::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { +void TransformationAddTypeInt::Apply(opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.is_signed() ? 1u : 0u}}}; - context->module()->AddType(MakeUnique( - context, SpvOpTypeInt, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeInt, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeInt::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_int.h b/source/fuzz/transformation_add_type_int.h index 86342d06..5c3c9591 100644 --- a/source/fuzz/transformation_add_type_int.h +++ b/source/fuzz/transformation_add_type_int.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_INT_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_INT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,12 +33,14 @@ class TransformationAddTypeInt : public Transformation { // - |message_.fresh_id| must not be used by the module // - The module must not contain an OpTypeInt instruction with width // |message_.width| and signedness |message.is_signed| - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeInt instruction to the module with the given width and // signedness. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_matrix.cpp b/source/fuzz/transformation_add_type_matrix.cpp index 07ab7054..2c24eaa0 100644 --- a/source/fuzz/transformation_add_type_matrix.cpp +++ b/source/fuzz/transformation_add_type_matrix.cpp @@ -31,15 +31,14 @@ TransformationAddTypeMatrix::TransformationAddTypeMatrix( } bool TransformationAddTypeMatrix::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The column type must be a floating-point vector. auto column_type = - context->get_type_mgr()->GetType(message_.column_type_id()); + ir_context->get_type_mgr()->GetType(message_.column_type_id()); if (!column_type) { return false; } @@ -48,17 +47,18 @@ bool TransformationAddTypeMatrix::IsApplicable( } void TransformationAddTypeMatrix::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.column_type_id()}}); in_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.column_count()}}); - context->module()->AddType(MakeUnique( - context, SpvOpTypeMatrix, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeMatrix, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeMatrix::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_matrix.h b/source/fuzz/transformation_add_type_matrix.h index 69d63890..6d0724e6 100644 --- a/source/fuzz/transformation_add_type_matrix.h +++ b/source/fuzz/transformation_add_type_matrix.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_MATRIX_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_MATRIX_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,13 +33,15 @@ class TransformationAddTypeMatrix : public Transformation { // - |message_.fresh_id| must be a fresh id // - |message_.column_type_id| must be the id of a floating-point vector type - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeMatrix instruction to the module, with column type // |message_.column_type_id| and |message_.column_count| columns, with result // id |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_pointer.cpp b/source/fuzz/transformation_add_type_pointer.cpp index 426985a3..6cc8171e 100644 --- a/source/fuzz/transformation_add_type_pointer.cpp +++ b/source/fuzz/transformation_add_type_pointer.cpp @@ -31,28 +31,29 @@ TransformationAddTypePointer::TransformationAddTypePointer( } bool TransformationAddTypePointer::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The base type must be known. - return context->get_type_mgr()->GetType(message_.base_type_id()) != nullptr; + return ir_context->get_type_mgr()->GetType(message_.base_type_id()) != + nullptr; } void TransformationAddTypePointer::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Add the pointer type. opt::Instruction::OperandList in_operands = { {SPV_OPERAND_TYPE_STORAGE_CLASS, {message_.storage_class()}}, {SPV_OPERAND_TYPE_ID, {message_.base_type_id()}}}; - context->module()->AddType(MakeUnique( - context, SpvOpTypePointer, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypePointer, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypePointer::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_pointer.h b/source/fuzz/transformation_add_type_pointer.h index 2b9ff77f..3b50a293 100644 --- a/source/fuzz/transformation_add_type_pointer.h +++ b/source/fuzz/transformation_add_type_pointer.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_POINTER_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_POINTER_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -34,12 +34,14 @@ class TransformationAddTypePointer : public Transformation { // - |message_.fresh_id| must not be used by the module // - |message_.base_type_id| must be the result id of an OpType[...] // instruction - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypePointer instruction with the given storage class and base // type to the module. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_struct.cpp b/source/fuzz/transformation_add_type_struct.cpp index 1ae83723..6ce5ea11 100644 --- a/source/fuzz/transformation_add_type_struct.cpp +++ b/source/fuzz/transformation_add_type_struct.cpp @@ -32,14 +32,13 @@ TransformationAddTypeStruct::TransformationAddTypeStruct( } bool TransformationAddTypeStruct::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // A fresh id is required. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } for (auto member_type : message_.member_type_id()) { - auto type = context->get_type_mgr()->GetType(member_type); + auto type = ir_context->get_type_mgr()->GetType(member_type); if (!type || type->AsFunction()) { // The member type id either does not refer to a type, or refers to a // function type; both are illegal. @@ -50,17 +49,18 @@ bool TransformationAddTypeStruct::IsApplicable( } void TransformationAddTypeStruct::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; for (auto member_type : message_.member_type_id()) { in_operands.push_back({SPV_OPERAND_TYPE_ID, {member_type}}); } - context->module()->AddType(MakeUnique( - context, SpvOpTypeStruct, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeStruct, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeStruct::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_struct.h b/source/fuzz/transformation_add_type_struct.h index edf3ec6e..86a532d2 100644 --- a/source/fuzz/transformation_add_type_struct.h +++ b/source/fuzz/transformation_add_type_struct.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -35,12 +35,14 @@ class TransformationAddTypeStruct : public Transformation { // - |message_.fresh_id| must be a fresh id // - |message_.member_type_id| must be a sequence of non-function type ids - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeStruct instruction whose field types are given by // |message_.member_type_id|, with result id |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_add_type_vector.cpp b/source/fuzz/transformation_add_type_vector.cpp index 3fdf50b1..f7b2fb59 100644 --- a/source/fuzz/transformation_add_type_vector.cpp +++ b/source/fuzz/transformation_add_type_vector.cpp @@ -31,13 +31,12 @@ TransformationAddTypeVector::TransformationAddTypeVector( } bool TransformationAddTypeVector::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } auto component_type = - context->get_type_mgr()->GetType(message_.component_type_id()); + ir_context->get_type_mgr()->GetType(message_.component_type_id()); if (!component_type) { return false; } @@ -46,17 +45,18 @@ bool TransformationAddTypeVector::IsApplicable( } void TransformationAddTypeVector::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList in_operands; in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.component_type_id()}}); in_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.component_count()}}); - context->module()->AddType(MakeUnique( - context, SpvOpTypeVector, 0, message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeVector, 0, message_.fresh_id(), in_operands)); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // We have added an instruction to the module, so need to be careful about the // validity of existing analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationAddTypeVector::ToMessage() const { diff --git a/source/fuzz/transformation_add_type_vector.h b/source/fuzz/transformation_add_type_vector.h index af840f5e..240f7cce 100644 --- a/source/fuzz/transformation_add_type_vector.h +++ b/source/fuzz/transformation_add_type_vector.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_VECTOR_H_ #define SOURCE_FUZZ_TRANSFORMATION_ADD_TYPE_VECTOR_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,13 +33,15 @@ class TransformationAddTypeVector : public Transformation { // - |message_.fresh_id| must be a fresh id // - |message_.component_type_id| must be the id of a scalar type - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpTypeVector instruction to the module, with component type // |message_.component_type_id| and |message_.component_count| components, // with result id |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_composite_construct.cpp b/source/fuzz/transformation_composite_construct.cpp index 9c63c1d9..cd4f22f1 100644 --- a/source/fuzz/transformation_composite_construct.cpp +++ b/source/fuzz/transformation_composite_construct.cpp @@ -40,14 +40,14 @@ TransformationCompositeConstruct::TransformationCompositeConstruct( } bool TransformationCompositeConstruct::IsApplicable( - opt::IRContext* context, const FactManager& /*fact_manager*/) const { - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { // We require the id for the composite constructor to be unused. return false; } auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!insert_before) { // The instruction before which the composite should be inserted was not // found. @@ -55,7 +55,7 @@ bool TransformationCompositeConstruct::IsApplicable( } auto composite_type = - context->get_type_mgr()->GetType(message_.composite_type_id()); + ir_context->get_type_mgr()->GetType(message_.composite_type_id()); if (!fuzzerutil::IsCompositeType(composite_type)) { // The type must actually be a composite. @@ -64,27 +64,31 @@ bool TransformationCompositeConstruct::IsApplicable( // If the type is an array, matrix, struct or vector, the components need to // be suitable for constructing something of that type. - if (composite_type->AsArray() && !ComponentsForArrayConstructionAreOK( - context, *composite_type->AsArray())) { + if (composite_type->AsArray() && + !ComponentsForArrayConstructionAreOK(ir_context, + *composite_type->AsArray())) { return false; } - if (composite_type->AsMatrix() && !ComponentsForMatrixConstructionAreOK( - context, *composite_type->AsMatrix())) { + if (composite_type->AsMatrix() && + !ComponentsForMatrixConstructionAreOK(ir_context, + *composite_type->AsMatrix())) { return false; } - if (composite_type->AsStruct() && !ComponentsForStructConstructionAreOK( - context, *composite_type->AsStruct())) { + if (composite_type->AsStruct() && + !ComponentsForStructConstructionAreOK(ir_context, + *composite_type->AsStruct())) { return false; } - if (composite_type->AsVector() && !ComponentsForVectorConstructionAreOK( - context, *composite_type->AsVector())) { + if (composite_type->AsVector() && + !ComponentsForVectorConstructionAreOK(ir_context, + *composite_type->AsVector())) { return false; } // Now check whether every component being used to initialize the composite is // available at the desired program point. for (auto& component : message_.component()) { - if (!fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + if (!fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, component)) { return false; } @@ -93,13 +97,14 @@ bool TransformationCompositeConstruct::IsApplicable( return true; } -void TransformationCompositeConstruct::Apply(opt::IRContext* context, - FactManager* fact_manager) const { +void TransformationCompositeConstruct::Apply( + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // Use the base and offset information from the transformation to determine // where in the module a new instruction should be inserted. auto insert_before_inst = - FindInstruction(message_.instruction_to_insert_before(), context); - auto destination_block = context->get_instr_block(insert_before_inst); + FindInstruction(message_.instruction_to_insert_before(), ir_context); + auto destination_block = ir_context->get_instr_block(insert_before_inst); auto insert_before = fuzzerutil::GetIteratorForInstruction( destination_block, insert_before_inst); @@ -111,22 +116,22 @@ void TransformationCompositeConstruct::Apply(opt::IRContext* context, // Insert an OpCompositeConstruct instruction. insert_before.InsertBefore(MakeUnique( - context, SpvOpCompositeConstruct, message_.composite_type_id(), + ir_context, SpvOpCompositeConstruct, message_.composite_type_id(), message_.fresh_id(), in_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); // Inform the fact manager that we now have new synonyms: every component of // the composite is synonymous with the id used to construct that component, // except in the case of a vector where a single vector id can span multiple // components. auto composite_type = - context->get_type_mgr()->GetType(message_.composite_type_id()); + ir_context->get_type_mgr()->GetType(message_.composite_type_id()); uint32_t index = 0; for (auto component : message_.component()) { - auto component_type = context->get_type_mgr()->GetType( - context->get_def_use_mgr()->GetDef(component)->type_id()); + auto component_type = ir_context->get_type_mgr()->GetType( + ir_context->get_def_use_mgr()->GetDef(component)->type_id()); if (composite_type->AsVector() && component_type->AsVector()) { // The case where the composite being constructed is a vector and the // component provided for construction is also a vector is special. It @@ -139,24 +144,24 @@ void TransformationCompositeConstruct::Apply(opt::IRContext* context, for (uint32_t subvector_index = 0; subvector_index < component_type->AsVector()->element_count(); subvector_index++) { - fact_manager->AddFactDataSynonym( + transformation_context->GetFactManager()->AddFactDataSynonym( MakeDataDescriptor(component, {subvector_index}), - MakeDataDescriptor(message_.fresh_id(), {index}), context); + MakeDataDescriptor(message_.fresh_id(), {index}), ir_context); index++; } } else { // The other cases are simple: the component is made directly synonymous // with the element of the composite being constructed. - fact_manager->AddFactDataSynonym( + transformation_context->GetFactManager()->AddFactDataSynonym( MakeDataDescriptor(component, {}), - MakeDataDescriptor(message_.fresh_id(), {index}), context); + MakeDataDescriptor(message_.fresh_id(), {index}), ir_context); index++; } } } bool TransformationCompositeConstruct::ComponentsForArrayConstructionAreOK( - opt::IRContext* context, const opt::analysis::Array& array_type) const { + opt::IRContext* ir_context, const opt::analysis::Array& array_type) const { if (array_type.length_info().words[0] != opt::analysis::Array::LengthInfo::kConstant) { // We only handle constant-sized arrays. @@ -176,13 +181,13 @@ bool TransformationCompositeConstruct::ComponentsForArrayConstructionAreOK( // Check that each component is the result id of an instruction whose type is // the array's element type. for (auto component_id : message_.component()) { - auto inst = context->get_def_use_mgr()->GetDef(component_id); + auto inst = ir_context->get_def_use_mgr()->GetDef(component_id); if (inst == nullptr || !inst->type_id()) { // The component does not correspond to an instruction with a result // type. return false; } - auto component_type = context->get_type_mgr()->GetType(inst->type_id()); + auto component_type = ir_context->get_type_mgr()->GetType(inst->type_id()); assert(component_type); if (component_type != array_type.element_type()) { // The component's type does not match the array's element type. @@ -193,7 +198,8 @@ bool TransformationCompositeConstruct::ComponentsForArrayConstructionAreOK( } bool TransformationCompositeConstruct::ComponentsForMatrixConstructionAreOK( - opt::IRContext* context, const opt::analysis::Matrix& matrix_type) const { + opt::IRContext* ir_context, + const opt::analysis::Matrix& matrix_type) const { if (static_cast(message_.component().size()) != matrix_type.element_count()) { // The number of components must match the number of columns of the matrix. @@ -202,13 +208,13 @@ bool TransformationCompositeConstruct::ComponentsForMatrixConstructionAreOK( // Check that each component is the result id of an instruction whose type is // the matrix's column type. for (auto component_id : message_.component()) { - auto inst = context->get_def_use_mgr()->GetDef(component_id); + auto inst = ir_context->get_def_use_mgr()->GetDef(component_id); if (inst == nullptr || !inst->type_id()) { // The component does not correspond to an instruction with a result // type. return false; } - auto component_type = context->get_type_mgr()->GetType(inst->type_id()); + auto component_type = ir_context->get_type_mgr()->GetType(inst->type_id()); assert(component_type); if (component_type != matrix_type.element_type()) { // The component's type does not match the matrix's column type. @@ -219,7 +225,8 @@ bool TransformationCompositeConstruct::ComponentsForMatrixConstructionAreOK( } bool TransformationCompositeConstruct::ComponentsForStructConstructionAreOK( - opt::IRContext* context, const opt::analysis::Struct& struct_type) const { + opt::IRContext* ir_context, + const opt::analysis::Struct& struct_type) const { if (static_cast(message_.component().size()) != struct_type.element_types().size()) { // The number of components must match the number of fields of the struct. @@ -229,14 +236,14 @@ bool TransformationCompositeConstruct::ComponentsForStructConstructionAreOK( // matches the associated field type. for (uint32_t field_index = 0; field_index < struct_type.element_types().size(); field_index++) { - auto inst = - context->get_def_use_mgr()->GetDef(message_.component()[field_index]); + auto inst = ir_context->get_def_use_mgr()->GetDef( + message_.component()[field_index]); if (inst == nullptr || !inst->type_id()) { // The component does not correspond to an instruction with a result // type. return false; } - auto component_type = context->get_type_mgr()->GetType(inst->type_id()); + auto component_type = ir_context->get_type_mgr()->GetType(inst->type_id()); assert(component_type); if (component_type != struct_type.element_types()[field_index]) { // The component's type does not match the corresponding field type. @@ -247,17 +254,18 @@ bool TransformationCompositeConstruct::ComponentsForStructConstructionAreOK( } bool TransformationCompositeConstruct::ComponentsForVectorConstructionAreOK( - opt::IRContext* context, const opt::analysis::Vector& vector_type) const { + opt::IRContext* ir_context, + const opt::analysis::Vector& vector_type) const { uint32_t base_element_count = 0; auto element_type = vector_type.element_type(); for (auto& component_id : message_.component()) { - auto inst = context->get_def_use_mgr()->GetDef(component_id); + auto inst = ir_context->get_def_use_mgr()->GetDef(component_id); if (inst == nullptr || !inst->type_id()) { // The component does not correspond to an instruction with a result // type. return false; } - auto component_type = context->get_type_mgr()->GetType(inst->type_id()); + auto component_type = ir_context->get_type_mgr()->GetType(inst->type_id()); assert(component_type); if (component_type == element_type) { base_element_count++; diff --git a/source/fuzz/transformation_composite_construct.h b/source/fuzz/transformation_composite_construct.h index 5369c4c8..2e55e70f 100644 --- a/source/fuzz/transformation_composite_construct.h +++ b/source/fuzz/transformation_composite_construct.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_CONSTRUCT_H_ #define SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_CONSTRUCT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -49,15 +49,17 @@ class TransformationCompositeConstruct : public Transformation { // before 'inst'. // - Each element of |message_.component| must be available directly before // 'inst'. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Inserts a new OpCompositeConstruct instruction, with id // |message_.fresh_id|, directly before the instruction identified by // |message_.base_instruction_id| and |message_.offset|. The instruction // creates a composite of type |message_.composite_type_id| using the ids of // |message_.component|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -65,19 +67,22 @@ class TransformationCompositeConstruct : public Transformation { // Helper to decide whether the components of the transformation are suitable // for constructing an array of the given type. bool ComponentsForArrayConstructionAreOK( - opt::IRContext* context, const opt::analysis::Array& array_type) const; + opt::IRContext* ir_context, const opt::analysis::Array& array_type) const; // Similar, but for matrices. bool ComponentsForMatrixConstructionAreOK( - opt::IRContext* context, const opt::analysis::Matrix& matrix_type) const; + opt::IRContext* ir_context, + const opt::analysis::Matrix& matrix_type) const; // Similar, but for structs. bool ComponentsForStructConstructionAreOK( - opt::IRContext* context, const opt::analysis::Struct& struct_type) const; + opt::IRContext* ir_context, + const opt::analysis::Struct& struct_type) const; // Similar, but for vectors. bool ComponentsForVectorConstructionAreOK( - opt::IRContext* context, const opt::analysis::Vector& vector_type) const; + opt::IRContext* ir_context, + const opt::analysis::Vector& vector_type) const; protobufs::TransformationCompositeConstruct message_; }; diff --git a/source/fuzz/transformation_composite_extract.cpp b/source/fuzz/transformation_composite_extract.cpp index 5d3a386e..3dc3953d 100644 --- a/source/fuzz/transformation_composite_extract.cpp +++ b/source/fuzz/transformation_composite_extract.cpp @@ -40,24 +40,23 @@ TransformationCompositeExtract::TransformationCompositeExtract( } bool TransformationCompositeExtract::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } auto instruction_to_insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!instruction_to_insert_before) { return false; } auto composite_instruction = - context->get_def_use_mgr()->GetDef(message_.composite_id()); + ir_context->get_def_use_mgr()->GetDef(message_.composite_id()); if (!composite_instruction) { return false; } - if (auto block = context->get_instr_block(composite_instruction)) { + if (auto block = ir_context->get_instr_block(composite_instruction)) { if (composite_instruction == instruction_to_insert_before || - !context->GetDominatorAnalysis(block->GetParent()) + !ir_context->GetDominatorAnalysis(block->GetParent()) ->Dominates(composite_instruction, instruction_to_insert_before)) { return false; } @@ -66,7 +65,7 @@ bool TransformationCompositeExtract::IsApplicable( "An instruction in a block cannot have a result id but no type id."); auto composite_type = - context->get_type_mgr()->GetType(composite_instruction->type_id()); + ir_context->get_type_mgr()->GetType(composite_instruction->type_id()); if (!composite_type) { return false; } @@ -76,30 +75,33 @@ bool TransformationCompositeExtract::IsApplicable( return false; } - return fuzzerutil::WalkCompositeTypeIndices( - context, composite_instruction->type_id(), message_.index()) != 0; + return fuzzerutil::WalkCompositeTypeIndices(ir_context, + composite_instruction->type_id(), + message_.index()) != 0; } void TransformationCompositeExtract::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { opt::Instruction::OperandList extract_operands; extract_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.composite_id()}}); for (auto an_index : message_.index()) { extract_operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {an_index}}); } auto composite_instruction = - context->get_def_use_mgr()->GetDef(message_.composite_id()); + ir_context->get_def_use_mgr()->GetDef(message_.composite_id()); auto extracted_type = fuzzerutil::WalkCompositeTypeIndices( - context, composite_instruction->type_id(), message_.index()); + ir_context, composite_instruction->type_id(), message_.index()); - FindInstruction(message_.instruction_to_insert_before(), context) + FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - context, SpvOpCompositeExtract, extracted_type, message_.fresh_id(), - extract_operands)); + ir_context, SpvOpCompositeExtract, extracted_type, + message_.fresh_id(), extract_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); // Add the fact that the id storing the extracted element is synonymous with // the index into the structure. @@ -111,8 +113,9 @@ void TransformationCompositeExtract::Apply( MakeDataDescriptor(message_.composite_id(), std::move(indices)); protobufs::DataDescriptor data_descriptor_for_result_id = MakeDataDescriptor(message_.fresh_id(), {}); - fact_manager->AddFactDataSynonym(data_descriptor_for_extracted_element, - data_descriptor_for_result_id, context); + transformation_context->GetFactManager()->AddFactDataSynonym( + data_descriptor_for_extracted_element, data_descriptor_for_result_id, + ir_context); } protobufs::Transformation TransformationCompositeExtract::ToMessage() const { diff --git a/source/fuzz/transformation_composite_extract.h b/source/fuzz/transformation_composite_extract.h index c4c9278c..8f52d226 100644 --- a/source/fuzz/transformation_composite_extract.h +++ b/source/fuzz/transformation_composite_extract.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_EXTRACT_H_ #define SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_EXTRACT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -41,15 +41,17 @@ class TransformationCompositeExtract : public Transformation { // - |message_.index| must be a suitable set of indices for // |message_.composite_id|, i.e. it must be possible to follow this chain // of indices to reach a sub-object of |message_.composite_id| - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an OpCompositeConstruct instruction before the instruction identified // by |message_.instruction_to_insert_before|, that extracts from // |message_.composite_id| via indices |message_.index| into // |message_.fresh_id|. Generates a data synonym fact relating // |message_.fresh_id| to the extracted element. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_context.cpp b/source/fuzz/transformation_context.cpp new file mode 100644 index 00000000..9c8a90f6 --- /dev/null +++ b/source/fuzz/transformation_context.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/fuzz/transformation_context.h" + +namespace spvtools { +namespace fuzz { + +TransformationContext::TransformationContext( + FactManager* transformation_context, + spv_validator_options validator_options) + : fact_manager_(transformation_context), + validator_options_(validator_options) {} + +TransformationContext::~TransformationContext() = default; + +} // namespace fuzz +} // namespace spvtools diff --git a/source/fuzz/transformation_context.h b/source/fuzz/transformation_context.h new file mode 100644 index 00000000..37e15a22 --- /dev/null +++ b/source/fuzz/transformation_context.h @@ -0,0 +1,56 @@ +// Copyright (c) 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_FUZZ_TRANSFORMATION_CONTEXT_H_ +#define SOURCE_FUZZ_TRANSFORMATION_CONTEXT_H_ + +#include "source/fuzz/fact_manager.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { +namespace fuzz { + +// Encapsulates all information that is required to inform how to apply a +// transformation to a module. +class TransformationContext { + public: + // Constructs a transformation context with a given fact manager and validator + // options. + TransformationContext(FactManager* fact_manager, + spv_validator_options validator_options); + + ~TransformationContext(); + + FactManager* GetFactManager() { return fact_manager_; } + + const FactManager* GetFactManager() const { return fact_manager_; } + + spv_validator_options GetValidatorOptions() const { + return validator_options_; + } + + private: + // Manages facts that inform whether transformations can be applied, and that + // are produced by applying transformations. + FactManager* fact_manager_; + + // Options to control validation when deciding whether transformations can be + // applied. + spv_validator_options validator_options_; +}; + +} // namespace fuzz +} // namespace spvtools + +#endif // SOURCE_FUZZ_TRANSFORMATION_CONTEXT_H_ diff --git a/source/fuzz/transformation_copy_object.cpp b/source/fuzz/transformation_copy_object.cpp index bfdced37..7b5b5c9e 100644 --- a/source/fuzz/transformation_copy_object.cpp +++ b/source/fuzz/transformation_copy_object.cpp @@ -38,22 +38,22 @@ TransformationCopyObject::TransformationCopyObject( } bool TransformationCopyObject::IsApplicable( - opt::IRContext* context, const FactManager& /*fact_manager*/) const { - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { // We require the id for the object copy to be unused. return false; } // The id of the object to be copied must exist - auto object_inst = context->get_def_use_mgr()->GetDef(message_.object()); + auto object_inst = ir_context->get_def_use_mgr()->GetDef(message_.object()); if (!object_inst) { return false; } - if (!fuzzerutil::CanMakeSynonymOf(context, object_inst)) { + if (!fuzzerutil::CanMakeSynonymOf(ir_context, object_inst)) { return false; } auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!insert_before) { // The instruction before which the copy should be inserted was not found. return false; @@ -66,17 +66,18 @@ bool TransformationCopyObject::IsApplicable( // |message_object| must be available directly before the point where we want // to add the copy. - return fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + return fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, message_.object()); } -void TransformationCopyObject::Apply(opt::IRContext* context, - FactManager* fact_manager) const { - auto object_inst = context->get_def_use_mgr()->GetDef(message_.object()); +void TransformationCopyObject::Apply( + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { + auto object_inst = ir_context->get_def_use_mgr()->GetDef(message_.object()); assert(object_inst && "The object to be copied must exist."); auto insert_before_inst = - FindInstruction(message_.instruction_to_insert_before(), context); - auto destination_block = context->get_instr_block(insert_before_inst); + FindInstruction(message_.instruction_to_insert_before(), ir_context); + auto destination_block = ir_context->get_instr_block(insert_before_inst); assert(destination_block && "The base instruction must be in a block."); auto insert_before = fuzzerutil::GetIteratorForInstruction( destination_block, insert_before_inst); @@ -86,18 +87,21 @@ void TransformationCopyObject::Apply(opt::IRContext* context, opt::Instruction::OperandList operands = { {SPV_OPERAND_TYPE_ID, {message_.object()}}}; insert_before->InsertBefore(MakeUnique( - context, SpvOp::SpvOpCopyObject, object_inst->type_id(), + ir_context, SpvOp::SpvOpCopyObject, object_inst->type_id(), message_.fresh_id(), operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); - fact_manager->AddFactDataSynonym(MakeDataDescriptor(message_.object(), {}), - MakeDataDescriptor(message_.fresh_id(), {}), - context); + transformation_context->GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(message_.object(), {}), + MakeDataDescriptor(message_.fresh_id(), {}), ir_context); - if (fact_manager->PointeeValueIsIrrelevant(message_.object())) { - fact_manager->AddFactValueOfPointeeIsIrrelevant(message_.fresh_id()); + if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant( + message_.object())) { + transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + message_.fresh_id()); } } diff --git a/source/fuzz/transformation_copy_object.h b/source/fuzz/transformation_copy_object.h index 9e9c26a3..80d57aeb 100644 --- a/source/fuzz/transformation_copy_object.h +++ b/source/fuzz/transformation_copy_object.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_COPY_OBJECT_H_ #define SOURCE_FUZZ_TRANSFORMATION_COPY_OBJECT_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -49,19 +49,21 @@ class TransformationCopyObject : public Transformation { // - |message_.object| must be available directly before 'inst'. // - |message_.object| must not be a null pointer or undefined pointer (so as // to make it legal to load from copied pointers). - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - A new instruction, // %|message_.fresh_id| = OpCopyObject %ty %|message_.object| // is added directly before the instruction at |message_.insert_after_id| + // |message_|.offset, where %ty is the type of |message_.object|. // - The fact that |message_.fresh_id| and |message_.object| are synonyms - // is added to |fact_manager|. + // is added to the fact manager in |transformation_context|. // - If |message_.object| is a pointer whose pointee value is known to be - // irrelevant, the analogous fact is added to |fact_manager| about - // |message_.fresh_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + // irrelevant, the analogous fact is added to the fact manager in + // |transformation_context| about |message_.fresh_id|. + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_equation_instruction.cpp b/source/fuzz/transformation_equation_instruction.cpp index 21b67f66..5c314171 100644 --- a/source/fuzz/transformation_equation_instruction.cpp +++ b/source/fuzz/transformation_equation_instruction.cpp @@ -37,40 +37,40 @@ TransformationEquationInstruction::TransformationEquationInstruction( } bool TransformationEquationInstruction::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The instruction to insert before must exist. auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!insert_before) { return false; } // The input ids must all exist, not be OpUndef, and be available before this // instruction. for (auto id : message_.in_operand_id()) { - auto inst = context->get_def_use_mgr()->GetDef(id); + auto inst = ir_context->get_def_use_mgr()->GetDef(id); if (!inst) { return false; } if (inst->opcode() == SpvOpUndef) { return false; } - if (!fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + if (!fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, id)) { return false; } } - return MaybeGetResultType(context) != 0; + return MaybeGetResultType(ir_context) != 0; } void TransformationEquationInstruction::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); opt::Instruction::OperandList in_operands; std::vector rhs_id; @@ -79,16 +79,16 @@ void TransformationEquationInstruction::Apply( rhs_id.push_back(id); } - FindInstruction(message_.instruction_to_insert_before(), context) + FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - context, static_cast(message_.opcode()), - MaybeGetResultType(context), message_.fresh_id(), in_operands)); + ir_context, static_cast(message_.opcode()), + MaybeGetResultType(ir_context), message_.fresh_id(), in_operands)); - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); - fact_manager->AddFactIdEquation(message_.fresh_id(), - static_cast(message_.opcode()), rhs_id, - context); + transformation_context->GetFactManager()->AddFactIdEquation( + message_.fresh_id(), static_cast(message_.opcode()), rhs_id, + ir_context); } protobufs::Transformation TransformationEquationInstruction::ToMessage() const { @@ -98,7 +98,7 @@ protobufs::Transformation TransformationEquationInstruction::ToMessage() const { } uint32_t TransformationEquationInstruction::MaybeGetResultType( - opt::IRContext* context) const { + opt::IRContext* ir_context) const { switch (static_cast(message_.opcode())) { case SpvOpIAdd: case SpvOpISub: { @@ -108,13 +108,13 @@ uint32_t TransformationEquationInstruction::MaybeGetResultType( uint32_t first_operand_width = 0; uint32_t first_operand_type_id = 0; for (uint32_t index = 0; index < 2; index++) { - auto operand_inst = - context->get_def_use_mgr()->GetDef(message_.in_operand_id(index)); + auto operand_inst = ir_context->get_def_use_mgr()->GetDef( + message_.in_operand_id(index)); if (!operand_inst || !operand_inst->type_id()) { return 0; } auto operand_type = - context->get_type_mgr()->GetType(operand_inst->type_id()); + ir_context->get_type_mgr()->GetType(operand_inst->type_id()); if (!(operand_type->AsInteger() || (operand_type->AsVector() && operand_type->AsVector()->element_type()->AsInteger()))) { @@ -144,12 +144,12 @@ uint32_t TransformationEquationInstruction::MaybeGetResultType( return 0; } auto operand_inst = - context->get_def_use_mgr()->GetDef(message_.in_operand_id(0)); + ir_context->get_def_use_mgr()->GetDef(message_.in_operand_id(0)); if (!operand_inst || !operand_inst->type_id()) { return 0; } auto operand_type = - context->get_type_mgr()->GetType(operand_inst->type_id()); + ir_context->get_type_mgr()->GetType(operand_inst->type_id()); if (!(operand_type->AsBool() || (operand_type->AsVector() && operand_type->AsVector()->element_type()->AsBool()))) { @@ -162,12 +162,12 @@ uint32_t TransformationEquationInstruction::MaybeGetResultType( return 0; } auto operand_inst = - context->get_def_use_mgr()->GetDef(message_.in_operand_id(0)); + ir_context->get_def_use_mgr()->GetDef(message_.in_operand_id(0)); if (!operand_inst || !operand_inst->type_id()) { return 0; } auto operand_type = - context->get_type_mgr()->GetType(operand_inst->type_id()); + ir_context->get_type_mgr()->GetType(operand_inst->type_id()); if (!(operand_type->AsInteger() || (operand_type->AsVector() && operand_type->AsVector()->element_type()->AsInteger()))) { diff --git a/source/fuzz/transformation_equation_instruction.h b/source/fuzz/transformation_equation_instruction.h index 2456ba50..7eec9c65 100644 --- a/source/fuzz/transformation_equation_instruction.h +++ b/source/fuzz/transformation_equation_instruction.h @@ -17,9 +17,9 @@ #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -44,8 +44,9 @@ class TransformationEquationInstruction : public Transformation { // equations, the types of the ids in |message_.in_operand_id| must be // suitable for use with this opcode, and the module must contain an // appropriate result type id. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction to the module, right before // |message_.instruction_to_insert_before|, of the form: @@ -56,7 +57,8 @@ class TransformationEquationInstruction : public Transformation { // compatible with the opcode and input operands. // // The fact manager is also updated to inform it of this equation fact. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -65,7 +67,7 @@ class TransformationEquationInstruction : public Transformation { // in |message_.in_operand_id| are compatible, and that the module contains // an appropriate result type id. If all is well, the result type id is // returned. Otherwise, 0 is returned. - uint32_t MaybeGetResultType(opt::IRContext* context) const; + uint32_t MaybeGetResultType(opt::IRContext* ir_context) const; protobufs::TransformationEquationInstruction message_; }; diff --git a/source/fuzz/transformation_function_call.cpp b/source/fuzz/transformation_function_call.cpp index cea85371..432634d3 100644 --- a/source/fuzz/transformation_function_call.cpp +++ b/source/fuzz/transformation_function_call.cpp @@ -39,25 +39,26 @@ TransformationFunctionCall::TransformationFunctionCall( } bool TransformationFunctionCall::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // The result id must be fresh - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The function must exist - auto callee_inst = context->get_def_use_mgr()->GetDef(message_.callee_id()); + auto callee_inst = + ir_context->get_def_use_mgr()->GetDef(message_.callee_id()); if (!callee_inst || callee_inst->opcode() != SpvOpFunction) { return false; } // The function must not be an entry point - if (fuzzerutil::FunctionIsEntryPoint(context, message_.callee_id())) { + if (fuzzerutil::FunctionIsEntryPoint(ir_context, message_.callee_id())) { return false; } - auto callee_type_inst = context->get_def_use_mgr()->GetDef( + auto callee_type_inst = ir_context->get_def_use_mgr()->GetDef( callee_inst->GetSingleWordInOperand(1)); assert(callee_type_inst->opcode() == SpvOpTypeFunction && "Bad function type."); @@ -73,7 +74,7 @@ bool TransformationFunctionCall::IsApplicable( // The instruction descriptor must refer to a position where it is valid to // insert the call auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!insert_before) { return false; } @@ -82,13 +83,15 @@ bool TransformationFunctionCall::IsApplicable( return false; } - auto block = context->get_instr_block(insert_before); + auto block = ir_context->get_instr_block(insert_before); auto enclosing_function = block->GetParent(); // If the block is not dead, the function must be livesafe - bool block_is_dead = fact_manager.BlockIsDead(block->id()); + bool block_is_dead = + transformation_context.GetFactManager()->BlockIsDead(block->id()); if (!block_is_dead && - !fact_manager.FunctionIsLivesafe(message_.callee_id())) { + !transformation_context.GetFactManager()->FunctionIsLivesafe( + message_.callee_id())) { return false; } @@ -98,7 +101,7 @@ bool TransformationFunctionCall::IsApplicable( arg_index < static_cast(message_.argument_id().size()); arg_index++) { opt::Instruction* arg_inst = - context->get_def_use_mgr()->GetDef(message_.argument_id(arg_index)); + ir_context->get_def_use_mgr()->GetDef(message_.argument_id(arg_index)); if (!arg_inst) { // The given argument does not correspond to an instruction. return false; @@ -112,7 +115,7 @@ bool TransformationFunctionCall::IsApplicable( return false; } opt::Instruction* arg_type_inst = - context->get_def_use_mgr()->GetDef(arg_inst->type_id()); + ir_context->get_def_use_mgr()->GetDef(arg_inst->type_id()); if (arg_type_inst->opcode() == SpvOpTypePointer) { switch (arg_inst->opcode()) { case SpvOpFunctionParameter: @@ -124,7 +127,8 @@ bool TransformationFunctionCall::IsApplicable( return false; } if (!block_is_dead && - !fact_manager.PointeeValueIsIrrelevant(arg_inst->result_id())) { + !transformation_context.GetFactManager()->PointeeValueIsIrrelevant( + arg_inst->result_id())) { // This is not a dead block, so pointer parameters passed to the called // function might really have their contents modified. We thus require // such pointers to be to arbitrary-valued variables, which this is not. @@ -134,7 +138,7 @@ bool TransformationFunctionCall::IsApplicable( // The argument id needs to be available (according to dominance rules) at // the point where the call will occur. - if (!fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + if (!fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, arg_inst->result_id())) { return false; } @@ -146,19 +150,19 @@ bool TransformationFunctionCall::IsApplicable( return false; } // Ensure the call would not lead to indirect recursion. - return !CallGraph(context) + return !CallGraph(ir_context) .GetIndirectCallees(message_.callee_id()) .count(block->GetParent()->result_id()); } void TransformationFunctionCall::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Update the module's bound to reflect the fresh id for the result of the // function call. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // Get the return type of the function being called. uint32_t return_type = - context->get_def_use_mgr()->GetDef(message_.callee_id())->type_id(); + ir_context->get_def_use_mgr()->GetDef(message_.callee_id())->type_id(); // Populate the operands to the call instruction, with the function id and the // arguments. opt::Instruction::OperandList operands; @@ -167,12 +171,12 @@ void TransformationFunctionCall::Apply( operands.push_back({SPV_OPERAND_TYPE_ID, {arg}}); } // Insert the function call before the instruction specified in the message. - FindInstruction(message_.instruction_to_insert_before(), context) - ->InsertBefore( - MakeUnique(context, SpvOpFunctionCall, return_type, - message_.fresh_id(), operands)); + FindInstruction(message_.instruction_to_insert_before(), ir_context) + ->InsertBefore(MakeUnique( + ir_context, SpvOpFunctionCall, return_type, message_.fresh_id(), + operands)); // Invalidate all analyses since we have changed the module. - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationFunctionCall::ToMessage() const { diff --git a/source/fuzz/transformation_function_call.h b/source/fuzz/transformation_function_call.h index a9ae5bee..4ad7db13 100644 --- a/source/fuzz/transformation_function_call.h +++ b/source/fuzz/transformation_function_call.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_FUNCTION_CALL_H_ #define SOURCE_FUZZ_TRANSFORMATION_FUNCTION_CALL_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -44,14 +44,16 @@ class TransformationFunctionCall : public Transformation { // - If the insertion point is not in a dead block then |message_function_id| // must refer to a livesafe function, and every pointer argument in // |message_.arg_id| must refer to an arbitrary-valued variable - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction of the form: // |fresh_id| = OpFunctionCall %type |callee_id| |arg_id...| // before |instruction_to_insert_before|, where %type is the return type of // |callee_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_load.cpp b/source/fuzz/transformation_load.cpp index 4cba37da..a260c335 100644 --- a/source/fuzz/transformation_load.cpp +++ b/source/fuzz/transformation_load.cpp @@ -34,20 +34,19 @@ TransformationLoad::TransformationLoad( } bool TransformationLoad::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The result id must be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The pointer must exist and have a type. - auto pointer = context->get_def_use_mgr()->GetDef(message_.pointer_id()); + auto pointer = ir_context->get_def_use_mgr()->GetDef(message_.pointer_id()); if (!pointer || !pointer->type_id()) { return false; } // The type must indeed be a pointer type. - auto pointer_type = context->get_def_use_mgr()->GetDef(pointer->type_id()); + auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); assert(pointer_type && "Type id must be defined."); if (pointer_type->opcode() != SpvOpTypePointer) { return false; @@ -65,7 +64,7 @@ bool TransformationLoad::IsApplicable( // Determine which instruction we should be inserting before. auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); // It must exist, ... if (!insert_before) { return false; @@ -76,21 +75,21 @@ bool TransformationLoad::IsApplicable( } // The pointer needs to be available at the insertion point. - return fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + return fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, message_.pointer_id()); } -void TransformationLoad::Apply(opt::IRContext* context, - spvtools::fuzz::FactManager* /*unused*/) const { +void TransformationLoad::Apply(opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { uint32_t result_type = fuzzerutil::GetPointeeTypeIdFromPointerType( - context, fuzzerutil::GetTypeId(context, message_.pointer_id())); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - FindInstruction(message_.instruction_to_insert_before(), context) + ir_context, fuzzerutil::GetTypeId(ir_context, message_.pointer_id())); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - context, SpvOpLoad, result_type, message_.fresh_id(), + ir_context, SpvOpLoad, result_type, message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}}))); - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationLoad::ToMessage() const { diff --git a/source/fuzz/transformation_load.h b/source/fuzz/transformation_load.h index ff990167..4c7c00b6 100644 --- a/source/fuzz/transformation_load.h +++ b/source/fuzz/transformation_load.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_LOAD_H_ #define SOURCE_FUZZ_TRANSFORMATION_LOAD_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -37,15 +37,17 @@ class TransformationLoad : public Transformation { // - |message_.instruction_to_insert_before| must identify an instruction // before which it is valid to insert an OpLoad, and where // |message_.pointer_id| is available (according to dominance rules) - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction of the form: // |message_.fresh_id| = OpLoad %type |message_.pointer_id| // before the instruction identified by // |message_.instruction_to_insert_before|, where %type is the pointer's // pointee type. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_merge_blocks.cpp b/source/fuzz/transformation_merge_blocks.cpp index 316e80df..68ac0922 100644 --- a/source/fuzz/transformation_merge_blocks.cpp +++ b/source/fuzz/transformation_merge_blocks.cpp @@ -29,40 +29,41 @@ TransformationMergeBlocks::TransformationMergeBlocks(uint32_t block_id) { } bool TransformationMergeBlocks::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { - auto second_block = fuzzerutil::MaybeFindBlock(context, message_.block_id()); + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + auto second_block = + fuzzerutil::MaybeFindBlock(ir_context, message_.block_id()); // The given block must exist. if (!second_block) { return false; } // The block must have just one predecessor. - auto predecessors = context->cfg()->preds(second_block->id()); + auto predecessors = ir_context->cfg()->preds(second_block->id()); if (predecessors.size() != 1) { return false; } - auto first_block = context->cfg()->block(predecessors.at(0)); + auto first_block = ir_context->cfg()->block(predecessors.at(0)); - return opt::blockmergeutil::CanMergeWithSuccessor(context, first_block); + return opt::blockmergeutil::CanMergeWithSuccessor(ir_context, first_block); } -void TransformationMergeBlocks::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { - auto second_block = fuzzerutil::MaybeFindBlock(context, message_.block_id()); - auto first_block = - context->cfg()->block(context->cfg()->preds(second_block->id()).at(0)); +void TransformationMergeBlocks::Apply(opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { + auto second_block = + fuzzerutil::MaybeFindBlock(ir_context, message_.block_id()); + auto first_block = ir_context->cfg()->block( + ir_context->cfg()->preds(second_block->id()).at(0)); auto function = first_block->GetParent(); // We need an iterator pointing to the predecessor, hence the loop. for (auto bi = function->begin(); bi != function->end(); ++bi) { if (bi->id() == first_block->id()) { - assert(opt::blockmergeutil::CanMergeWithSuccessor(context, &*bi) && + assert(opt::blockmergeutil::CanMergeWithSuccessor(ir_context, &*bi) && "Because 'Apply' should only be invoked if 'IsApplicable' holds, " "it must be possible to merge |bi| with its successor."); - opt::blockmergeutil::MergeWithSuccessor(context, function, bi); + opt::blockmergeutil::MergeWithSuccessor(ir_context, function, bi); // Invalidate all analyses, since we have changed the module // significantly. - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); return; } } diff --git a/source/fuzz/transformation_merge_blocks.h b/source/fuzz/transformation_merge_blocks.h index 86216db3..1dc16d2f 100644 --- a/source/fuzz/transformation_merge_blocks.h +++ b/source/fuzz/transformation_merge_blocks.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_MERGE_BLOCKS_H_ #define SOURCE_FUZZ_TRANSFORMATION_MERGE_BLOCKS_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -35,12 +35,14 @@ class TransformationMergeBlocks : public Transformation { // - b must be the sole successor of a // - Replacing a with the merge of a and b (and removing b) must lead to a // valid module - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // The contents of b are merged into a, and a's terminator is replaced with // the terminator of b. Block b is removed from the module. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_move_block_down.cpp b/source/fuzz/transformation_move_block_down.cpp index f181855f..6c71ab70 100644 --- a/source/fuzz/transformation_move_block_down.cpp +++ b/source/fuzz/transformation_move_block_down.cpp @@ -28,10 +28,10 @@ TransformationMoveBlockDown::TransformationMoveBlockDown(uint32_t id) { } bool TransformationMoveBlockDown::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // Go through every block in every function, looking for a block whose id // matches that of the block we want to consider moving down. - for (auto& function : *context->module()) { + for (auto& function : *ir_context->module()) { for (auto block_it = function.begin(); block_it != function.end(); ++block_it) { if (block_it->id() == message_.block_id()) { @@ -43,7 +43,7 @@ bool TransformationMoveBlockDown::IsApplicable( } // Record the block we would like to consider moving down. opt::BasicBlock* block_matching_id = &*block_it; - if (!context->GetDominatorAnalysis(&function)->IsReachable( + if (!ir_context->GetDominatorAnalysis(&function)->IsReachable( block_matching_id)) { // The block is not reachable. We are not allowed to move it down. return false; @@ -60,7 +60,7 @@ bool TransformationMoveBlockDown::IsApplicable( opt::BasicBlock* next_block_in_program_order = &*block_it; // We can move the block of interest down if and only if it does not // dominate the block that comes next. - return !context->GetDominatorAnalysis(&function)->Dominates( + return !ir_context->GetDominatorAnalysis(&function)->Dominates( block_matching_id, next_block_in_program_order); } } @@ -71,11 +71,11 @@ bool TransformationMoveBlockDown::IsApplicable( return false; } -void TransformationMoveBlockDown::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { +void TransformationMoveBlockDown::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Go through every block in every function, looking for a block whose id // matches that of the block we want to move down. - for (auto& function : *context->module()) { + for (auto& function : *ir_context->module()) { for (auto block_it = function.begin(); block_it != function.end(); ++block_it) { if (block_it->id() == message_.block_id()) { @@ -87,7 +87,7 @@ void TransformationMoveBlockDown::Apply(opt::IRContext* context, // For performance, it is vital to keep the dominator analysis valid // (which due to https://github.com/KhronosGroup/SPIRV-Tools/issues/2889 // requires keeping the CFG analysis valid). - context->InvalidateAnalysesExceptFor( + ir_context->InvalidateAnalysesExceptFor( opt::IRContext::Analysis::kAnalysisDefUse | opt::IRContext::Analysis::kAnalysisCFG | opt::IRContext::Analysis::kAnalysisDominatorAnalysis); diff --git a/source/fuzz/transformation_move_block_down.h b/source/fuzz/transformation_move_block_down.h index fd1584a3..7551c382 100644 --- a/source/fuzz/transformation_move_block_down.h +++ b/source/fuzz/transformation_move_block_down.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_MOVE_BLOCK_DOWN_H_ #define SOURCE_FUZZ_TRANSFORMATION_MOVE_BLOCK_DOWN_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -35,12 +35,14 @@ class TransformationMoveBlockDown : public Transformation { // in a function. // - b must not dominate the block that follows it in program order. // - b must be reachable. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // The block with id |message_.block_id| is moved down; i.e. the program order // between it and the block that follows it is swapped. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_outline_function.cpp b/source/fuzz/transformation_outline_function.cpp index 01d1c458..117cdc6f 100644 --- a/source/fuzz/transformation_outline_function.cpp +++ b/source/fuzz/transformation_outline_function.cpp @@ -70,72 +70,71 @@ TransformationOutlineFunction::TransformationOutlineFunction( } bool TransformationOutlineFunction::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { std::set ids_used_by_this_transformation; // The various new ids used by the transformation must be fresh and distinct. if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_function_struct_return_type_id(), context, + message_.new_function_struct_return_type_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_function_type_id(), context, + message_.new_function_type_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_function_id(), context, + message_.new_function_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_function_region_entry_block(), context, + message_.new_function_region_entry_block(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_caller_result_id(), context, + message_.new_caller_result_id(), ir_context, &ids_used_by_this_transformation)) { return false; } if (!CheckIdIsFreshAndNotUsedByThisTransformation( - message_.new_callee_result_id(), context, + message_.new_callee_result_id(), ir_context, &ids_used_by_this_transformation)) { return false; } for (auto& pair : message_.input_id_to_fresh_id()) { if (!CheckIdIsFreshAndNotUsedByThisTransformation( - pair.second(), context, &ids_used_by_this_transformation)) { + pair.second(), ir_context, &ids_used_by_this_transformation)) { return false; } } for (auto& pair : message_.output_id_to_fresh_id()) { if (!CheckIdIsFreshAndNotUsedByThisTransformation( - pair.second(), context, &ids_used_by_this_transformation)) { + pair.second(), ir_context, &ids_used_by_this_transformation)) { return false; } } // The entry and exit block ids must indeed refer to blocks. for (auto block_id : {message_.entry_block(), message_.exit_block()}) { - auto block_label = context->get_def_use_mgr()->GetDef(block_id); + auto block_label = ir_context->get_def_use_mgr()->GetDef(block_id); if (!block_label || block_label->opcode() != SpvOpLabel) { return false; } } - auto entry_block = context->cfg()->block(message_.entry_block()); - auto exit_block = context->cfg()->block(message_.exit_block()); + auto entry_block = ir_context->cfg()->block(message_.entry_block()); + auto exit_block = ir_context->cfg()->block(message_.exit_block()); // The entry block cannot start with OpVariable - this would mean that // outlining would remove a variable from the function containing the region @@ -151,7 +150,7 @@ bool TransformationOutlineFunction::IsApplicable( // For simplicity, we do not allow the exit block to be a merge block or // continue target. - if (fuzzerutil::IsMergeOrContinue(context, exit_block->id())) { + if (fuzzerutil::IsMergeOrContinue(ir_context, exit_block->id())) { return false; } @@ -169,14 +168,14 @@ bool TransformationOutlineFunction::IsApplicable( // The entry block must dominate the exit block. auto dominator_analysis = - context->GetDominatorAnalysis(entry_block->GetParent()); + ir_context->GetDominatorAnalysis(entry_block->GetParent()); if (!dominator_analysis->Dominates(entry_block, exit_block)) { return false; } // The exit block must post-dominate the entry block. auto postdominator_analysis = - context->GetPostDominatorAnalysis(entry_block->GetParent()); + ir_context->GetPostDominatorAnalysis(entry_block->GetParent()); if (!postdominator_analysis->Dominates(exit_block, entry_block)) { return false; } @@ -184,8 +183,9 @@ bool TransformationOutlineFunction::IsApplicable( // Find all the blocks dominated by |message_.entry_block| and post-dominated // by |message_.exit_block|. auto region_set = GetRegionBlocks( - context, entry_block = context->cfg()->block(message_.entry_block()), - exit_block = context->cfg()->block(message_.exit_block())); + ir_context, + entry_block = ir_context->cfg()->block(message_.entry_block()), + exit_block = ir_context->cfg()->block(message_.exit_block())); // Check whether |region_set| really is a single-entry single-exit region, and // also check whether structured control flow constructs and their merge @@ -210,9 +210,9 @@ bool TransformationOutlineFunction::IsApplicable( // see whether all of the block's successors are in the region. If they // are not, the region is not single-entry single-exit. bool all_successors_in_region = true; - block.WhileEachSuccessorLabel([&all_successors_in_region, context, + block.WhileEachSuccessorLabel([&all_successors_in_region, ir_context, ®ion_set](uint32_t successor) -> bool { - if (region_set.count(context->cfg()->block(successor)) == 0) { + if (region_set.count(ir_context->cfg()->block(successor)) == 0) { all_successors_in_region = false; return false; } @@ -227,7 +227,8 @@ bool TransformationOutlineFunction::IsApplicable( // The block is a loop or selection header -- the header and its // associated merge block had better both be in the region or both be // outside the region. - auto merge_block = context->cfg()->block(merge->GetSingleWordOperand(0)); + auto merge_block = + ir_context->cfg()->block(merge->GetSingleWordOperand(0)); if (region_set.count(&block) != region_set.count(merge_block)) { return false; } @@ -236,7 +237,7 @@ bool TransformationOutlineFunction::IsApplicable( if (auto loop_merge = block.GetLoopMergeInst()) { // Similar to the above, but for the continue target of a loop. auto continue_target = - context->cfg()->block(loop_merge->GetSingleWordOperand(1)); + ir_context->cfg()->block(loop_merge->GetSingleWordOperand(1)); if (continue_target != exit_block && region_set.count(&block) != region_set.count(continue_target)) { return false; @@ -248,7 +249,7 @@ bool TransformationOutlineFunction::IsApplicable( // used inside the region, ... std::map input_id_to_fresh_id_map = PairSequenceToMap(message_.input_id_to_fresh_id()); - for (auto id : GetRegionInputIds(context, region_set, exit_block)) { + for (auto id : GetRegionInputIds(ir_context, region_set, exit_block)) { // There needs to be a corresponding fresh id to be used as a function // parameter. if (input_id_to_fresh_id_map.count(id) == 0) { @@ -256,8 +257,8 @@ bool TransformationOutlineFunction::IsApplicable( } // Furthermore, if the input id has pointer type it must be an OpVariable // or OpFunctionParameter. - auto input_id_inst = context->get_def_use_mgr()->GetDef(id); - if (context->get_def_use_mgr() + auto input_id_inst = ir_context->get_def_use_mgr()->GetDef(id); + if (ir_context->get_def_use_mgr() ->GetDef(input_id_inst->type_id()) ->opcode() == SpvOpTypePointer) { switch (input_id_inst->opcode()) { @@ -277,7 +278,7 @@ bool TransformationOutlineFunction::IsApplicable( // can hold the value for this id computed in the outlined function. std::map output_id_to_fresh_id_map = PairSequenceToMap(message_.output_id_to_fresh_id()); - for (auto id : GetRegionOutputIds(context, region_set, exit_block)) { + for (auto id : GetRegionOutputIds(ir_context, region_set, exit_block)) { if (output_id_to_fresh_id_map.count(id) == 0) { return false; } @@ -287,25 +288,26 @@ bool TransformationOutlineFunction::IsApplicable( } void TransformationOutlineFunction::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // The entry block for the region before outlining. auto original_region_entry_block = - context->cfg()->block(message_.entry_block()); + ir_context->cfg()->block(message_.entry_block()); // The exit block for the region before outlining. auto original_region_exit_block = - context->cfg()->block(message_.exit_block()); + ir_context->cfg()->block(message_.exit_block()); // The single-entry single-exit region defined by |message_.entry_block| and // |message_.exit_block|. std::set region_blocks = GetRegionBlocks( - context, original_region_entry_block, original_region_exit_block); + ir_context, original_region_entry_block, original_region_exit_block); // Input and output ids for the region being outlined. std::vector region_input_ids = - GetRegionInputIds(context, region_blocks, original_region_exit_block); + GetRegionInputIds(ir_context, region_blocks, original_region_exit_block); std::vector region_output_ids = - GetRegionOutputIds(context, region_blocks, original_region_exit_block); + GetRegionOutputIds(ir_context, region_blocks, original_region_exit_block); // Maps from input and output ids to fresh ids. std::map input_id_to_fresh_id_map = @@ -313,14 +315,14 @@ void TransformationOutlineFunction::Apply( std::map output_id_to_fresh_id_map = PairSequenceToMap(message_.output_id_to_fresh_id()); - UpdateModuleIdBoundForFreshIds(context, input_id_to_fresh_id_map, + UpdateModuleIdBoundForFreshIds(ir_context, input_id_to_fresh_id_map, output_id_to_fresh_id_map); // Construct a map that associates each output id with its type id. std::map output_id_to_type_id; for (uint32_t output_id : region_output_ids) { output_id_to_type_id[output_id] = - context->get_def_use_mgr()->GetDef(output_id)->type_id(); + ir_context->get_def_use_mgr()->GetDef(output_id)->type_id(); } // The region will be collapsed to a single block that calls a function @@ -331,53 +333,55 @@ void TransformationOutlineFunction::Apply( // collapsed block later. std::unique_ptr cloned_exit_block_terminator = std::unique_ptr( - original_region_exit_block->terminator()->Clone(context)); + original_region_exit_block->terminator()->Clone(ir_context)); std::unique_ptr cloned_exit_block_merge = original_region_exit_block->GetMergeInst() ? std::unique_ptr( - original_region_exit_block->GetMergeInst()->Clone(context)) + original_region_exit_block->GetMergeInst()->Clone(ir_context)) : nullptr; // Make a function prototype for the outlined function, which involves // figuring out its required type. - std::unique_ptr outlined_function = - PrepareFunctionPrototype(region_input_ids, region_output_ids, - input_id_to_fresh_id_map, context, fact_manager); + std::unique_ptr outlined_function = PrepareFunctionPrototype( + region_input_ids, region_output_ids, input_id_to_fresh_id_map, ir_context, + transformation_context); // If the original function was livesafe, the new function should also be // livesafe. - if (fact_manager->FunctionIsLivesafe( + if (transformation_context->GetFactManager()->FunctionIsLivesafe( original_region_entry_block->GetParent()->result_id())) { - fact_manager->AddFactFunctionIsLivesafe(message_.new_function_id()); + transformation_context->GetFactManager()->AddFactFunctionIsLivesafe( + message_.new_function_id()); } // Adapt the region to be outlined so that its input ids are replaced with the // ids of the outlined function's input parameters, and so that output ids // are similarly remapped. RemapInputAndOutputIdsInRegion( - context, *original_region_exit_block, region_blocks, region_input_ids, + ir_context, *original_region_exit_block, region_blocks, region_input_ids, region_output_ids, input_id_to_fresh_id_map, output_id_to_fresh_id_map); // Fill out the body of the outlined function according to the region that is // being outlined. - PopulateOutlinedFunction(*original_region_entry_block, - *original_region_exit_block, region_blocks, - region_output_ids, output_id_to_fresh_id_map, - context, outlined_function.get(), fact_manager); + PopulateOutlinedFunction( + *original_region_entry_block, *original_region_exit_block, region_blocks, + region_output_ids, output_id_to_fresh_id_map, ir_context, + outlined_function.get(), transformation_context); // Collapse the region that has been outlined into a function down to a single // block that calls said function. ShrinkOriginalRegion( - context, region_blocks, region_input_ids, region_output_ids, + ir_context, region_blocks, region_input_ids, region_output_ids, output_id_to_type_id, outlined_function->type_id(), std::move(cloned_exit_block_merge), std::move(cloned_exit_block_terminator), original_region_entry_block); // Add the outlined function to the module. - context->module()->AddFunction(std::move(outlined_function)); + ir_context->module()->AddFunction(std::move(outlined_function)); // Major surgery has been conducted on the module, so invalidate all analyses. - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationOutlineFunction::ToMessage() const { @@ -387,30 +391,31 @@ protobufs::Transformation TransformationOutlineFunction::ToMessage() const { } std::vector TransformationOutlineFunction::GetRegionInputIds( - opt::IRContext* context, const std::set& region_set, + opt::IRContext* ir_context, const std::set& region_set, opt::BasicBlock* region_exit_block) { std::vector result; auto enclosing_function = region_exit_block->GetParent(); // Consider each parameter of the function containing the region. - enclosing_function->ForEachParam([context, ®ion_set, &result]( - opt::Instruction* function_parameter) { - // Consider every use of the parameter. - context->get_def_use_mgr()->WhileEachUse( - function_parameter, [context, function_parameter, ®ion_set, &result]( - opt::Instruction* use, uint32_t /*unused*/) { - // Get the block, if any, in which the parameter is used. - auto use_block = context->get_instr_block(use); - // If the use is in a block that lies within the region, the - // parameter is an input id for the region. - if (use_block && region_set.count(use_block) != 0) { - result.push_back(function_parameter->result_id()); - return false; - } - return true; - }); - }); + enclosing_function->ForEachParam( + [ir_context, ®ion_set, &result](opt::Instruction* function_parameter) { + // Consider every use of the parameter. + ir_context->get_def_use_mgr()->WhileEachUse( + function_parameter, + [ir_context, function_parameter, ®ion_set, &result]( + opt::Instruction* use, uint32_t /*unused*/) { + // Get the block, if any, in which the parameter is used. + auto use_block = ir_context->get_instr_block(use); + // If the use is in a block that lies within the region, the + // parameter is an input id for the region. + if (use_block && region_set.count(use_block) != 0) { + result.push_back(function_parameter->result_id()); + return false; + } + return true; + }); + }); // Consider all definitions in the function that might turn out to be input // ids. @@ -430,15 +435,15 @@ std::vector TransformationOutlineFunction::GetRegionInputIds( // Consider each candidate input id to check whether it is used in the // region. for (auto& inst : candidate_input_ids_for_block) { - context->get_def_use_mgr()->WhileEachUse( + ir_context->get_def_use_mgr()->WhileEachUse( inst, - [context, &inst, region_exit_block, ®ion_set, &result]( + [ir_context, &inst, region_exit_block, ®ion_set, &result]( opt::Instruction* use, uint32_t /*unused*/) -> bool { // Find the block in which this id use occurs, recording the id as // an input id if the block is outside the region, with some // exceptions detailed below. - auto use_block = context->get_instr_block(use); + auto use_block = ir_context->get_instr_block(use); if (!use_block) { // There might be no containing block, e.g. if the use is in a @@ -467,7 +472,7 @@ std::vector TransformationOutlineFunction::GetRegionInputIds( } std::vector TransformationOutlineFunction::GetRegionOutputIds( - opt::IRContext* context, const std::set& region_set, + opt::IRContext* ir_context, const std::set& region_set, opt::BasicBlock* region_exit_block) { std::vector result; @@ -479,15 +484,15 @@ std::vector TransformationOutlineFunction::GetRegionOutputIds( } // Consider each use of each instruction defined in the block. for (auto& inst : block) { - context->get_def_use_mgr()->WhileEachUse( + ir_context->get_def_use_mgr()->WhileEachUse( &inst, - [®ion_set, context, &inst, region_exit_block, &result]( + [®ion_set, ir_context, &inst, region_exit_block, &result]( opt::Instruction* use, uint32_t /*unused*/) -> bool { // Find the block in which this id use occurs, recording the id as // an output id if the block is outside the region, with some // exceptions detailed below. - auto use_block = context->get_instr_block(use); + auto use_block = ir_context->get_instr_block(use); if (!use_block) { // There might be no containing block, e.g. if the use is in a @@ -513,12 +518,13 @@ std::vector TransformationOutlineFunction::GetRegionOutputIds( } std::set TransformationOutlineFunction::GetRegionBlocks( - opt::IRContext* context, opt::BasicBlock* entry_block, + opt::IRContext* ir_context, opt::BasicBlock* entry_block, opt::BasicBlock* exit_block) { auto enclosing_function = entry_block->GetParent(); - auto dominator_analysis = context->GetDominatorAnalysis(enclosing_function); + auto dominator_analysis = + ir_context->GetDominatorAnalysis(enclosing_function); auto postdominator_analysis = - context->GetPostDominatorAnalysis(enclosing_function); + ir_context->GetPostDominatorAnalysis(enclosing_function); std::set result; for (auto& block : *enclosing_function) { @@ -535,7 +541,8 @@ TransformationOutlineFunction::PrepareFunctionPrototype( const std::vector& region_input_ids, const std::vector& region_output_ids, const std::map& input_id_to_fresh_id_map, - opt::IRContext* context, FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { uint32_t return_type_id = 0; uint32_t function_type_id = 0; @@ -547,14 +554,14 @@ TransformationOutlineFunction::PrepareFunctionPrototype( if (region_output_ids.empty()) { std::vector return_and_parameter_types; opt::analysis::Void void_type; - return_type_id = context->get_type_mgr()->GetId(&void_type); + return_type_id = ir_context->get_type_mgr()->GetId(&void_type); return_and_parameter_types.push_back(return_type_id); for (auto id : region_input_ids) { return_and_parameter_types.push_back( - context->get_def_use_mgr()->GetDef(id)->type_id()); + ir_context->get_def_use_mgr()->GetDef(id)->type_id()); } function_type_id = - fuzzerutil::FindFunctionType(context, return_and_parameter_types); + fuzzerutil::FindFunctionType(ir_context, return_and_parameter_types); } // If no existing function type was found, we need to create one. @@ -568,12 +575,12 @@ TransformationOutlineFunction::PrepareFunctionPrototype( opt::Instruction::OperandList struct_member_types; for (uint32_t output_id : region_output_ids) { auto output_id_type = - context->get_def_use_mgr()->GetDef(output_id)->type_id(); + ir_context->get_def_use_mgr()->GetDef(output_id)->type_id(); struct_member_types.push_back({SPV_OPERAND_TYPE_ID, {output_id_type}}); } // Add a new struct type to the module. - context->module()->AddType(MakeUnique( - context, SpvOpTypeStruct, 0, + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeStruct, 0, message_.new_function_struct_return_type_id(), std::move(struct_member_types))); // The return type for the function is the newly-created struct. @@ -589,12 +596,12 @@ TransformationOutlineFunction::PrepareFunctionPrototype( for (auto id : region_input_ids) { function_type_operands.push_back( {SPV_OPERAND_TYPE_ID, - {context->get_def_use_mgr()->GetDef(id)->type_id()}}); + {ir_context->get_def_use_mgr()->GetDef(id)->type_id()}}); } // Add a new function type to the module, and record that this is the type // id for the new function. - context->module()->AddType(MakeUnique( - context, SpvOpTypeFunction, 0, message_.new_function_type_id(), + ir_context->module()->AddType(MakeUnique( + ir_context, SpvOpTypeFunction, 0, message_.new_function_type_id(), function_type_operands)); function_type_id = message_.new_function_type_id(); } @@ -603,7 +610,7 @@ TransformationOutlineFunction::PrepareFunctionPrototype( // and the return type and function type prepared above. std::unique_ptr outlined_function = MakeUnique(MakeUnique( - context, SpvOpFunction, return_type_id, message_.new_function_id(), + ir_context, SpvOpFunction, return_type_id, message_.new_function_id(), opt::Instruction::OperandList( {{spv_operand_type_t ::SPV_OPERAND_TYPE_LITERAL_INTEGER, {SpvFunctionControlMaskNone}}, @@ -614,14 +621,15 @@ TransformationOutlineFunction::PrepareFunctionPrototype( // provided in |input_id_to_fresh_id_map|. for (auto id : region_input_ids) { outlined_function->AddParameter(MakeUnique( - context, SpvOpFunctionParameter, - context->get_def_use_mgr()->GetDef(id)->type_id(), + ir_context, SpvOpFunctionParameter, + ir_context->get_def_use_mgr()->GetDef(id)->type_id(), input_id_to_fresh_id_map.at(id), opt::Instruction::OperandList())); // If the input id is an irrelevant-valued variable, the same should be true // of the corresponding parameter. - if (fact_manager->PointeeValueIsIrrelevant(id)) { - fact_manager->AddFactValueOfPointeeIsIrrelevant( - input_id_to_fresh_id_map.at(id)); + if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant( + id)) { + transformation_context->GetFactManager() + ->AddFactValueOfPointeeIsIrrelevant(input_id_to_fresh_id_map.at(id)); } } @@ -629,31 +637,32 @@ TransformationOutlineFunction::PrepareFunctionPrototype( } void TransformationOutlineFunction::UpdateModuleIdBoundForFreshIds( - opt::IRContext* context, + opt::IRContext* ir_context, const std::map& input_id_to_fresh_id_map, const std::map& output_id_to_fresh_id_map) const { // Enlarge the module's id bound as needed to accommodate the various fresh // ids associated with the transformation. fuzzerutil::UpdateModuleIdBound( - context, message_.new_function_struct_return_type_id()); - fuzzerutil::UpdateModuleIdBound(context, message_.new_function_type_id()); - fuzzerutil::UpdateModuleIdBound(context, message_.new_function_id()); - fuzzerutil::UpdateModuleIdBound(context, + ir_context, message_.new_function_struct_return_type_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.new_function_type_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.new_function_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.new_function_region_entry_block()); - fuzzerutil::UpdateModuleIdBound(context, message_.new_caller_result_id()); - fuzzerutil::UpdateModuleIdBound(context, message_.new_callee_result_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.new_caller_result_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.new_callee_result_id()); for (auto& entry : input_id_to_fresh_id_map) { - fuzzerutil::UpdateModuleIdBound(context, entry.second); + fuzzerutil::UpdateModuleIdBound(ir_context, entry.second); } for (auto& entry : output_id_to_fresh_id_map) { - fuzzerutil::UpdateModuleIdBound(context, entry.second); + fuzzerutil::UpdateModuleIdBound(ir_context, entry.second); } } void TransformationOutlineFunction::RemapInputAndOutputIdsInRegion( - opt::IRContext* context, const opt::BasicBlock& original_region_exit_block, + opt::IRContext* ir_context, + const opt::BasicBlock& original_region_exit_block, const std::set& region_blocks, const std::vector& region_input_ids, const std::vector& region_output_ids, @@ -664,11 +673,11 @@ void TransformationOutlineFunction::RemapInputAndOutputIdsInRegion( // This is done by considering each region input id in turn. for (uint32_t id : region_input_ids) { // We then consider each use of the input id. - context->get_def_use_mgr()->ForEachUse( - id, [context, id, &input_id_to_fresh_id_map, region_blocks]( + ir_context->get_def_use_mgr()->ForEachUse( + id, [ir_context, id, &input_id_to_fresh_id_map, region_blocks]( opt::Instruction* use, uint32_t operand_index) { // Find the block in which this use of the input id occurs. - opt::BasicBlock* use_block = context->get_instr_block(use); + opt::BasicBlock* use_block = ir_context->get_instr_block(use); // We want to rewrite the use id if its block occurs in the outlined // region. if (region_blocks.count(use_block) != 0) { @@ -684,12 +693,12 @@ void TransformationOutlineFunction::RemapInputAndOutputIdsInRegion( // This is done by considering each region output id in turn. for (uint32_t id : region_output_ids) { // First consider each use of the output id and update the relevant uses. - context->get_def_use_mgr()->ForEachUse( - id, - [context, &original_region_exit_block, id, &output_id_to_fresh_id_map, - region_blocks](opt::Instruction* use, uint32_t operand_index) { + ir_context->get_def_use_mgr()->ForEachUse( + id, [ir_context, &original_region_exit_block, id, + &output_id_to_fresh_id_map, + region_blocks](opt::Instruction* use, uint32_t operand_index) { // Find the block in which this use of the output id occurs. - auto use_block = context->get_instr_block(use); + auto use_block = ir_context->get_instr_block(use); // We want to rewrite the use id if its block occurs in the outlined // region, with one exception: the terminator of the exit block of // the region is going to remain in the original function, so if the @@ -710,7 +719,7 @@ void TransformationOutlineFunction::RemapInputAndOutputIdsInRegion( // defines the corresponding fresh id. We do this after changing all the // uses so that the definition of the original id is still registered when // we analyse its uses. - context->get_def_use_mgr()->GetDef(id)->SetResultId( + ir_context->get_def_use_mgr()->GetDef(id)->SetResultId( output_id_to_fresh_id_map.at(id)); } } @@ -721,8 +730,8 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( const std::set& region_blocks, const std::vector& region_output_ids, const std::map& output_id_to_fresh_id_map, - opt::IRContext* context, opt::Function* outlined_function, - FactManager* fact_manager) const { + opt::IRContext* ir_context, opt::Function* outlined_function, + TransformationContext* transformation_context) const { // When we create the exit block for the outlined region, we use this pointer // to track of it so that we can manipulate it later. opt::BasicBlock* outlined_region_exit_block = nullptr; @@ -732,14 +741,16 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( // |message_.new_function_region_entry_block| as its id. std::unique_ptr outlined_region_entry_block = MakeUnique(MakeUnique( - context, SpvOpLabel, 0, message_.new_function_region_entry_block(), + ir_context, SpvOpLabel, 0, message_.new_function_region_entry_block(), opt::Instruction::OperandList())); outlined_region_entry_block->SetParent(outlined_function); // If the original region's entry block was dead, the outlined region's entry // block is also dead. - if (fact_manager->BlockIsDead(original_region_entry_block.id())) { - fact_manager->AddFactBlockIsDead(outlined_region_entry_block->id()); + if (transformation_context->GetFactManager()->BlockIsDead( + original_region_entry_block.id())) { + transformation_context->GetFactManager()->AddFactBlockIsDead( + outlined_region_entry_block->id()); } if (&original_region_entry_block == &original_region_exit_block) { @@ -748,7 +759,7 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( for (auto& inst : original_region_entry_block) { outlined_region_entry_block->AddInstruction( - std::unique_ptr(inst.Clone(context))); + std::unique_ptr(inst.Clone(ir_context))); } outlined_function->AddBasicBlock(std::move(outlined_region_entry_block)); @@ -767,7 +778,7 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( } // Clone the block so that it can be added to the new function. auto cloned_block = - std::unique_ptr(block_it->Clone(context)); + std::unique_ptr(block_it->Clone(ir_context)); // If this is the region's exit block, then the cloned block is the outlined // region's exit block. @@ -823,7 +834,7 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( // The case where there are no region output ids is simple: we just add // OpReturn. outlined_region_exit_block->AddInstruction(MakeUnique( - context, SpvOpReturn, 0, 0, opt::Instruction::OperandList())); + ir_context, SpvOpReturn, 0, 0, opt::Instruction::OperandList())); } else { // In the case where there are output ids, we add an OpCompositeConstruct // instruction to pack all the output values into a struct, and then an @@ -834,21 +845,21 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( {SPV_OPERAND_TYPE_ID, {output_id_to_fresh_id_map.at(id)}}); } outlined_region_exit_block->AddInstruction(MakeUnique( - context, SpvOpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, message_.new_function_struct_return_type_id(), message_.new_callee_result_id(), struct_member_operands)); outlined_region_exit_block->AddInstruction(MakeUnique( - context, SpvOpReturnValue, 0, 0, + ir_context, SpvOpReturnValue, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.new_callee_result_id()}}}))); } outlined_function->SetFunctionEnd(MakeUnique( - context, SpvOpFunctionEnd, 0, 0, opt::Instruction::OperandList())); + ir_context, SpvOpFunctionEnd, 0, 0, opt::Instruction::OperandList())); } void TransformationOutlineFunction::ShrinkOriginalRegion( - opt::IRContext* context, std::set& region_blocks, + opt::IRContext* ir_context, std::set& region_blocks, const std::vector& region_input_ids, const std::vector& region_output_ids, const std::map& output_id_to_type_id, @@ -912,7 +923,7 @@ void TransformationOutlineFunction::ShrinkOriginalRegion( } original_region_entry_block->AddInstruction(MakeUnique( - context, SpvOpFunctionCall, return_type_id, + ir_context, SpvOpFunctionCall, return_type_id, message_.new_caller_result_id(), function_call_operands)); // If there are output ids, the function call will return a struct. For each @@ -921,7 +932,7 @@ void TransformationOutlineFunction::ShrinkOriginalRegion( for (uint32_t index = 0; index < region_output_ids.size(); ++index) { uint32_t output_id = region_output_ids[index]; original_region_entry_block->AddInstruction(MakeUnique( - context, SpvOpCompositeExtract, output_id_to_type_id.at(output_id), + ir_context, SpvOpCompositeExtract, output_id_to_type_id.at(output_id), output_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.new_caller_result_id()}}, diff --git a/source/fuzz/transformation_outline_function.h b/source/fuzz/transformation_outline_function.h index 57117906..ba439c84 100644 --- a/source/fuzz/transformation_outline_function.h +++ b/source/fuzz/transformation_outline_function.h @@ -19,9 +19,9 @@ #include #include -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -58,8 +58,9 @@ class TransformationOutlineFunction : public Transformation { // defined outside the region but used in the region // - |message_.output_id_to_fresh_id| must contain an entry for every id // defined in the region but used outside the region - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - A new function with id |message_.new_function_id| is added to the module. // - If the region generates output ids, the return type of this function is @@ -95,14 +96,15 @@ class TransformationOutlineFunction : public Transformation { // |message_.new_function_struct_return_type| comprised of all the fresh // output ids (unless the return type is void, in which case no value is // returned. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; // Returns the set of blocks dominated by |entry_block| and post-dominated // by |exit_block|. static std::set GetRegionBlocks( - opt::IRContext* context, opt::BasicBlock* entry_block, + opt::IRContext* ir_context, opt::BasicBlock* entry_block, opt::BasicBlock* exit_block); // Yields ids that are used in |region_set| and that are either parameters @@ -114,7 +116,7 @@ class TransformationOutlineFunction : public Transformation { // - id uses in OpPhi instructions in |region_entry_block| are ignored // - id uses in the terminator instruction of |region_exit_block| are ignored static std::vector GetRegionInputIds( - opt::IRContext* context, const std::set& region_set, + opt::IRContext* ir_context, const std::set& region_set, opt::BasicBlock* region_exit_block); // Yields all ids that are defined in |region_set| and used outside @@ -124,14 +126,14 @@ class TransformationOutlineFunction : public Transformation { // - ids defined in the region and used in the terminator of // |region_exit_block| count as output ids static std::vector GetRegionOutputIds( - opt::IRContext* context, const std::set& region_set, + opt::IRContext* ir_context, const std::set& region_set, opt::BasicBlock* region_exit_block); private: // Ensures that the module's id bound is at least the maximum of any fresh id // associated with the transformation. void UpdateModuleIdBoundForFreshIds( - opt::IRContext* context, + opt::IRContext* ir_context, const std::map& input_id_to_fresh_id_map, const std::map& output_id_to_fresh_id_map) const; @@ -142,7 +144,7 @@ class TransformationOutlineFunction : public Transformation { // modified, and |original_region_exit_block| allows for some special cases // where ids should not be remapped. void RemapInputAndOutputIdsInRegion( - opt::IRContext* context, + opt::IRContext* ir_context, const opt::BasicBlock& original_region_exit_block, const std::set& region_blocks, const std::vector& region_input_ids, @@ -160,12 +162,14 @@ class TransformationOutlineFunction : public Transformation { // are already present). // // Facts about the function containing the outlined region that are relevant - // to the new function are propagated via |fact_manager|. + // to the new function are propagated via the vact manager in + // |transformation_context|. std::unique_ptr PrepareFunctionPrototype( const std::vector& region_input_ids, const std::vector& region_output_ids, const std::map& input_id_to_fresh_id_map, - opt::IRContext* context, FactManager* fact_manager) const; + opt::IRContext* ir_context, + TransformationContext* transformation_context) const; // Creates the body of the outlined function by cloning blocks from the // original region, given by |region_blocks|, adapting the cloned version @@ -174,17 +178,17 @@ class TransformationOutlineFunction : public Transformation { // clone. Parameters |region_output_ids| and |output_id_to_fresh_id_map| are // used to determine what the function should return. // - // The |fact_manager| argument allow facts about blocks being outlined, e.g. - // whether they are dead blocks, to be asserted about blocks that get created - // during outlining. + // The |transformation_context| argument allow facts about blocks being + // outlined, e.g. whether they are dead blocks, to be asserted about blocks + // that get created during outlining. void PopulateOutlinedFunction( const opt::BasicBlock& original_region_entry_block, const opt::BasicBlock& original_region_exit_block, const std::set& region_blocks, const std::vector& region_output_ids, const std::map& output_id_to_fresh_id_map, - opt::IRContext* context, opt::Function* outlined_function, - FactManager* fact_manager) const; + opt::IRContext* ir_context, opt::Function* outlined_function, + TransformationContext* transformation_context) const; // Shrinks the outlined region, given by |region_blocks|, down to the single // block |original_region_entry_block|. This block is itself shrunk to just @@ -203,7 +207,7 @@ class TransformationOutlineFunction : public Transformation { // function is called, this information cannot be gotten from the def-use // manager. void ShrinkOriginalRegion( - opt::IRContext* context, std::set& region_blocks, + opt::IRContext* ir_context, std::set& region_blocks, const std::vector& region_input_ids, const std::vector& region_output_ids, const std::map& output_id_to_type_id, diff --git a/source/fuzz/transformation_permute_function_parameters.cpp b/source/fuzz/transformation_permute_function_parameters.cpp index 21415335..0f1220e2 100644 --- a/source/fuzz/transformation_permute_function_parameters.cpp +++ b/source/fuzz/transformation_permute_function_parameters.cpp @@ -40,17 +40,17 @@ TransformationPermuteFunctionParameters:: } bool TransformationPermuteFunctionParameters::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // Check that function exists const auto* function = - fuzzerutil::FindFunction(context, message_.function_id()); + fuzzerutil::FindFunction(ir_context, message_.function_id()); if (!function || function->DefInst().opcode() != SpvOpFunction || - fuzzerutil::FunctionIsEntryPoint(context, function->result_id())) { + fuzzerutil::FunctionIsEntryPoint(ir_context, function->result_id())) { return false; } // Check that permutation has valid indices - const auto* function_type = fuzzerutil::GetFunctionType(context, function); + const auto* function_type = fuzzerutil::GetFunctionType(ir_context, function); assert(function_type && "Function type is null"); const auto& permutation = message_.permutation(); @@ -83,7 +83,7 @@ bool TransformationPermuteFunctionParameters::IsApplicable( // - Has the same result type as the old one // - Order of arguments is permuted auto new_type_id = message_.new_type_id(); - const auto* new_type = context->get_def_use_mgr()->GetDef(new_type_id); + const auto* new_type = ir_context->get_def_use_mgr()->GetDef(new_type_id); if (!new_type || new_type->opcode() != SpvOpTypeFunction || new_type->NumInOperands() != function_type->NumInOperands()) { @@ -109,14 +109,14 @@ bool TransformationPermuteFunctionParameters::IsApplicable( } void TransformationPermuteFunctionParameters::Apply( - opt::IRContext* context, FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Retrieve all data from the message uint32_t function_id = message_.function_id(); uint32_t new_type_id = message_.new_type_id(); const auto& permutation = message_.permutation(); // Find the function that will be transformed - auto* function = fuzzerutil::FindFunction(context, function_id); + auto* function = fuzzerutil::FindFunction(ir_context, function_id); assert(function && "Can't find the function"); // Change function's type @@ -149,7 +149,7 @@ void TransformationPermuteFunctionParameters::Apply( }); // Fix all OpFunctionCall instructions - context->get_def_use_mgr()->ForEachUser( + ir_context->get_def_use_mgr()->ForEachUser( &function->DefInst(), [function_id, &permutation](opt::Instruction* call) { if (call->opcode() != SpvOpFunctionCall || @@ -170,7 +170,8 @@ void TransformationPermuteFunctionParameters::Apply( }); // Make sure our changes are analyzed - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationPermuteFunctionParameters::ToMessage() diff --git a/source/fuzz/transformation_permute_function_parameters.h b/source/fuzz/transformation_permute_function_parameters.h index c67a7356..994e4c24 100644 --- a/source/fuzz/transformation_permute_function_parameters.h +++ b/source/fuzz/transformation_permute_function_parameters.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_PERMUTE_FUNCTION_PARAMETERS_H_ #define SOURCE_FUZZ_TRANSFORMATION_PERMUTE_FUNCTION_PARAMETERS_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -40,14 +40,16 @@ class TransformationPermuteFunctionParameters : public Transformation { // - function's arguments are permuted according to |permutation| vector // - |permutation| is a set of [0..(n - 1)], where n is a number of arguments // to the function - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - OpFunction instruction with |result_id == function_id| is changed. // Its arguments are permuted according to the |permutation| vector // - Changed function gets a new type specified by |type_id| // - Calls to the function are adjusted accordingly - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp index 72d9b228..d6f17fc3 100644 --- a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp +++ b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp @@ -128,15 +128,15 @@ TransformationReplaceBooleanConstantWithConstantBinary:: } bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The id for the binary result must be fresh - if (!fuzzerutil::IsFreshId(context, + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id_for_binary_operation())) { return false; } // The used id must be for a boolean constant - auto boolean_constant = context->get_def_use_mgr()->GetDef( + auto boolean_constant = ir_context->get_def_use_mgr()->GetDef( message_.id_use_descriptor().id_of_interest()); if (!boolean_constant) { return false; @@ -148,7 +148,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( // The left-hand-side id must correspond to a constant instruction. auto lhs_constant_inst = - context->get_def_use_mgr()->GetDef(message_.lhs_id()); + ir_context->get_def_use_mgr()->GetDef(message_.lhs_id()); if (!lhs_constant_inst) { return false; } @@ -158,7 +158,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( // The right-hand-side id must correspond to a constant instruction. auto rhs_constant_inst = - context->get_def_use_mgr()->GetDef(message_.rhs_id()); + ir_context->get_def_use_mgr()->GetDef(message_.rhs_id()); if (!rhs_constant_inst) { return false; } @@ -173,9 +173,9 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( // The expression 'LHS opcode RHS' must evaluate to the boolean constant. auto lhs_constant = - context->get_constant_mgr()->FindDeclaredConstant(message_.lhs_id()); + ir_context->get_constant_mgr()->FindDeclaredConstant(message_.lhs_id()); auto rhs_constant = - context->get_constant_mgr()->FindDeclaredConstant(message_.rhs_id()); + ir_context->get_constant_mgr()->FindDeclaredConstant(message_.rhs_id()); bool expected_result = (boolean_constant->opcode() == SpvOpConstantTrue); const auto binary_opcode = static_cast(message_.opcode()); @@ -238,7 +238,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( // The id use descriptor must identify some instruction auto instruction = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); if (instruction == nullptr) { return false; } @@ -262,24 +262,25 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( } void TransformationReplaceBooleanConstantWithConstantBinary::Apply( - opt::IRContext* context, FactManager* fact_manager) const { - ApplyWithResult(context, fact_manager); + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { + ApplyWithResult(ir_context, transformation_context); } opt::Instruction* TransformationReplaceBooleanConstantWithConstantBinary::ApplyWithResult( - opt::IRContext* context, FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::analysis::Bool bool_type; opt::Instruction::OperandList operands = { {SPV_OPERAND_TYPE_ID, {message_.lhs_id()}}, {SPV_OPERAND_TYPE_ID, {message_.rhs_id()}}}; auto binary_instruction = MakeUnique( - context, static_cast(message_.opcode()), - context->get_type_mgr()->GetId(&bool_type), + ir_context, static_cast(message_.opcode()), + ir_context->get_type_mgr()->GetId(&bool_type), message_.fresh_id_for_binary_operation(), operands); opt::Instruction* result = binary_instruction.get(); auto instruction_containing_constant_use = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); // We want to insert the new instruction before the instruction that contains // the use of the boolean, but we need to go backwards one more instruction if @@ -298,9 +299,10 @@ TransformationReplaceBooleanConstantWithConstantBinary::ApplyWithResult( instruction_containing_constant_use->SetInOperand( message_.id_use_descriptor().in_operand_index(), {message_.fresh_id_for_binary_operation()}); - fuzzerutil::UpdateModuleIdBound(context, + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id_for_binary_operation()); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); return result; } diff --git a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h index f74cd8d1..3abb4854 100644 --- a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h +++ b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_REPLACE_BOOLEAN_CONSTANT_WITH_CONSTANT_BINARY_H_ #define SOURCE_FUZZ_TRANSFORMATION_REPLACE_BOOLEAN_CONSTANT_WITH_CONSTANT_BINARY_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -49,20 +49,23 @@ class TransformationReplaceBooleanConstantWithConstantBinary // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2902): consider // replacing a boolean in an OpPhi by adding a binary operator instruction // to the parent block for the OpPhi. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // A new instruction is added before the boolean constant usage that computes // the result of applying |message_.opcode| to |message_.lhs_id| and // |message_.rhs_id| is added, with result id // |message_.fresh_id_for_binary_operation|. The boolean constant usage is // replaced with this result id. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; // The same as Apply, except that the newly-added binary instruction is // returned. - opt::Instruction* ApplyWithResult(opt::IRContext* context, - FactManager* fact_manager) const; + opt::Instruction* ApplyWithResult( + opt::IRContext* ir_context, + TransformationContext* transformation_context) const; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_replace_constant_with_uniform.cpp b/source/fuzz/transformation_replace_constant_with_uniform.cpp index 8e0e4e5a..a8f94954 100644 --- a/source/fuzz/transformation_replace_constant_with_uniform.cpp +++ b/source/fuzz/transformation_replace_constant_with_uniform.cpp @@ -39,12 +39,12 @@ TransformationReplaceConstantWithUniform:: std::unique_ptr TransformationReplaceConstantWithUniform::MakeAccessChainInstruction( - spvtools::opt::IRContext* context, uint32_t constant_type_id) const { + spvtools::opt::IRContext* ir_context, uint32_t constant_type_id) const { // The input operands for the access chain. opt::Instruction::OperandList operands_for_access_chain; opt::Instruction* uniform_variable = - FindUniformVariable(message_.uniform_descriptor(), context, false); + FindUniformVariable(message_.uniform_descriptor(), ir_context, false); // The first input operand is the id of the uniform variable. operands_for_access_chain.push_back( @@ -56,42 +56,43 @@ TransformationReplaceConstantWithUniform::MakeAccessChainInstruction( // instruction ids as operands. opt::analysis::Integer int_type(32, true); auto registered_int_type = - context->get_type_mgr()->GetRegisteredType(&int_type)->AsInteger(); - auto int_type_id = context->get_type_mgr()->GetId(&int_type); + ir_context->get_type_mgr()->GetRegisteredType(&int_type)->AsInteger(); + auto int_type_id = ir_context->get_type_mgr()->GetId(&int_type); for (auto index : message_.uniform_descriptor().index()) { opt::analysis::IntConstant int_constant(registered_int_type, {index}); - auto constant_id = context->get_constant_mgr()->FindDeclaredConstant( + auto constant_id = ir_context->get_constant_mgr()->FindDeclaredConstant( &int_constant, int_type_id); operands_for_access_chain.push_back({SPV_OPERAND_TYPE_ID, {constant_id}}); } // The type id for the access chain is a uniform pointer with base type // matching the given constant id type. - auto type_and_pointer_type = context->get_type_mgr()->GetTypeAndPointerType( - constant_type_id, SpvStorageClassUniform); + auto type_and_pointer_type = + ir_context->get_type_mgr()->GetTypeAndPointerType(constant_type_id, + SpvStorageClassUniform); assert(type_and_pointer_type.first != nullptr); assert(type_and_pointer_type.second != nullptr); auto pointer_to_uniform_constant_type_id = - context->get_type_mgr()->GetId(type_and_pointer_type.second.get()); + ir_context->get_type_mgr()->GetId(type_and_pointer_type.second.get()); return MakeUnique( - context, SpvOpAccessChain, pointer_to_uniform_constant_type_id, + ir_context, SpvOpAccessChain, pointer_to_uniform_constant_type_id, message_.fresh_id_for_access_chain(), operands_for_access_chain); } std::unique_ptr TransformationReplaceConstantWithUniform::MakeLoadInstruction( - spvtools::opt::IRContext* context, uint32_t constant_type_id) const { + spvtools::opt::IRContext* ir_context, uint32_t constant_type_id) const { opt::Instruction::OperandList operands_for_load = { {SPV_OPERAND_TYPE_ID, {message_.fresh_id_for_access_chain()}}}; - return MakeUnique(context, SpvOpLoad, constant_type_id, + return MakeUnique(ir_context, SpvOpLoad, constant_type_id, message_.fresh_id_for_load(), operands_for_load); } bool TransformationReplaceConstantWithUniform::IsApplicable( - spvtools::opt::IRContext* context, - const spvtools::fuzz::FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // The following is really an invariant of the transformation rather than // merely a requirement of the precondition. We check it here since we cannot // check it in the message_ constructor. @@ -99,16 +100,17 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( "Fresh ids for access chain and load result cannot be the same."); // The ids for the access chain and load instructions must both be fresh. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id_for_access_chain())) { + if (!fuzzerutil::IsFreshId(ir_context, + message_.fresh_id_for_access_chain())) { return false; } - if (!fuzzerutil::IsFreshId(context, message_.fresh_id_for_load())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id_for_load())) { return false; } // The id specified in the id use descriptor must be that of a declared scalar // constant. - auto declared_constant = context->get_constant_mgr()->FindDeclaredConstant( + auto declared_constant = ir_context->get_constant_mgr()->FindDeclaredConstant( message_.id_use_descriptor().id_of_interest()); if (!declared_constant) { return false; @@ -120,13 +122,13 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( // The fact manager needs to believe that the uniform data element described // by the uniform buffer element descriptor will hold a scalar value. auto constant_id_associated_with_uniform = - fact_manager.GetConstantFromUniformDescriptor( - context, message_.uniform_descriptor()); + transformation_context.GetFactManager()->GetConstantFromUniformDescriptor( + ir_context, message_.uniform_descriptor()); if (!constant_id_associated_with_uniform) { return false; } auto constant_associated_with_uniform = - context->get_constant_mgr()->FindDeclaredConstant( + ir_context->get_constant_mgr()->FindDeclaredConstant( constant_id_associated_with_uniform); assert(constant_associated_with_uniform && "The constant should be present in the module."); @@ -149,7 +151,7 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( // The id use descriptor must identify some instruction with respect to the // module. auto instruction_using_constant = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); if (!instruction_using_constant) { return false; } @@ -165,23 +167,23 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( // replace with a uniform. opt::analysis::Pointer pointer_to_type_of_constant(declared_constant->type(), SpvStorageClassUniform); - if (!context->get_type_mgr()->GetId(&pointer_to_type_of_constant)) { + if (!ir_context->get_type_mgr()->GetId(&pointer_to_type_of_constant)) { return false; } // In order to index into the uniform, the module has got to contain the int32 // type, plus an OpConstant for each of the indices of interest. opt::analysis::Integer int_type(32, true); - if (!context->get_type_mgr()->GetId(&int_type)) { + if (!ir_context->get_type_mgr()->GetId(&int_type)) { return false; } auto registered_int_type = - context->get_type_mgr()->GetRegisteredType(&int_type)->AsInteger(); - auto int_type_id = context->get_type_mgr()->GetId(&int_type); + ir_context->get_type_mgr()->GetRegisteredType(&int_type)->AsInteger(); + auto int_type_id = ir_context->get_type_mgr()->GetId(&int_type); for (auto index : message_.uniform_descriptor().index()) { opt::analysis::IntConstant int_constant(registered_int_type, {index}); - if (!context->get_constant_mgr()->FindDeclaredConstant(&int_constant, - int_type_id)) { + if (!ir_context->get_constant_mgr()->FindDeclaredConstant(&int_constant, + int_type_id)) { return false; } } @@ -190,11 +192,11 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( } void TransformationReplaceConstantWithUniform::Apply( - spvtools::opt::IRContext* context, - spvtools::fuzz::FactManager* /*unused*/) const { + spvtools::opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { // Get the instruction that contains the id use we wish to replace. auto instruction_containing_constant_use = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); assert(instruction_containing_constant_use && "Precondition requires that the id use can be found."); assert(instruction_containing_constant_use->GetSingleWordInOperand( @@ -204,17 +206,17 @@ void TransformationReplaceConstantWithUniform::Apply( // The id of the type for the constant whose use we wish to replace. auto constant_type_id = - context->get_def_use_mgr() + ir_context->get_def_use_mgr() ->GetDef(message_.id_use_descriptor().id_of_interest()) ->type_id(); // Add an access chain instruction to target the uniform element. instruction_containing_constant_use->InsertBefore( - MakeAccessChainInstruction(context, constant_type_id)); + MakeAccessChainInstruction(ir_context, constant_type_id)); // Add a load from this access chain. instruction_containing_constant_use->InsertBefore( - MakeLoadInstruction(context, constant_type_id)); + MakeLoadInstruction(ir_context, constant_type_id)); // Adjust the instruction containing the usage of the constant so that this // usage refers instead to the result of the load. @@ -223,11 +225,12 @@ void TransformationReplaceConstantWithUniform::Apply( {message_.fresh_id_for_load()}); // Update the module id bound to reflect the new instructions. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id_for_load()); - fuzzerutil::UpdateModuleIdBound(context, + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id_for_load()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id_for_access_chain()); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationReplaceConstantWithUniform::ToMessage() diff --git a/source/fuzz/transformation_replace_constant_with_uniform.h b/source/fuzz/transformation_replace_constant_with_uniform.h index ed354b1d..b72407c8 100644 --- a/source/fuzz/transformation_replace_constant_with_uniform.h +++ b/source/fuzz/transformation_replace_constant_with_uniform.h @@ -58,8 +58,9 @@ class TransformationReplaceConstantWithUniform : public Transformation { // - According to the fact manager, the uniform data element specified by // |message_.uniform_descriptor| holds a value with the same type and // value as %C - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - Introduces two new instructions: // - An access chain targeting the uniform data element specified by @@ -68,7 +69,8 @@ class TransformationReplaceConstantWithUniform : public Transformation { // - A load from this access chain, with id |message_.fresh_id_for_load| // - Replaces the id use specified by |message_.id_use_descriptor| with // |message_.fresh_id_for_load| - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -76,11 +78,11 @@ class TransformationReplaceConstantWithUniform : public Transformation { // Helper method to create an access chain for the uniform element associated // with the transformation. std::unique_ptr MakeAccessChainInstruction( - spvtools::opt::IRContext* context, uint32_t constant_type_id) const; + spvtools::opt::IRContext* ir_context, uint32_t constant_type_id) const; // Helper to create a load instruction. std::unique_ptr MakeLoadInstruction( - spvtools::opt::IRContext* context, uint32_t constant_type_id) const; + spvtools::opt::IRContext* ir_context, uint32_t constant_type_id) const; protobufs::TransformationReplaceConstantWithUniform message_; }; diff --git a/source/fuzz/transformation_replace_id_with_synonym.cpp b/source/fuzz/transformation_replace_id_with_synonym.cpp index 88c977a2..87194c8e 100644 --- a/source/fuzz/transformation_replace_id_with_synonym.cpp +++ b/source/fuzz/transformation_replace_id_with_synonym.cpp @@ -37,28 +37,29 @@ TransformationReplaceIdWithSynonym::TransformationReplaceIdWithSynonym( } bool TransformationReplaceIdWithSynonym::IsApplicable( - spvtools::opt::IRContext* context, - const spvtools::fuzz::FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { auto id_of_interest = message_.id_use_descriptor().id_of_interest(); // Does the fact manager know about the synonym? auto data_descriptor_for_synonymous_id = MakeDataDescriptor(message_.synonymous_id(), {}); - if (!fact_manager.IsSynonymous(MakeDataDescriptor(id_of_interest, {}), - data_descriptor_for_synonymous_id, context)) { + if (!transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(id_of_interest, {}), + data_descriptor_for_synonymous_id, ir_context)) { return false; } // Does the id use descriptor in the transformation identify an instruction? auto use_instruction = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); if (!use_instruction) { return false; } // Is the use suitable for being replaced in principle? if (!UseCanBeReplacedWithSynonym( - context, use_instruction, + ir_context, use_instruction, message_.id_use_descriptor().in_operand_index())) { return false; } @@ -66,19 +67,21 @@ bool TransformationReplaceIdWithSynonym::IsApplicable( // The transformation is applicable if the synonymous id is available at the // use point. return fuzzerutil::IdIsAvailableAtUse( - context, use_instruction, message_.id_use_descriptor().in_operand_index(), + ir_context, use_instruction, + message_.id_use_descriptor().in_operand_index(), message_.synonymous_id()); } void TransformationReplaceIdWithSynonym::Apply( - spvtools::opt::IRContext* context, - spvtools::fuzz::FactManager* /*unused*/) const { + spvtools::opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { auto instruction_to_change = - FindInstructionContainingUse(message_.id_use_descriptor(), context); + FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); instruction_to_change->SetInOperand( message_.id_use_descriptor().in_operand_index(), {message_.synonymous_id()}); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationReplaceIdWithSynonym::ToMessage() @@ -89,7 +92,7 @@ protobufs::Transformation TransformationReplaceIdWithSynonym::ToMessage() } bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym( - opt::IRContext* context, opt::Instruction* use_instruction, + opt::IRContext* ir_context, opt::Instruction* use_instruction, uint32_t use_in_operand_index) { if (use_instruction->opcode() == SpvOpAccessChain && use_in_operand_index > 0) { @@ -98,10 +101,10 @@ bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym( // synonym, as the use needs to be an OpConstant. // Get the top-level composite type that is being accessed. - auto object_being_accessed = context->get_def_use_mgr()->GetDef( + auto object_being_accessed = ir_context->get_def_use_mgr()->GetDef( use_instruction->GetSingleWordInOperand(0)); auto pointer_type = - context->get_type_mgr()->GetType(object_being_accessed->type_id()); + ir_context->get_type_mgr()->GetType(object_being_accessed->type_id()); assert(pointer_type->AsPointer()); auto composite_type_being_accessed = pointer_type->AsPointer()->pointee_type(); @@ -124,7 +127,7 @@ bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym( composite_type_being_accessed->AsArray()->element_type(); } else { assert(composite_type_being_accessed->AsStruct()); - auto constant_index_instruction = context->get_def_use_mgr()->GetDef( + auto constant_index_instruction = ir_context->get_def_use_mgr()->GetDef( use_instruction->GetSingleWordInOperand(index_in_operand)); assert(constant_index_instruction->opcode() == SpvOpConstant); uint32_t member_index = @@ -149,16 +152,16 @@ bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym( // type. // Get the definition of the function being called. - auto function = context->get_def_use_mgr()->GetDef( + auto function = ir_context->get_def_use_mgr()->GetDef( use_instruction->GetSingleWordInOperand(0)); // From the function definition, get the function type. - auto function_type = - context->get_def_use_mgr()->GetDef(function->GetSingleWordInOperand(1)); + auto function_type = ir_context->get_def_use_mgr()->GetDef( + function->GetSingleWordInOperand(1)); // OpTypeFunction's 0-th input operand is the function return type, and the // function argument types follow. Because the arguments to OpFunctionCall // start from input operand 1, we can use |use_in_operand_index| to get the // type associated with this function argument. - auto parameter_type = context->get_type_mgr()->GetType( + auto parameter_type = ir_context->get_type_mgr()->GetType( function_type->GetSingleWordInOperand(use_in_operand_index)); if (parameter_type->AsPointer()) { return false; diff --git a/source/fuzz/transformation_replace_id_with_synonym.h b/source/fuzz/transformation_replace_id_with_synonym.h index 48132c1e..a5a9dfda 100644 --- a/source/fuzz/transformation_replace_id_with_synonym.h +++ b/source/fuzz/transformation_replace_id_with_synonym.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_REPLACE_ID_WITH_SYNONYM_H_ #define SOURCE_FUZZ_TRANSFORMATION_REPLACE_ID_WITH_SYNONYM_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -42,12 +42,14 @@ class TransformationReplaceIdWithSynonym : public Transformation { // - The id must not be a pointer argument to a function call (because the // synonym might not be a memory object declaration). // - |fresh_id_for_temporary| must be 0. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Replaces the use identified by |message_.id_use_descriptor| with the // synonymous id identified by |message_.synonymous_id|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -58,7 +60,7 @@ class TransformationReplaceIdWithSynonym : public Transformation { // indices must be constants, so it is dangerous to replace them. // - the id use is not a pointer function call argument, on which there are // restrictions that make replacement problematic. - static bool UseCanBeReplacedWithSynonym(opt::IRContext* context, + static bool UseCanBeReplacedWithSynonym(opt::IRContext* ir_context, opt::Instruction* use_instruction, uint32_t use_in_operand_index); diff --git a/source/fuzz/transformation_set_function_control.cpp b/source/fuzz/transformation_set_function_control.cpp index d2b61f19..d01e7434 100644 --- a/source/fuzz/transformation_set_function_control.cpp +++ b/source/fuzz/transformation_set_function_control.cpp @@ -28,9 +28,9 @@ TransformationSetFunctionControl::TransformationSetFunctionControl( } bool TransformationSetFunctionControl::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { opt::Instruction* function_def_instruction = - FindFunctionDefInstruction(context); + FindFunctionDefInstruction(ir_context); if (!function_def_instruction) { // The given function id does not correspond to any function. return false; @@ -69,10 +69,10 @@ bool TransformationSetFunctionControl::IsApplicable( return true; } -void TransformationSetFunctionControl::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { +void TransformationSetFunctionControl::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction* function_def_instruction = - FindFunctionDefInstruction(context); + FindFunctionDefInstruction(ir_context); function_def_instruction->SetInOperand(0, {message_.function_control()}); } @@ -83,11 +83,11 @@ protobufs::Transformation TransformationSetFunctionControl::ToMessage() const { } opt::Instruction* TransformationSetFunctionControl ::FindFunctionDefInstruction( - opt::IRContext* context) const { + opt::IRContext* ir_context) const { // Look through all functions for a function whose defining instruction's // result id matches |message_.function_id|, returning the defining // instruction if found. - for (auto& function : *context->module()) { + for (auto& function : *ir_context->module()) { if (function.DefInst().result_id() == message_.function_id()) { return &function.DefInst(); } diff --git a/source/fuzz/transformation_set_function_control.h b/source/fuzz/transformation_set_function_control.h index 0526bb9c..5109f748 100644 --- a/source/fuzz/transformation_set_function_control.h +++ b/source/fuzz/transformation_set_function_control.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SET_FUNCTION_CONTROL_H_ #define SOURCE_FUZZ_TRANSFORMATION_SET_FUNCTION_CONTROL_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -37,17 +37,20 @@ class TransformationSetFunctionControl : public Transformation { // at most one of 'Inline' or 'DontInline', and that may not contain 'Pure' // (respectively 'Const') unless the existing function control mask contains // 'Pure' (respectively 'Const'). - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // The function control operand of instruction |message_.function_id| is // over-written with |message_.function_control|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; private: - opt::Instruction* FindFunctionDefInstruction(opt::IRContext* context) const; + opt::Instruction* FindFunctionDefInstruction( + opt::IRContext* ir_context) const; protobufs::TransformationSetFunctionControl message_; }; diff --git a/source/fuzz/transformation_set_loop_control.cpp b/source/fuzz/transformation_set_loop_control.cpp index 9062f174..845ac69e 100644 --- a/source/fuzz/transformation_set_loop_control.cpp +++ b/source/fuzz/transformation_set_loop_control.cpp @@ -31,9 +31,9 @@ TransformationSetLoopControl::TransformationSetLoopControl( } bool TransformationSetLoopControl::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // |message_.block_id| must identify a block that ends with OpLoopMerge. - auto block = context->get_instr_block(message_.block_id()); + auto block = ir_context->get_instr_block(message_.block_id()); if (!block) { return false; } @@ -79,7 +79,8 @@ bool TransformationSetLoopControl::IsApplicable( if ((message_.loop_control() & (SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask)) && - !(PeelCountIsSupported(context) && PartialCountIsSupported(context))) { + !(PeelCountIsSupported(ir_context) && + PartialCountIsSupported(ir_context))) { // At least one of PeelCount or PartialCount is used, but the SPIR-V version // in question does not support these loop controls. return false; @@ -104,11 +105,11 @@ bool TransformationSetLoopControl::IsApplicable( (SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask))); } -void TransformationSetLoopControl::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { +void TransformationSetLoopControl::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Grab the loop merge instruction and its associated loop control mask. auto merge_inst = - context->get_instr_block(message_.block_id())->GetMergeInst(); + ir_context->get_instr_block(message_.block_id())->GetMergeInst(); auto existing_loop_control_mask = merge_inst->GetSingleWordInOperand(kLoopControlMaskInOperandIndex); @@ -181,11 +182,11 @@ bool TransformationSetLoopControl::LoopControlBitIsAddedByTransformation( } bool TransformationSetLoopControl::PartialCountIsSupported( - opt::IRContext* context) { + opt::IRContext* ir_context) { // TODO(afd): We capture the universal environments for which this loop // control is definitely not supported. The check should be refined on // demand for other target environments. - switch (context->grammar().target_env()) { + switch (ir_context->grammar().target_env()) { case SPV_ENV_UNIVERSAL_1_0: case SPV_ENV_UNIVERSAL_1_1: case SPV_ENV_UNIVERSAL_1_2: @@ -197,11 +198,11 @@ bool TransformationSetLoopControl::PartialCountIsSupported( } bool TransformationSetLoopControl::PeelCountIsSupported( - opt::IRContext* context) { + opt::IRContext* ir_context) { // TODO(afd): We capture the universal environments for which this loop // control is definitely not supported. The check should be refined on // demand for other target environments. - switch (context->grammar().target_env()) { + switch (ir_context->grammar().target_env()) { case SPV_ENV_UNIVERSAL_1_0: case SPV_ENV_UNIVERSAL_1_1: case SPV_ENV_UNIVERSAL_1_2: diff --git a/source/fuzz/transformation_set_loop_control.h b/source/fuzz/transformation_set_loop_control.h index 28b148ca..f0c364f9 100644 --- a/source/fuzz/transformation_set_loop_control.h +++ b/source/fuzz/transformation_set_loop_control.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SET_LOOP_CONTROL_H_ #define SOURCE_FUZZ_TRANSFORMATION_SET_LOOP_CONTROL_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -38,13 +38,14 @@ class TransformationSetLoopControl : public Transformation { // instruction. // - |message_.loop_control| must be a legal loop control mask that // only uses controls available in the SPIR-V version associated with - // |context|, and must not add loop controls that are only valid in the + // |ir_context|, and must not add loop controls that are only valid in the // presence of guarantees about what the loop does (e.g. MinIterations). // - |message_.peel_count| (respectively |message_.partial_count|) must be // zero PeelCount (respectively PartialCount) is set in // |message_.loop_control|. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - The loop control operand of the OpLoopMergeInstruction in // |message_.block_id| is overwritten with |message_.loop_control|. @@ -52,16 +53,17 @@ class TransformationSetLoopControl : public Transformation { // controls with associated literals that have been removed (e.g. // MinIterations), and any that have been added (PeelCount and/or // PartialCount). - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; // Does the version of SPIR-V being used support the PartialCount loop // control? - static bool PartialCountIsSupported(opt::IRContext* context); + static bool PartialCountIsSupported(opt::IRContext* ir_context); // Does the version of SPIR-V being used support the PeelCount loop control? - static bool PeelCountIsSupported(opt::IRContext* context); + static bool PeelCountIsSupported(opt::IRContext* ir_context); private: // Returns true if and only if |loop_single_bit_mask| is *not* set in diff --git a/source/fuzz/transformation_set_memory_operands_mask.cpp b/source/fuzz/transformation_set_memory_operands_mask.cpp index a14e1a60..131a4994 100644 --- a/source/fuzz/transformation_set_memory_operands_mask.cpp +++ b/source/fuzz/transformation_set_memory_operands_mask.cpp @@ -42,8 +42,7 @@ TransformationSetMemoryOperandsMask::TransformationSetMemoryOperandsMask( } bool TransformationSetMemoryOperandsMask::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { if (message_.memory_operands_mask_index() != 0) { // The following conditions should never be violated, even if // transformations end up being replayed in a different way to the manner in @@ -54,11 +53,11 @@ bool TransformationSetMemoryOperandsMask::IsApplicable( SpvOpCopyMemory || message_.memory_access_instruction().target_instruction_opcode() == SpvOpCopyMemorySized); - assert(MultipleMemoryOperandMasksAreSupported(context)); + assert(MultipleMemoryOperandMasksAreSupported(ir_context)); } auto instruction = - FindInstruction(message_.memory_access_instruction(), context); + FindInstruction(message_.memory_access_instruction(), ir_context); if (!instruction) { return false; } @@ -94,9 +93,9 @@ bool TransformationSetMemoryOperandsMask::IsApplicable( } void TransformationSetMemoryOperandsMask::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/) const { + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto instruction = - FindInstruction(message_.memory_access_instruction(), context); + FindInstruction(message_.memory_access_instruction(), ir_context); auto original_mask_in_operand_index = GetInOperandIndexForMask( *instruction, message_.memory_operands_mask_index()); // Either add a new operand, if no mask operand was already present, or @@ -182,11 +181,11 @@ uint32_t TransformationSetMemoryOperandsMask::GetInOperandIndexForMask( } bool TransformationSetMemoryOperandsMask:: - MultipleMemoryOperandMasksAreSupported(opt::IRContext* context) { + MultipleMemoryOperandMasksAreSupported(opt::IRContext* ir_context) { // TODO(afd): We capture the universal environments for which this loop // control is definitely not supported. The check should be refined on // demand for other target environments. - switch (context->grammar().target_env()) { + switch (ir_context->grammar().target_env()) { case SPV_ENV_UNIVERSAL_1_0: case SPV_ENV_UNIVERSAL_1_1: case SPV_ENV_UNIVERSAL_1_2: diff --git a/source/fuzz/transformation_set_memory_operands_mask.h b/source/fuzz/transformation_set_memory_operands_mask.h index 20ae1457..9f5081bf 100644 --- a/source/fuzz/transformation_set_memory_operands_mask.h +++ b/source/fuzz/transformation_set_memory_operands_mask.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SET_MEMORY_OPERANDS_MASK_H_ #define SOURCE_FUZZ_TRANSFORMATION_SET_MEMORY_OPERANDS_MASK_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -40,14 +40,16 @@ class TransformationSetMemoryOperandsMask : public Transformation { // - |message_.memory_operands_mask| must be identical to the original memory // operands mask, except that Volatile may be added, and Nontemporal may be // toggled. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Replaces the operands mask identified by // |message_.memory_operands_mask_index| in the instruction described by // |message_.memory_access_instruction| with |message_.memory_operands_mask|, // creating an input operand for the mask if no such operand was present. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; @@ -57,7 +59,8 @@ class TransformationSetMemoryOperandsMask : public Transformation { // Does the version of SPIR-V being used support multiple memory operand // masks on relevant memory access instructions? - static bool MultipleMemoryOperandMasksAreSupported(opt::IRContext* context); + static bool MultipleMemoryOperandMasksAreSupported( + opt::IRContext* ir_context); // Helper function to get the input operand index associated with mask number // |mask_index|. This is a bit tricky if there are multiple masks, because the diff --git a/source/fuzz/transformation_set_selection_control.cpp b/source/fuzz/transformation_set_selection_control.cpp index ebabdef2..bee1e357 100644 --- a/source/fuzz/transformation_set_selection_control.cpp +++ b/source/fuzz/transformation_set_selection_control.cpp @@ -28,13 +28,13 @@ TransformationSetSelectionControl::TransformationSetSelectionControl( } bool TransformationSetSelectionControl::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { assert((message_.selection_control() == SpvSelectionControlMaskNone || message_.selection_control() == SpvSelectionControlFlattenMask || message_.selection_control() == SpvSelectionControlDontFlattenMask) && "Selection control should never be set to something other than " "'None', 'Flatten' or 'DontFlatten'"); - if (auto block = context->get_instr_block(message_.block_id())) { + if (auto block = ir_context->get_instr_block(message_.block_id())) { if (auto merge_inst = block->GetMergeInst()) { return merge_inst->opcode() == SpvOpSelectionMerge; } @@ -43,9 +43,9 @@ bool TransformationSetSelectionControl::IsApplicable( return false; } -void TransformationSetSelectionControl::Apply(opt::IRContext* context, - FactManager* /*unused*/) const { - context->get_instr_block(message_.block_id()) +void TransformationSetSelectionControl::Apply( + opt::IRContext* ir_context, TransformationContext* /*unused*/) const { + ir_context->get_instr_block(message_.block_id()) ->GetMergeInst() ->SetInOperand(1, {message_.selection_control()}); } diff --git a/source/fuzz/transformation_set_selection_control.h b/source/fuzz/transformation_set_selection_control.h index 19e0c3cf..21fbdda4 100644 --- a/source/fuzz/transformation_set_selection_control.h +++ b/source/fuzz/transformation_set_selection_control.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SET_SELECTION_CONTROL_H_ #define SOURCE_FUZZ_TRANSFORMATION_SET_SELECTION_CONTROL_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -35,12 +35,14 @@ class TransformationSetSelectionControl : public Transformation { // instruction. // - |message_.selection_control| must be one of None, Flatten or // DontFlatten. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - The selection control operand of the OpSelectionMergeInstruction in // |message_.block_id| is overwritten with |message_.selection_control|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_split_block.cpp b/source/fuzz/transformation_split_block.cpp index fc5229ed..3de081e0 100644 --- a/source/fuzz/transformation_split_block.cpp +++ b/source/fuzz/transformation_split_block.cpp @@ -35,18 +35,19 @@ TransformationSplitBlock::TransformationSplitBlock( } bool TransformationSplitBlock::IsApplicable( - opt::IRContext* context, const FactManager& /*unused*/) const { - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { // We require the id for the new block to be unused. return false; } auto instruction_to_split_before = - FindInstruction(message_.instruction_to_split_before(), context); + FindInstruction(message_.instruction_to_split_before(), ir_context); if (!instruction_to_split_before) { // The instruction describing the block we should split does not exist. return false; } - auto block_to_split = context->get_instr_block(instruction_to_split_before); + auto block_to_split = + ir_context->get_instr_block(instruction_to_split_before); assert(block_to_split && "We should not have managed to find the " "instruction if it was not contained in a block."); @@ -79,12 +80,13 @@ bool TransformationSplitBlock::IsApplicable( split_before->NumInOperands() != 2); } -void TransformationSplitBlock::Apply(opt::IRContext* context, - FactManager* fact_manager) const { +void TransformationSplitBlock::Apply( + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { opt::Instruction* instruction_to_split_before = - FindInstruction(message_.instruction_to_split_before(), context); + FindInstruction(message_.instruction_to_split_before(), ir_context); opt::BasicBlock* block_to_split = - context->get_instr_block(instruction_to_split_before); + ir_context->get_instr_block(instruction_to_split_before); auto split_before = fuzzerutil::GetIteratorForInstruction( block_to_split, instruction_to_split_before); assert(split_before != block_to_split->end() && @@ -93,14 +95,14 @@ void TransformationSplitBlock::Apply(opt::IRContext* context, // We need to make sure the module's id bound is large enough to add the // fresh id. - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // Split the block. - auto new_bb = block_to_split->SplitBasicBlock(context, message_.fresh_id(), + auto new_bb = block_to_split->SplitBasicBlock(ir_context, message_.fresh_id(), split_before); // The split does not automatically add a branch between the two parts of // the original block, so we add one. block_to_split->AddInstruction(MakeUnique( - context, SpvOpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, std::initializer_list{opt::Operand( spv_operand_type_t::SPV_OPERAND_TYPE_ID, {message_.fresh_id()})})); // If we split before OpPhi instructions, we need to update their @@ -117,12 +119,15 @@ void TransformationSplitBlock::Apply(opt::IRContext* context, // If the block being split was dead, the new block arising from the split is // also dead. - if (fact_manager->BlockIsDead(block_to_split->id())) { - fact_manager->AddFactBlockIsDead(message_.fresh_id()); + if (transformation_context->GetFactManager()->BlockIsDead( + block_to_split->id())) { + transformation_context->GetFactManager()->AddFactBlockIsDead( + message_.fresh_id()); } // Invalidate all analyses - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); } protobufs::Transformation TransformationSplitBlock::ToMessage() const { diff --git a/source/fuzz/transformation_split_block.h b/source/fuzz/transformation_split_block.h index a193fc7b..3bf6dfd2 100644 --- a/source/fuzz/transformation_split_block.h +++ b/source/fuzz/transformation_split_block.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SPLIT_BLOCK_H_ #define SOURCE_FUZZ_TRANSFORMATION_SPLIT_BLOCK_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -40,8 +40,9 @@ class TransformationSplitBlock : public Transformation { // - Splitting 'blk' at 'inst', so that all instructions from 'inst' onwards // appear in a new block that 'blk' directly jumps to must be valid. // - |message_.fresh_id| must not be used by the module. - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // - A new block with label |message_.fresh_id| is inserted right after 'blk' // in program order. @@ -49,7 +50,8 @@ class TransformationSplitBlock : public Transformation { // block. // - 'blk' is made to jump unconditionally to the new block. // - If 'blk' was dead, the new block is also dead. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_store.cpp b/source/fuzz/transformation_store.cpp index 7cb76112..3df1b7d3 100644 --- a/source/fuzz/transformation_store.cpp +++ b/source/fuzz/transformation_store.cpp @@ -34,16 +34,16 @@ TransformationStore::TransformationStore( } bool TransformationStore::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& fact_manager) const { + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const { // The pointer must exist and have a type. - auto pointer = context->get_def_use_mgr()->GetDef(message_.pointer_id()); + auto pointer = ir_context->get_def_use_mgr()->GetDef(message_.pointer_id()); if (!pointer || !pointer->type_id()) { return false; } // The pointer type must indeed be a pointer. - auto pointer_type = context->get_def_use_mgr()->GetDef(pointer->type_id()); + auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); assert(pointer_type && "Type id must be defined."); if (pointer_type->opcode() != SpvOpTypePointer) { return false; @@ -65,7 +65,7 @@ bool TransformationStore::IsApplicable( // Determine which instruction we should be inserting before. auto insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); // It must exist, ... if (!insert_before) { return false; @@ -79,14 +79,15 @@ bool TransformationStore::IsApplicable( // The block we are inserting into needs to be dead, or else the pointee type // of the pointer we are storing to needs to be irrelevant (otherwise the // store could impact on the observable behaviour of the module). - if (!fact_manager.BlockIsDead( - context->get_instr_block(insert_before)->id()) && - !fact_manager.PointeeValueIsIrrelevant(message_.pointer_id())) { + if (!transformation_context.GetFactManager()->BlockIsDead( + ir_context->get_instr_block(insert_before)->id()) && + !transformation_context.GetFactManager()->PointeeValueIsIrrelevant( + message_.pointer_id())) { return false; } // The value being stored needs to exist and have a type. - auto value = context->get_def_use_mgr()->GetDef(message_.value_id()); + auto value = ir_context->get_def_use_mgr()->GetDef(message_.value_id()); if (!value || !value->type_id()) { return false; } @@ -97,25 +98,25 @@ bool TransformationStore::IsApplicable( } // The pointer needs to be available at the insertion point. - if (!fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + if (!fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, message_.pointer_id())) { return false; } // The value needs to be available at the insertion point. - return fuzzerutil::IdIsAvailableBeforeInstruction(context, insert_before, + return fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before, message_.value_id()); } -void TransformationStore::Apply(opt::IRContext* context, - spvtools::fuzz::FactManager* /*unused*/) const { - FindInstruction(message_.instruction_to_insert_before(), context) +void TransformationStore::Apply(opt::IRContext* ir_context, + TransformationContext* /*unused*/) const { + FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - context, SpvOpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_ID, {message_.value_id()}}}))); - context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); + ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } protobufs::Transformation TransformationStore::ToMessage() const { diff --git a/source/fuzz/transformation_store.h b/source/fuzz/transformation_store.h index 699afdda..6746aab5 100644 --- a/source/fuzz/transformation_store.h +++ b/source/fuzz/transformation_store.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_STORE_H_ #define SOURCE_FUZZ_TRANSFORMATION_STORE_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -42,14 +42,16 @@ class TransformationStore : public Transformation { // to dominance rules) // - Either the insertion point must be in a dead block, or it must be known // that the pointee value of |message_.pointer_id| is irrelevant - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Adds an instruction of the form: // OpStore |pointer_id| |value_id| // before the instruction identified by // |message_.instruction_to_insert_before|. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_swap_commutable_operands.cpp b/source/fuzz/transformation_swap_commutable_operands.cpp index 49d9de83..b7622a23 100644 --- a/source/fuzz/transformation_swap_commutable_operands.cpp +++ b/source/fuzz/transformation_swap_commutable_operands.cpp @@ -31,10 +31,10 @@ TransformationSwapCommutableOperands::TransformationSwapCommutableOperands( } bool TransformationSwapCommutableOperands::IsApplicable( - opt::IRContext* context, const spvtools::fuzz::FactManager& /*unused*/ + opt::IRContext* ir_context, const TransformationContext& /*unused*/ ) const { auto instruction = - FindInstruction(message_.instruction_descriptor(), context); + FindInstruction(message_.instruction_descriptor(), ir_context); if (instruction == nullptr) return false; SpvOp opcode = static_cast( @@ -46,10 +46,10 @@ bool TransformationSwapCommutableOperands::IsApplicable( } void TransformationSwapCommutableOperands::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/ + opt::IRContext* ir_context, TransformationContext* /*unused*/ ) const { auto instruction = - FindInstruction(message_.instruction_descriptor(), context); + FindInstruction(message_.instruction_descriptor(), ir_context); // By design, the instructions defined to be commutative have exactly two // input parameters. std::swap(instruction->GetInOperand(0), instruction->GetInOperand(1)); diff --git a/source/fuzz/transformation_swap_commutable_operands.h b/source/fuzz/transformation_swap_commutable_operands.h index 061e92da..7fe5b709 100644 --- a/source/fuzz/transformation_swap_commutable_operands.h +++ b/source/fuzz/transformation_swap_commutable_operands.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_SWAP_COMMUTABLE_OPERANDS_H_ #define SOURCE_FUZZ_TRANSFORMATION_SWAP_COMMUTABLE_OPERANDS_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,11 +33,13 @@ class TransformationSwapCommutableOperands : public Transformation { // - |message_.instruction_descriptor| must identify an existing // commutative instruction - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Swaps the commutable operands. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_toggle_access_chain_instruction.cpp b/source/fuzz/transformation_toggle_access_chain_instruction.cpp index ace331aa..ca24a18a 100644 --- a/source/fuzz/transformation_toggle_access_chain_instruction.cpp +++ b/source/fuzz/transformation_toggle_access_chain_instruction.cpp @@ -33,10 +33,10 @@ TransformationToggleAccessChainInstruction:: } bool TransformationToggleAccessChainInstruction::IsApplicable( - opt::IRContext* context, const spvtools::fuzz::FactManager& /*unused*/ + opt::IRContext* ir_context, const TransformationContext& /*unused*/ ) const { auto instruction = - FindInstruction(message_.instruction_descriptor(), context); + FindInstruction(message_.instruction_descriptor(), ir_context); if (instruction == nullptr) { return false; } @@ -56,10 +56,10 @@ bool TransformationToggleAccessChainInstruction::IsApplicable( } void TransformationToggleAccessChainInstruction::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* /*unused*/ + opt::IRContext* ir_context, TransformationContext* /*unused*/ ) const { auto instruction = - FindInstruction(message_.instruction_descriptor(), context); + FindInstruction(message_.instruction_descriptor(), ir_context); SpvOp opcode = instruction->opcode(); if (opcode == SpvOpAccessChain) { diff --git a/source/fuzz/transformation_toggle_access_chain_instruction.h b/source/fuzz/transformation_toggle_access_chain_instruction.h index 125e1ab0..9cd8fd6e 100644 --- a/source/fuzz/transformation_toggle_access_chain_instruction.h +++ b/source/fuzz/transformation_toggle_access_chain_instruction.h @@ -15,9 +15,9 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_TOGGLE_ACCESS_CHAIN_INSTRUCTION_H_ #define SOURCE_FUZZ_TRANSFORMATION_TOGGLE_ACCESS_CHAIN_INSTRUCTION_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -33,11 +33,13 @@ class TransformationToggleAccessChainInstruction : public Transformation { // - |message_.instruction_descriptor| must identify an existing // access chain instruction - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Toggles the access chain instruction. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; diff --git a/source/fuzz/transformation_vector_shuffle.cpp b/source/fuzz/transformation_vector_shuffle.cpp index e2d889d5..ee642926 100644 --- a/source/fuzz/transformation_vector_shuffle.cpp +++ b/source/fuzz/transformation_vector_shuffle.cpp @@ -39,38 +39,37 @@ TransformationVectorShuffle::TransformationVectorShuffle( } bool TransformationVectorShuffle::IsApplicable( - opt::IRContext* context, - const spvtools::fuzz::FactManager& /*unused*/) const { + opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { // The fresh id must not already be in use. - if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) { + if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { return false; } // The instruction before which the shuffle will be inserted must exist. auto instruction_to_insert_before = - FindInstruction(message_.instruction_to_insert_before(), context); + FindInstruction(message_.instruction_to_insert_before(), ir_context); if (!instruction_to_insert_before) { return false; } // The first vector must be an instruction with a type id auto vector1_instruction = - context->get_def_use_mgr()->GetDef(message_.vector1()); + ir_context->get_def_use_mgr()->GetDef(message_.vector1()); if (!vector1_instruction || !vector1_instruction->type_id()) { return false; } // The second vector must be an instruction with a type id auto vector2_instruction = - context->get_def_use_mgr()->GetDef(message_.vector2()); + ir_context->get_def_use_mgr()->GetDef(message_.vector2()); if (!vector2_instruction || !vector2_instruction->type_id()) { return false; } auto vector1_type = - context->get_type_mgr()->GetType(vector1_instruction->type_id()); + ir_context->get_type_mgr()->GetType(vector1_instruction->type_id()); // The first vector instruction's type must actually be a vector type. if (!vector1_type->AsVector()) { return false; } auto vector2_type = - context->get_type_mgr()->GetType(vector2_instruction->type_id()); + ir_context->get_type_mgr()->GetType(vector2_instruction->type_id()); // The second vector instruction's type must actually be a vector type. if (!vector2_type->AsVector()) { return false; @@ -92,14 +91,14 @@ bool TransformationVectorShuffle::IsApplicable( } // The module must already declare an appropriate type in which to store the // result of the shuffle. - if (!GetResultTypeId(context, *vector1_type->AsVector()->element_type())) { + if (!GetResultTypeId(ir_context, *vector1_type->AsVector()->element_type())) { return false; } // Each of the vectors used in the shuffle must be available at the insertion // point. for (auto used_instruction : {vector1_instruction, vector2_instruction}) { - if (auto block = context->get_instr_block(used_instruction)) { - if (!context->GetDominatorAnalysis(block->GetParent()) + if (auto block = ir_context->get_instr_block(used_instruction)) { + if (!ir_context->GetDominatorAnalysis(block->GetParent()) ->Dominates(used_instruction, instruction_to_insert_before)) { return false; } @@ -113,7 +112,8 @@ bool TransformationVectorShuffle::IsApplicable( } void TransformationVectorShuffle::Apply( - opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const { + opt::IRContext* ir_context, + TransformationContext* transformation_context) const { // Make input operands for a shuffle instruction - these comprise the two // vectors being shuffled, followed by the integer literal components. opt::Instruction::OperandList shuffle_operands = { @@ -125,16 +125,18 @@ void TransformationVectorShuffle::Apply( } uint32_t result_type_id = GetResultTypeId( - context, *GetVectorType(context, message_.vector1())->element_type()); + ir_context, + *GetVectorType(ir_context, message_.vector1())->element_type()); // Add a shuffle instruction right before the instruction identified by // |message_.instruction_to_insert_before|. - FindInstruction(message_.instruction_to_insert_before(), context) + FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - context, SpvOpVectorShuffle, result_type_id, message_.fresh_id(), + ir_context, SpvOpVectorShuffle, result_type_id, message_.fresh_id(), shuffle_operands)); - fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); - context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); + fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); + ir_context->InvalidateAnalysesExceptFor( + opt::IRContext::Analysis::kAnalysisNone); // Add synonym facts relating the defined elements of the shuffle result to // the vector components that they come from. @@ -158,24 +160,26 @@ void TransformationVectorShuffle::Apply( // Get a data descriptor for the component of the input vector to which // |component| refers. if (component < - GetVectorType(context, message_.vector1())->element_count()) { + GetVectorType(ir_context, message_.vector1())->element_count()) { descriptor_for_source_component = MakeDataDescriptor(message_.vector1(), {component}); } else { auto index_into_vector_2 = component - - GetVectorType(context, message_.vector1())->element_count(); - assert(index_into_vector_2 < - GetVectorType(context, message_.vector2())->element_count() && - "Vector shuffle index is out of bounds."); + GetVectorType(ir_context, message_.vector1())->element_count(); + assert( + index_into_vector_2 < + GetVectorType(ir_context, message_.vector2())->element_count() && + "Vector shuffle index is out of bounds."); descriptor_for_source_component = MakeDataDescriptor(message_.vector2(), {index_into_vector_2}); } // Add a fact relating this input vector component with the associated // result component. - fact_manager->AddFactDataSynonym(descriptor_for_result_component, - descriptor_for_source_component, context); + transformation_context->GetFactManager()->AddFactDataSynonym( + descriptor_for_result_component, descriptor_for_source_component, + ir_context); } } @@ -186,16 +190,16 @@ protobufs::Transformation TransformationVectorShuffle::ToMessage() const { } uint32_t TransformationVectorShuffle::GetResultTypeId( - opt::IRContext* context, const opt::analysis::Type& element_type) const { + opt::IRContext* ir_context, const opt::analysis::Type& element_type) const { opt::analysis::Vector result_type( &element_type, static_cast(message_.component_size())); - return context->get_type_mgr()->GetId(&result_type); + return ir_context->get_type_mgr()->GetId(&result_type); } opt::analysis::Vector* TransformationVectorShuffle::GetVectorType( - opt::IRContext* context, uint32_t id_of_vector) { - return context->get_type_mgr() - ->GetType(context->get_def_use_mgr()->GetDef(id_of_vector)->type_id()) + opt::IRContext* ir_context, uint32_t id_of_vector) { + return ir_context->get_type_mgr() + ->GetType(ir_context->get_def_use_mgr()->GetDef(id_of_vector)->type_id()) ->AsVector(); } diff --git a/source/fuzz/transformation_vector_shuffle.h b/source/fuzz/transformation_vector_shuffle.h index 81ed2270..f73fc311 100644 --- a/source/fuzz/transformation_vector_shuffle.h +++ b/source/fuzz/transformation_vector_shuffle.h @@ -15,10 +15,11 @@ #ifndef SOURCE_FUZZ_TRANSFORMATION_VECTOR_SHUFFLE_H_ #define SOURCE_FUZZ_TRANSFORMATION_VECTOR_SHUFFLE_H_ -#include "source/fuzz/fact_manager.h" #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" +#include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" + #include "source/opt/types.h" namespace spvtools { @@ -45,8 +46,9 @@ class TransformationVectorShuffle : public Transformation { // - The module must already contain a vector type with the same element type // as |message_.vector1| and |message_.vector2|, and with the size of // |message_component| as its element count - bool IsApplicable(opt::IRContext* context, - const FactManager& fact_manager) const override; + bool IsApplicable( + opt::IRContext* ir_context, + const TransformationContext& transformation_context) const override; // Inserts an OpVectorShuffle instruction before // |message_.instruction_to_insert_before|, shuffles vectors @@ -58,19 +60,20 @@ class TransformationVectorShuffle : public Transformation { // result vector is a contiguous sub-range of one of the input vectors, a // fact is added to record that |message_.fresh_id| is synonymous with this // sub-range. - void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + void Apply(opt::IRContext* ir_context, + TransformationContext* transformation_context) const override; protobufs::Transformation ToMessage() const override; private: - // Returns a type id that already exists in |context| suitable for + // Returns a type id that already exists in |ir_context| suitable for // representing the result of the shuffle, where |element_type| is known to // be the common element type of the vectors to which the shuffle is being // applied. Returns 0 if no such id exists. - uint32_t GetResultTypeId(opt::IRContext* context, + uint32_t GetResultTypeId(opt::IRContext* ir_context, const opt::analysis::Type& element_type) const; - static opt::analysis::Vector* GetVectorType(opt::IRContext* context, + static opt::analysis::Vector* GetVectorType(opt::IRContext* ir_context, uint32_t id_of_vector); protobufs::TransformationVectorShuffle message_; diff --git a/test/fuzz/data_synonym_transformation_test.cpp b/test/fuzz/data_synonym_transformation_test.cpp index 21ea068f..2d26d170 100644 --- a/test/fuzz/data_synonym_transformation_test.cpp +++ b/test/fuzz/data_synonym_transformation_test.cpp @@ -123,13 +123,24 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFact(MakeSynonymFact(12, {}, 100, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(13, {}, 100, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(22, {}, 100, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(28, {}, 101, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(23, {}, 101, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(32, {}, 101, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(23, {}, 101, {3}), context.get()); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(12, {}, 100, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(13, {}, 100, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(22, {}, 100, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(28, {}, 101, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(23, {}, 101, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(32, {}, 101, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(23, {}, 101, {3}), context.get()); // Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12' auto instruction_descriptor_1 = @@ -139,13 +150,16 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Bad: id already in use auto bad_extract_1 = TransformationCompositeExtract( MakeInstructionDescriptor(25, SpvOpAccessChain, 0), 25, 100, {0}); - ASSERT_TRUE(good_extract_1.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_extract_1.IsApplicable(context.get(), fact_manager)); - good_extract_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_1.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_extract_1.IsApplicable(context.get(), transformation_context)); + good_extract_1.Apply(context.get(), &transformation_context); auto replacement_1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(12, instruction_descriptor_1, 1), 102); - ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager)); - replacement_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_1.IsApplicable(context.get(), transformation_context)); + replacement_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %13 with %100[1] in 'OpStore %15 %13' @@ -153,12 +167,14 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { auto good_extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 103, 100, {1}); // No bad example provided here. - ASSERT_TRUE(good_extract_2.IsApplicable(context.get(), fact_manager)); - good_extract_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_2.IsApplicable(context.get(), transformation_context)); + good_extract_2.Apply(context.get(), &transformation_context); auto replacement_2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(13, instruction_descriptor_2, 1), 103); - ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager)); - replacement_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_2.IsApplicable(context.get(), transformation_context)); + replacement_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %22 with %100[2] in '%23 = OpConvertSToF %16 %22' @@ -166,16 +182,19 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { MakeInstructionDescriptor(23, SpvOpConvertSToF, 0); auto good_extract_3 = TransformationCompositeExtract(instruction_descriptor_3, 104, 100, {2}); - ASSERT_TRUE(good_extract_3.IsApplicable(context.get(), fact_manager)); - good_extract_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_3.IsApplicable(context.get(), transformation_context)); + good_extract_3.Apply(context.get(), &transformation_context); auto replacement_3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(22, instruction_descriptor_3, 0), 104); // Bad: wrong input operand index auto bad_replacement_3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(22, instruction_descriptor_3, 1), 104); - ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_replacement_3.IsApplicable(context.get(), fact_manager)); - replacement_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_3.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_replacement_3.IsApplicable(context.get(), transformation_context)); + replacement_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %28 with %101[0] in 'OpStore %33 %28' @@ -185,13 +204,16 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Bad: instruction descriptor does not identify an appropriate instruction auto bad_extract_4 = TransformationCompositeExtract( MakeInstructionDescriptor(33, SpvOpCopyObject, 0), 105, 101, {0}); - ASSERT_TRUE(good_extract_4.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_extract_4.IsApplicable(context.get(), fact_manager)); - good_extract_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_4.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_extract_4.IsApplicable(context.get(), transformation_context)); + good_extract_4.Apply(context.get(), &transformation_context); auto replacement_4 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(28, instruction_descriptor_4, 1), 105); - ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager)); - replacement_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_4.IsApplicable(context.get(), transformation_context)); + replacement_4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %23 with %101[1] in '%50 = OpCopyObject %16 %23' @@ -199,16 +221,19 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { MakeInstructionDescriptor(50, SpvOpCopyObject, 0); auto good_extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 106, 101, {1}); - ASSERT_TRUE(good_extract_5.IsApplicable(context.get(), fact_manager)); - good_extract_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_5.IsApplicable(context.get(), transformation_context)); + good_extract_5.Apply(context.get(), &transformation_context); auto replacement_5 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 106); // Bad: wrong synonym fact being used auto bad_replacement_5 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 105); - ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_replacement_5.IsApplicable(context.get(), fact_manager)); - replacement_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_replacement_5.IsApplicable(context.get(), transformation_context)); + replacement_5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %32 with %101[2] in 'OpStore %33 %32' @@ -218,13 +243,16 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Bad: id 1001 does not exist auto bad_extract_6 = TransformationCompositeExtract(instruction_descriptor_6, 107, 1001, {2}); - ASSERT_TRUE(good_extract_6.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_extract_6.IsApplicable(context.get(), fact_manager)); - good_extract_6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_6.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_extract_6.IsApplicable(context.get(), transformation_context)); + good_extract_6.Apply(context.get(), &transformation_context); auto replacement_6 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(32, instruction_descriptor_6, 1), 107); - ASSERT_TRUE(replacement_6.IsApplicable(context.get(), fact_manager)); - replacement_6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_6.IsApplicable(context.get(), transformation_context)); + replacement_6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %23 with %101[3] in '%51 = OpCopyObject %16 %23' @@ -232,16 +260,19 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { MakeInstructionDescriptor(51, SpvOpCopyObject, 0); auto good_extract_7 = TransformationCompositeExtract(instruction_descriptor_7, 108, 101, {3}); - ASSERT_TRUE(good_extract_7.IsApplicable(context.get(), fact_manager)); - good_extract_7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + good_extract_7.IsApplicable(context.get(), transformation_context)); + good_extract_7.Apply(context.get(), &transformation_context); auto replacement_7 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(23, instruction_descriptor_7, 0), 108); // Bad: use id 0 is invalid auto bad_replacement_7 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(0, instruction_descriptor_7, 0), 108); - ASSERT_TRUE(replacement_7.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(bad_replacement_7.IsApplicable(context.get(), fact_manager)); - replacement_7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_7.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + bad_replacement_7.IsApplicable(context.get(), transformation_context)); + replacement_7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( @@ -380,32 +411,41 @@ TEST(DataSynonymTransformationTest, MatrixCompositeSynonyms) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFact(MakeSynonymFact(23, {}, 100, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(25, {}, 100, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(50, {}, 100, {2}), context.get()); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(23, {}, 100, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(25, {}, 100, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(50, {}, 100, {2}), context.get()); // Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25' auto instruction_descriptor_1 = MakeInstructionDescriptor(26, SpvOpFAdd, 0); auto extract_1 = TransformationCompositeExtract(instruction_descriptor_1, 101, 100, {0}); - ASSERT_TRUE(extract_1.IsApplicable(context.get(), fact_manager)); - extract_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); + extract_1.Apply(context.get(), &transformation_context); auto replacement_1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(23, instruction_descriptor_1, 0), 101); - ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager)); - replacement_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_1.IsApplicable(context.get(), transformation_context)); + replacement_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %25 with %100[1] in '%26 = OpFAdd %7 %23 %25' auto instruction_descriptor_2 = MakeInstructionDescriptor(26, SpvOpFAdd, 0); auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 102, 100, {1}); - ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager)); - extract_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); + extract_2.Apply(context.get(), &transformation_context); auto replacement_2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(25, instruction_descriptor_2, 1), 102); - ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager)); - replacement_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_2.IsApplicable(context.get(), transformation_context)); + replacement_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( @@ -541,26 +581,37 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFact(MakeSynonymFact(16, {}, 100, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(45, {}, 100, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(27, {}, 101, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(36, {}, 101, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(27, {}, 101, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(22, {}, 102, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(15, {}, 102, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(16, {}, 100, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(45, {}, 100, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(27, {}, 101, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(36, {}, 101, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(27, {}, 101, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(22, {}, 102, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(15, {}, 102, {1}), context.get()); // Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45' auto instruction_descriptor_1 = MakeInstructionDescriptor(46, SpvOpCompositeConstruct, 0); auto extract_1 = TransformationCompositeExtract(instruction_descriptor_1, 201, 100, {1}); - ASSERT_TRUE(extract_1.IsApplicable(context.get(), fact_manager)); - extract_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); + extract_1.Apply(context.get(), &transformation_context); auto replacement_1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(45, instruction_descriptor_1, 1), 201); - ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager)); - replacement_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_1.IsApplicable(context.get(), transformation_context)); + replacement_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace second occurrence of %27 with %101[0] in '%28 = @@ -569,12 +620,13 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0); auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 202, 101, {0}); - ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager)); - extract_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); + extract_2.Apply(context.get(), &transformation_context); auto replacement_2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(27, instruction_descriptor_2, 1), 202); - ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager)); - replacement_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_2.IsApplicable(context.get(), transformation_context)); + replacement_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %36 with %101[1] in '%45 = OpCompositeConstruct %31 %36 %41 %44' @@ -582,12 +634,13 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { MakeInstructionDescriptor(45, SpvOpCompositeConstruct, 0); auto extract_3 = TransformationCompositeExtract(instruction_descriptor_3, 203, 101, {1}); - ASSERT_TRUE(extract_3.IsApplicable(context.get(), fact_manager)); - extract_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_3.IsApplicable(context.get(), transformation_context)); + extract_3.Apply(context.get(), &transformation_context); auto replacement_3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(36, instruction_descriptor_3, 0), 203); - ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager)); - replacement_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_3.IsApplicable(context.get(), transformation_context)); + replacement_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace first occurrence of %27 with %101[2] in '%28 = OpCompositeConstruct @@ -596,24 +649,26 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0); auto extract_4 = TransformationCompositeExtract(instruction_descriptor_4, 204, 101, {2}); - ASSERT_TRUE(extract_4.IsApplicable(context.get(), fact_manager)); - extract_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_4.IsApplicable(context.get(), transformation_context)); + extract_4.Apply(context.get(), &transformation_context); auto replacement_4 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(27, instruction_descriptor_4, 0), 204); - ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager)); - replacement_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_4.IsApplicable(context.get(), transformation_context)); + replacement_4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %22 with %102[0] in 'OpStore %23 %22' auto instruction_descriptor_5 = MakeInstructionDescriptor(23, SpvOpStore, 0); auto extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 205, 102, {0}); - ASSERT_TRUE(extract_5.IsApplicable(context.get(), fact_manager)); - extract_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context)); + extract_5.Apply(context.get(), &transformation_context); auto replacement_5 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(22, instruction_descriptor_5, 1), 205); - ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager)); - replacement_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_5.IsApplicable(context.get(), transformation_context)); + replacement_5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( @@ -816,38 +871,63 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFact(MakeSynonymFact(20, {0}, 100, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(20, {1}, 100, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(20, {2}, 100, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(54, {}, 100, {3}), context.get()); - fact_manager.AddFact(MakeSynonymFact(15, {0}, 101, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(15, {1}, 101, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(19, {0}, 101, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(19, {1}, 101, {3}), context.get()); - fact_manager.AddFact(MakeSynonymFact(27, {}, 102, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(15, {0}, 102, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(15, {1}, 102, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(33, {}, 103, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(47, {0}, 103, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(47, {1}, 103, {2}), context.get()); - fact_manager.AddFact(MakeSynonymFact(47, {2}, 103, {3}), context.get()); - fact_manager.AddFact(MakeSynonymFact(42, {}, 104, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(45, {}, 104, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(38, {0}, 105, {0}), context.get()); - fact_manager.AddFact(MakeSynonymFact(38, {1}, 105, {1}), context.get()); - fact_manager.AddFact(MakeSynonymFact(46, {}, 105, {2}), context.get()); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(20, {0}, 100, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(20, {1}, 100, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(20, {2}, 100, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(54, {}, 100, {3}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(15, {0}, 101, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(15, {1}, 101, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(19, {0}, 101, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(19, {1}, 101, {3}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(27, {}, 102, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(15, {0}, 102, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(15, {1}, 102, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(33, {}, 103, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(47, {0}, 103, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(47, {1}, 103, {2}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(47, {2}, 103, {3}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(42, {}, 104, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(45, {}, 104, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(38, {0}, 105, {0}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(38, {1}, 105, {1}), context.get()); + transformation_context.GetFactManager()->AddFact( + MakeSynonymFact(46, {}, 105, {2}), context.get()); // Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20' auto instruction_descriptor_1 = MakeInstructionDescriptor(80, SpvOpCopyObject, 0); auto shuffle_1 = TransformationVectorShuffle(instruction_descriptor_1, 200, 100, 100, {0, 1, 2}); - ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), fact_manager)); - shuffle_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context)); + shuffle_1.Apply(context.get(), &transformation_context); auto replacement_1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200); - ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager)); - replacement_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_1.IsApplicable(context.get(), transformation_context)); + replacement_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %54 with %100[3] in '%56 = OpFOrdNotEqual %30 %54 %55' @@ -856,24 +936,26 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 201, 100, {3}); - ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager)); - extract_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); + extract_2.Apply(context.get(), &transformation_context); auto replacement_2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(54, instruction_descriptor_2, 0), 201); - ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager)); - replacement_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_2.IsApplicable(context.get(), transformation_context)); + replacement_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %15 with %101[0:1] in 'OpStore %12 %15' auto instruction_descriptor_3 = MakeInstructionDescriptor(64, SpvOpStore, 0); auto shuffle_3 = TransformationVectorShuffle(instruction_descriptor_3, 202, 101, 101, {0, 1}); - ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), fact_manager)); - shuffle_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context)); + shuffle_3.Apply(context.get(), &transformation_context); auto replacement_3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202); - ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager)); - replacement_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_3.IsApplicable(context.get(), transformation_context)); + replacement_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %19 with %101[2:3] in '%81 = OpVectorShuffle %16 %19 %19 0 0 1' @@ -881,12 +963,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(81, SpvOpVectorShuffle, 0); auto shuffle_4 = TransformationVectorShuffle(instruction_descriptor_4, 203, 101, 101, {2, 3}); - ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), fact_manager)); - shuffle_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context)); + shuffle_4.Apply(context.get(), &transformation_context); auto replacement_4 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203); - ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager)); - replacement_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_4.IsApplicable(context.get(), transformation_context)); + replacement_4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %27 with %102[0] in '%82 = OpCompositeConstruct %21 %26 %27 %28 @@ -896,12 +979,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { auto extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 204, 102, {0}); - ASSERT_TRUE(extract_5.IsApplicable(context.get(), fact_manager)); - extract_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context)); + extract_5.Apply(context.get(), &transformation_context); auto replacement_5 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(27, instruction_descriptor_5, 1), 204); - ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager)); - replacement_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_5.IsApplicable(context.get(), transformation_context)); + replacement_5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %15 with %102[1:2] in '%83 = OpCopyObject %10 %15' @@ -909,12 +993,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(83, SpvOpCopyObject, 0); auto shuffle_6 = TransformationVectorShuffle(instruction_descriptor_6, 205, 102, 102, {1, 2}); - ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), fact_manager)); - shuffle_6.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context)); + shuffle_6.Apply(context.get(), &transformation_context); auto replacement_6 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205); - ASSERT_TRUE(replacement_6.IsApplicable(context.get(), fact_manager)); - replacement_6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_6.IsApplicable(context.get(), transformation_context)); + replacement_6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %33 with %103[0] in '%86 = OpCopyObject %30 %33' @@ -922,12 +1007,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(86, SpvOpCopyObject, 0); auto extract_7 = TransformationCompositeExtract(instruction_descriptor_7, 206, 103, {0}); - ASSERT_TRUE(extract_7.IsApplicable(context.get(), fact_manager)); - extract_7.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_7.IsApplicable(context.get(), transformation_context)); + extract_7.Apply(context.get(), &transformation_context); auto replacement_7 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(33, instruction_descriptor_7, 0), 206); - ASSERT_TRUE(replacement_7.IsApplicable(context.get(), fact_manager)); - replacement_7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_7.IsApplicable(context.get(), transformation_context)); + replacement_7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %47 with %103[1:3] in '%84 = OpCopyObject %39 %47' @@ -935,12 +1021,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(84, SpvOpCopyObject, 0); auto shuffle_8 = TransformationVectorShuffle(instruction_descriptor_8, 207, 103, 103, {1, 2, 3}); - ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), fact_manager)); - shuffle_8.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context)); + shuffle_8.Apply(context.get(), &transformation_context); auto replacement_8 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207); - ASSERT_TRUE(replacement_8.IsApplicable(context.get(), fact_manager)); - replacement_8.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_8.IsApplicable(context.get(), transformation_context)); + replacement_8.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %42 with %104[0] in '%85 = OpCopyObject %30 %42' @@ -948,12 +1035,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(85, SpvOpCopyObject, 0); auto extract_9 = TransformationCompositeExtract(instruction_descriptor_9, 208, 104, {0}); - ASSERT_TRUE(extract_9.IsApplicable(context.get(), fact_manager)); - extract_9.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_9.IsApplicable(context.get(), transformation_context)); + extract_9.Apply(context.get(), &transformation_context); auto replacement_9 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(42, instruction_descriptor_9, 0), 208); - ASSERT_TRUE(replacement_9.IsApplicable(context.get(), fact_manager)); - replacement_9.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_9.IsApplicable(context.get(), transformation_context)); + replacement_9.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %45 with %104[1] in '%63 = OpLogicalOr %30 %45 %46' @@ -961,24 +1049,26 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(63, SpvOpLogicalOr, 0); auto extract_10 = TransformationCompositeExtract(instruction_descriptor_10, 209, 104, {1}); - ASSERT_TRUE(extract_10.IsApplicable(context.get(), fact_manager)); - extract_10.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_10.IsApplicable(context.get(), transformation_context)); + extract_10.Apply(context.get(), &transformation_context); auto replacement_10 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(45, instruction_descriptor_10, 0), 209); - ASSERT_TRUE(replacement_10.IsApplicable(context.get(), fact_manager)); - replacement_10.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_10.IsApplicable(context.get(), transformation_context)); + replacement_10.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %38 with %105[0:1] in 'OpStore %36 %38' auto instruction_descriptor_11 = MakeInstructionDescriptor(85, SpvOpStore, 0); auto shuffle_11 = TransformationVectorShuffle(instruction_descriptor_11, 210, 105, 105, {0, 1}); - ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), fact_manager)); - shuffle_11.Apply(context.get(), &fact_manager); + ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context)); + shuffle_11.Apply(context.get(), &transformation_context); auto replacement_11 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210); - ASSERT_TRUE(replacement_11.IsApplicable(context.get(), fact_manager)); - replacement_11.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_11.IsApplicable(context.get(), transformation_context)); + replacement_11.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %46 with %105[2] in '%62 = OpLogicalAnd %30 %45 %46' @@ -986,12 +1076,13 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { MakeInstructionDescriptor(62, SpvOpLogicalAnd, 0); auto extract_12 = TransformationCompositeExtract(instruction_descriptor_12, 211, 105, {2}); - ASSERT_TRUE(extract_12.IsApplicable(context.get(), fact_manager)); - extract_12.Apply(context.get(), &fact_manager); + ASSERT_TRUE(extract_12.IsApplicable(context.get(), transformation_context)); + extract_12.Apply(context.get(), &transformation_context); auto replacement_12 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(46, instruction_descriptor_12, 1), 211); - ASSERT_TRUE(replacement_12.IsApplicable(context.get(), fact_manager)); - replacement_12.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_12.IsApplicable(context.get(), transformation_context)); + replacement_12.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( diff --git a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp b/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp index 89f006e0..90d1c847 100644 --- a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp +++ b/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp @@ -64,10 +64,14 @@ TEST(FuzzerPassAddUsefulConstructsTest, CheckBasicStuffIsAdded) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassAddUsefulConstructs pass(context.get(), &fact_manager, + FuzzerPassAddUsefulConstructs pass(context.get(), &transformation_context, &fuzzer_context, &transformation_sequence); pass.Apply(); ASSERT_TRUE(IsValid(env, context.get())); @@ -173,6 +177,10 @@ TEST(FuzzerPassAddUsefulConstructsTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; @@ -292,7 +300,7 @@ TEST(FuzzerPassAddUsefulConstructsTest, context->get_constant_mgr()->FindConstant(&int_constant_8)); } - FuzzerPassAddUsefulConstructs pass(context.get(), &fact_manager, + FuzzerPassAddUsefulConstructs pass(context.get(), &transformation_context, &fuzzer_context, &transformation_sequence); pass.Apply(); ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/fuzzer_pass_donate_modules_test.cpp b/test/fuzz/fuzzer_pass_donate_modules_test.cpp index dc7ba3a5..549dd13f 100644 --- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp +++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp @@ -194,14 +194,17 @@ TEST(FuzzerPassDonateModulesTest, BasicDonation) { ASSERT_TRUE(IsValid(env, donor_context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto prng = MakeUnique(0); FuzzerContext fuzzer_context(prng.get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager, - &fuzzer_context, &transformation_sequence, - {}); + FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), + &transformation_context, &fuzzer_context, + &transformation_sequence, {}); fuzzer_pass.DonateSingleModule(donor_context.get(), false); @@ -269,13 +272,16 @@ TEST(FuzzerPassDonateModulesTest, DonationWithUniforms) { ASSERT_TRUE(IsValid(env, donor_context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager, - &fuzzer_context, &transformation_sequence, - {}); + FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), + &transformation_context, &fuzzer_context, + &transformation_sequence, {}); fuzzer_pass.DonateSingleModule(donor_context.get(), false); @@ -393,13 +399,16 @@ TEST(FuzzerPassDonateModulesTest, DonationWithInputAndOutputVariables) { ASSERT_TRUE(IsValid(env, donor_context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager, - &fuzzer_context, &transformation_sequence, - {}); + FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), + &transformation_context, &fuzzer_context, + &transformation_sequence, {}); fuzzer_pass.DonateSingleModule(donor_context.get(), false); @@ -481,13 +490,16 @@ TEST(FuzzerPassDonateModulesTest, DonateFunctionTypeWithDifferentPointers) { ASSERT_TRUE(IsValid(env, donor_context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager, - &fuzzer_context, &transformation_sequence, - {}); + FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), + &transformation_context, &fuzzer_context, + &transformation_sequence, {}); fuzzer_pass.DonateSingleModule(donor_context.get(), false); @@ -658,13 +670,16 @@ TEST(FuzzerPassDonateModulesTest, Miscellaneous1) { ASSERT_TRUE(IsValid(env, donor_context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); FuzzerContext fuzzer_context(MakeUnique(0).get(), 100); protobufs::TransformationSequence transformation_sequence; - FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager, - &fuzzer_context, &transformation_sequence, - {}); + FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), + &transformation_context, &fuzzer_context, + &transformation_sequence, {}); fuzzer_pass.DonateSingleModule(donor_context.get(), false); diff --git a/test/fuzz/transformation_access_chain_test.cpp b/test/fuzz/transformation_access_chain_test.cpp index 516d371b..443c31c7 100644 --- a/test/fuzz/transformation_access_chain_test.cpp +++ b/test/fuzz/transformation_access_chain_test.cpp @@ -118,169 +118,194 @@ TEST(TransformationAccessChainTest, BasicTest) { // Indices 0-5 are in ids 80-85 FactManager fact_manager; - fact_manager.AddFactValueOfPointeeIsIrrelevant(54); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 54); // Bad: id is not fresh ASSERT_FALSE(TransformationAccessChain( 43, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist ASSERT_FALSE(TransformationAccessChain( 100, 1000, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id is not a type ASSERT_FALSE(TransformationAccessChain( 100, 5, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id is not a pointer ASSERT_FALSE(TransformationAccessChain( 100, 23, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: index id does not exist ASSERT_FALSE(TransformationAccessChain( 100, 43, {1000}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: index id is not a constant ASSERT_FALSE(TransformationAccessChain( 100, 43, {24}, MakeInstructionDescriptor(25, SpvOpIAdd, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: too many indices ASSERT_FALSE( TransformationAccessChain(100, 43, {80, 80, 80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: index id is out of bounds ASSERT_FALSE( TransformationAccessChain(100, 43, {80, 83}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before variable ASSERT_FALSE(TransformationAccessChain( 100, 34, {}, MakeInstructionDescriptor(36, SpvOpVariable, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer not available ASSERT_FALSE( TransformationAccessChain( 100, 43, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: instruction descriptor does not identify anything ASSERT_FALSE(TransformationAccessChain( 100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 100)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is null ASSERT_FALSE(TransformationAccessChain( 100, 45, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is undef ASSERT_FALSE(TransformationAccessChain( 100, 46, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer to result type does not exist ASSERT_FALSE(TransformationAccessChain( 100, 52, {0}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); { TransformationAccessChain transformation( 100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); } { TransformationAccessChain transformation( 101, 28, {81}, MakeInstructionDescriptor(42, SpvOpReturn, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); } { TransformationAccessChain transformation( 102, 36, {80, 81}, MakeInstructionDescriptor(37, SpvOpStore, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(102)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); } { TransformationAccessChain transformation( 103, 44, {}, MakeInstructionDescriptor(44, SpvOpStore, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(103)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103)); } { TransformationAccessChain transformation( 104, 13, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(104)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104)); } { TransformationAccessChain transformation( 105, 34, {}, MakeInstructionDescriptor(44, SpvOpStore, 1)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(105)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105)); } { TransformationAccessChain transformation( 106, 38, {}, MakeInstructionDescriptor(40, SpvOpFunctionCall, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(106)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(106)); } { TransformationAccessChain transformation( 107, 14, {}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(107)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(107)); } { TransformationAccessChain transformation( 108, 54, {85, 81, 81}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(108)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(108)); } { TransformationAccessChain transformation( 109, 48, {80, 80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(109)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(109)); } std::string after_transformation = R"( @@ -401,19 +426,24 @@ TEST(TransformationAccessChainTest, IsomorphicStructs) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); { TransformationAccessChain transformation( 100, 11, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { TransformationAccessChain transformation( 101, 12, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_add_constant_boolean_test.cpp b/test/fuzz/transformation_add_constant_boolean_test.cpp index f51c46bf..c6033336 100644 --- a/test/fuzz/transformation_add_constant_boolean_test.cpp +++ b/test/fuzz/transformation_add_constant_boolean_test.cpp @@ -43,42 +43,47 @@ TEST(TransformationAddConstantBooleanTest, NeitherPresentInitiallyAddBoth) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // True and false can both be added as neither is present. ASSERT_TRUE(TransformationAddConstantBoolean(7, true).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); ASSERT_TRUE(TransformationAddConstantBoolean(7, false).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // Id 5 is already taken. ASSERT_FALSE(TransformationAddConstantBoolean(5, true).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); auto add_true = TransformationAddConstantBoolean(7, true); auto add_false = TransformationAddConstantBoolean(8, false); - ASSERT_TRUE(add_true.IsApplicable(context.get(), fact_manager)); - add_true.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_true.IsApplicable(context.get(), transformation_context)); + add_true.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Having added true, we cannot add it again with the same id. - ASSERT_FALSE(add_true.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(add_true.IsApplicable(context.get(), transformation_context)); // But we can add it with a different id. auto add_true_again = TransformationAddConstantBoolean(100, true); - ASSERT_TRUE(add_true_again.IsApplicable(context.get(), fact_manager)); - add_true_again.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_true_again.IsApplicable(context.get(), transformation_context)); + add_true_again.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_false.IsApplicable(context.get(), fact_manager)); - add_false.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_false.IsApplicable(context.get(), transformation_context)); + add_false.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Having added false, we cannot add it again with the same id. - ASSERT_FALSE(add_false.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(add_false.IsApplicable(context.get(), transformation_context)); // But we can add it with a different id. auto add_false_again = TransformationAddConstantBoolean(101, false); - ASSERT_TRUE(add_false_again.IsApplicable(context.get(), fact_manager)); - add_false_again.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_false_again.IsApplicable(context.get(), transformation_context)); + add_false_again.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -128,12 +133,15 @@ TEST(TransformationAddConstantBooleanTest, NoOpTypeBoolPresent) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Neither true nor false can be added as OpTypeBool is not present. ASSERT_FALSE(TransformationAddConstantBoolean(6, true).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); ASSERT_FALSE(TransformationAddConstantBoolean(6, false).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_add_constant_composite_test.cpp b/test/fuzz/transformation_add_constant_composite_test.cpp index 5ce171ba..021bf58e 100644 --- a/test/fuzz/transformation_add_constant_composite_test.cpp +++ b/test/fuzz/transformation_add_constant_composite_test.cpp @@ -64,19 +64,22 @@ TEST(TransformationAddConstantCompositeTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Too few ids ASSERT_FALSE(TransformationAddConstantComposite(103, 8, {100, 101}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too many ids ASSERT_FALSE(TransformationAddConstantComposite(101, 7, {14, 15, 14}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Id already in use ASSERT_FALSE(TransformationAddConstantComposite(40, 7, {11, 12}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %39 is not a type ASSERT_FALSE(TransformationAddConstantComposite(100, 39, {11, 12}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddConstantComposite transformations[] = { // %100 = OpConstantComposite %7 %11 %12 @@ -101,8 +104,9 @@ TEST(TransformationAddConstantCompositeTest, BasicTest) { TransformationAddConstantComposite(106, 35, {38, 39, 40})}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_constant_scalar_test.cpp b/test/fuzz/transformation_add_constant_scalar_test.cpp index b1561112..5124b7d8 100644 --- a/test/fuzz/transformation_add_constant_scalar_test.cpp +++ b/test/fuzz/transformation_add_constant_scalar_test.cpp @@ -62,6 +62,9 @@ TEST(TransformationAddConstantScalarTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const float float_values[2] = {3.0, 30.0}; uint32_t uint_for_float[2]; @@ -87,55 +90,62 @@ TEST(TransformationAddConstantScalarTest, BasicTest) { auto bad_type_id_is_pointer = TransformationAddConstantScalar(111, 11, {0}); // Id is already in use. - ASSERT_FALSE(bad_id_already_used.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_id_already_used.IsApplicable(context.get(), transformation_context)); // At least one word of data must be provided. - ASSERT_FALSE(bad_no_data.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_no_data.IsApplicable(context.get(), transformation_context)); // Cannot give two data words for a 32-bit type. - ASSERT_FALSE(bad_too_much_data.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_too_much_data.IsApplicable(context.get(), transformation_context)); // Type id does not exist - ASSERT_FALSE( - bad_type_id_does_not_exist.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_type_id_does_not_exist.IsApplicable(context.get(), + transformation_context)); // Type id is not a type - ASSERT_FALSE( - bad_type_id_is_not_a_type.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_type_id_is_not_a_type.IsApplicable(context.get(), + transformation_context)); // Type id is void - ASSERT_FALSE(bad_type_id_is_void.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_type_id_is_void.IsApplicable(context.get(), transformation_context)); // Type id is pointer - ASSERT_FALSE( - bad_type_id_is_pointer.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_type_id_is_pointer.IsApplicable(context.get(), + transformation_context)); - ASSERT_TRUE(add_signed_int_1.IsApplicable(context.get(), fact_manager)); - add_signed_int_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_signed_int_1.IsApplicable(context.get(), transformation_context)); + add_signed_int_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_signed_int_10.IsApplicable(context.get(), fact_manager)); - add_signed_int_10.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_signed_int_10.IsApplicable(context.get(), transformation_context)); + add_signed_int_10.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_unsigned_int_2.IsApplicable(context.get(), fact_manager)); - add_unsigned_int_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_unsigned_int_2.IsApplicable(context.get(), transformation_context)); + add_unsigned_int_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_unsigned_int_20.IsApplicable(context.get(), fact_manager)); - add_unsigned_int_20.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_unsigned_int_20.IsApplicable(context.get(), transformation_context)); + add_unsigned_int_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_float_3.IsApplicable(context.get(), fact_manager)); - add_float_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_float_3.IsApplicable(context.get(), transformation_context)); + add_float_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(add_float_30.IsApplicable(context.get(), fact_manager)); - add_float_30.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_float_30.IsApplicable(context.get(), transformation_context)); + add_float_30.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(bad_add_float_30_id_already_used.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(bad_add_float_30_id_already_used.IsApplicable( + context.get(), transformation_context)); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_dead_block_test.cpp b/test/fuzz/transformation_add_dead_block_test.cpp index f89140f8..c9be5209 100644 --- a/test/fuzz/transformation_add_dead_block_test.cpp +++ b/test/fuzz/transformation_add_dead_block_test.cpp @@ -46,21 +46,25 @@ TEST(TransformationAddDeadBlockTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id 4 is already in use ASSERT_FALSE(TransformationAddDeadBlock(4, 5, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Id 7 is not a block ASSERT_FALSE(TransformationAddDeadBlock(100, 7, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddDeadBlock transformation(100, 5, true); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.BlockIsDead(100)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100)); std::string after_transformation = R"( OpCapability Shader @@ -119,9 +123,12 @@ TEST(TransformationAddDeadBlockTest, TargetBlockMustNotBeSelectionMerge) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBlockTest, TargetBlockMustNotBeLoopMergeOrContinue) { @@ -160,13 +167,16 @@ TEST(TransformationAddDeadBlockTest, TargetBlockMustNotBeLoopMergeOrContinue) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Bad because 9's successor is the loop continue target. ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad because 10's successor is the loop merge. ASSERT_FALSE(TransformationAddDeadBlock(100, 10, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBlockTest, SourceBlockMustNotBeLoopHead) { @@ -203,10 +213,13 @@ TEST(TransformationAddDeadBlockTest, SourceBlockMustNotBeLoopHead) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Bad because 8 is a loop head. ASSERT_FALSE(TransformationAddDeadBlock(100, 8, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBlockTest, OpPhiInTarget) { @@ -240,13 +253,17 @@ TEST(TransformationAddDeadBlockTest, OpPhiInTarget) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationAddDeadBlock transformation(100, 5, true); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.BlockIsDead(100)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100)); std::string after_transformation = R"( OpCapability Shader @@ -309,11 +326,14 @@ TEST(TransformationAddDeadBlockTest, BackEdge) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // 9 is a back edge block, so it would not be OK to add a dead block here, // as then both 9 and the dead block would branch to the loop header, 8. ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_add_dead_break_test.cpp b/test/fuzz/transformation_add_dead_break_test.cpp index d60fc1fc..8400b0cf 100644 --- a/test/fuzz/transformation_add_dead_break_test.cpp +++ b/test/fuzz/transformation_add_dead_break_test.cpp @@ -100,44 +100,47 @@ TEST(TransformationAddDeadBreakTest, BreaksOutOfSimpleIf) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const uint32_t merge_block = 16; // These are all possibilities. ASSERT_TRUE(TransformationAddDeadBreak(15, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(15, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(21, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(21, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(22, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(22, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(19, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(19, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(23, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(23, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(24, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(24, merge_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 100 is not a block id. ASSERT_FALSE(TransformationAddDeadBreak(100, merge_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(15, 100, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 24 is not a merge block. ASSERT_FALSE(TransformationAddDeadBreak(15, 24, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // These are the transformations we will apply. auto transformation1 = TransformationAddDeadBreak(15, merge_block, true, {}); @@ -147,28 +150,34 @@ TEST(TransformationAddDeadBreakTest, BreaksOutOfSimpleIf) { auto transformation5 = TransformationAddDeadBreak(23, merge_block, true, {}); auto transformation6 = TransformationAddDeadBreak(24, merge_block, false, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -333,6 +342,9 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedIfs) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // The header and merge blocks const uint32_t header_inner = 34; @@ -354,53 +366,53 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedIfs) { // Fine to break from a construct to its merge ASSERT_TRUE(TransformationAddDeadBreak(inner_block_1, merge_inner, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(inner_block_2, merge_inner, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(outer_block_1, merge_outer, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(outer_block_2, merge_outer, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(outer_block_3, merge_outer, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(outer_block_4, merge_outer, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(after_block_1, merge_after, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(after_block_2, merge_after, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break to the wrong merge (whether enclosing or not) ASSERT_FALSE(TransformationAddDeadBreak(inner_block_1, merge_outer, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(inner_block_2, merge_after, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(outer_block_1, merge_inner, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(outer_block_2, merge_after, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(after_block_1, merge_inner, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(after_block_2, merge_outer, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break from header (as it does not branch unconditionally) ASSERT_FALSE(TransformationAddDeadBreak(header_inner, merge_inner, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_outer, merge_outer, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_after, merge_after, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break to non-merge ASSERT_FALSE( TransformationAddDeadBreak(inner_block_1, inner_block_2, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(outer_block_2, after_block_1, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(outer_block_1, header_after, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationAddDeadBreak(inner_block_1, merge_inner, true, {}); @@ -419,36 +431,44 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedIfs) { auto transformation8 = TransformationAddDeadBreak(after_block_2, merge_after, false, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager)); - transformation7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation7.IsApplicable(context.get(), transformation_context)); + transformation7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager)); - transformation8.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation8.IsApplicable(context.get(), transformation_context)); + transformation8.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -685,6 +705,9 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedSwitches) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // The header and merge blocks const uint32_t header_outer_if = 5; @@ -715,63 +738,63 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedSwitches) { // Fine to branch straight to direct merge block for a construct ASSERT_TRUE(TransformationAddDeadBreak(then_outer_switch_block_1, merge_then_outer_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_1, merge_then_inner_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_2, merge_then_inner_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_3, merge_then_inner_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_1, merge_else_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_2, merge_else_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_3, merge_else_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationAddDeadBreak(inner_if_1_block_1, merge_inner_if_1, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(inner_if_1_block_2, merge_inner_if_1, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationAddDeadBreak(inner_if_2_block_1, merge_inner_if_2, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break out of a switch from a selection construct inside the // switch. ASSERT_FALSE(TransformationAddDeadBreak(inner_if_1_block_1, merge_then_outer_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(inner_if_1_block_2, merge_then_outer_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(inner_if_2_block_1, merge_then_outer_switch, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Some miscellaneous inapplicable cases. ASSERT_FALSE( TransformationAddDeadBreak(header_outer_if, merge_outer_if, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_inner_if_1, inner_if_1_block_2, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_then_inner_switch, header_then_outer_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_else_switch, then_inner_switch_block_3, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(header_inner_if_2, header_inner_if_2, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationAddDeadBreak( then_outer_switch_block_1, merge_then_outer_switch, true, {}); @@ -794,44 +817,54 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfNestedSwitches) { auto transformation10 = TransformationAddDeadBreak( inner_if_2_block_1, merge_inner_if_2, true, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager)); - transformation7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation7.IsApplicable(context.get(), transformation_context)); + transformation7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager)); - transformation8.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation8.IsApplicable(context.get(), transformation_context)); + transformation8.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation9.IsApplicable(context.get(), fact_manager)); - transformation9.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation9.IsApplicable(context.get(), transformation_context)); + transformation9.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation10.IsApplicable(context.get(), fact_manager)); - transformation10.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation10.IsApplicable(context.get(), transformation_context)); + transformation10.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1094,6 +1127,9 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfLoopNest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // The header and merge blocks const uint32_t header_do_while = 6; @@ -1123,75 +1159,75 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfLoopNest) { // Fine to break from any loop header to its merge ASSERT_TRUE( TransformationAddDeadBreak(header_do_while, merge_do_while, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(header_for_i, merge_for_i, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadBreak(header_for_j, merge_for_j, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Fine to break from any of the blocks in constructs in the "for j" loop to // that loop's merge ASSERT_TRUE( TransformationAddDeadBreak(block_in_inner_if, merge_for_j, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationAddDeadBreak(block_switch_case, merge_for_j, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationAddDeadBreak(block_switch_default, merge_for_j, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Fine to break from the body of the "for i" loop to that loop's merge ASSERT_TRUE( TransformationAddDeadBreak(block_in_for_i_loop, merge_for_i, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break from multiple loops ASSERT_FALSE( TransformationAddDeadBreak(block_in_inner_if, merge_do_while, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(block_switch_case, merge_do_while, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(block_switch_default, merge_do_while, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(header_for_j, merge_do_while, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break loop from its continue construct ASSERT_FALSE( TransformationAddDeadBreak(continue_do_while, merge_do_while, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(continue_for_j, merge_for_j, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(continue_for_i, merge_for_i, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to break out of multiple non-loop constructs if not breaking to a // loop merge ASSERT_FALSE( TransformationAddDeadBreak(block_in_inner_if, merge_if_x_eq_y, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(block_switch_case, merge_if_x_eq_y, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(block_switch_default, merge_if_x_eq_y, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Some miscellaneous inapplicable transformations ASSERT_FALSE( TransformationAddDeadBreak(header_if_x_eq_2, header_if_x_eq_y, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(merge_if_x_eq_2, merge_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(header_switch, header_switch, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationAddDeadBreak(header_do_while, merge_do_while, true, {}); @@ -1208,32 +1244,39 @@ TEST(TransformationAddDeadBreakTest, BreakOutOfLoopNest) { auto transformation7 = TransformationAddDeadBreak(block_in_for_i_loop, merge_for_i, true, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager)); - transformation7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation7.IsApplicable(context.get(), transformation_context)); + transformation7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1421,12 +1464,15 @@ TEST(TransformationAddDeadBreakTest, NoBreakFromContinueConstruct) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Not OK to break loop from its continue construct ASSERT_FALSE(TransformationAddDeadBreak(13, 12, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(23, 12, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, SelectionInContinueConstruct) { @@ -1509,6 +1555,9 @@ TEST(TransformationAddDeadBreakTest, SelectionInContinueConstruct) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const uint32_t loop_merge = 12; const uint32_t selection_merge = 24; @@ -1520,13 +1569,13 @@ TEST(TransformationAddDeadBreakTest, SelectionInContinueConstruct) { // Not OK to jump from the selection to the loop merge, as this would break // from the loop's continue construct. ASSERT_FALSE(TransformationAddDeadBreak(in_selection_1, loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(in_selection_2, loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(in_selection_3, loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddDeadBreak(in_selection_4, loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // But fine to jump from the selection to its merge. @@ -1539,20 +1588,24 @@ TEST(TransformationAddDeadBreakTest, SelectionInContinueConstruct) { auto transformation4 = TransformationAddDeadBreak(in_selection_4, selection_merge, true, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1720,6 +1773,9 @@ TEST(TransformationAddDeadBreakTest, LoopInContinueConstruct) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const uint32_t outer_loop_merge = 34; const uint32_t outer_loop_block = 33; @@ -1729,22 +1785,24 @@ TEST(TransformationAddDeadBreakTest, LoopInContinueConstruct) { // Some inapplicable cases ASSERT_FALSE( TransformationAddDeadBreak(inner_loop_block, outer_loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationAddDeadBreak(outer_loop_block, inner_loop_merge, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationAddDeadBreak(inner_loop_block, inner_loop_merge, true, {}); auto transformation2 = TransformationAddDeadBreak(outer_loop_block, outer_loop_merge, true, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1936,36 +1994,39 @@ TEST(TransformationAddDeadBreakTest, PhiInstructions) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Some inapplicable transformations // Not applicable because there is already an edge 19->20, so the OpPhis at 20 // do not need to be updated ASSERT_FALSE(TransformationAddDeadBreak(19, 20, true, {13, 21}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because two OpPhis (not zero) need to be updated at 20 ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because two OpPhis (not just one) need to be updated at 20 ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {13}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because the given ids do not have types that match the // OpPhis at 20, in order ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 13}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because id 23 is a label ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 23}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because 101 is not an id ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 101}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because ids 51 and 47 are not available at the end of block // 23 ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {51, 47}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not applicable because OpConstantFalse is not present in the module ASSERT_FALSE(TransformationAddDeadBreak(19, 20, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationAddDeadBreak(19, 20, true, {}); auto transformation2 = TransformationAddDeadBreak(23, 20, true, {13, 21}); @@ -1973,24 +2034,29 @@ TEST(TransformationAddDeadBreakTest, PhiInstructions) { auto transformation4 = TransformationAddDeadBreak(30, 31, true, {21, 13}); auto transformation5 = TransformationAddDeadBreak(75, 31, true, {47, 51}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -2119,9 +2185,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, RespectDominanceRules2) { @@ -2172,9 +2242,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, RespectDominanceRules3) { @@ -2219,11 +2293,15 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules3) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto good_transformation = TransformationAddDeadBreak(100, 101, false, {11}); - ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_TRUE( + good_transformation.IsApplicable(context.get(), transformation_context)); - good_transformation.Apply(context.get(), &fact_manager); + good_transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -2307,11 +2385,15 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules4) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto good_transformation = TransformationAddDeadBreak(102, 101, false, {11}); - ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_TRUE( + good_transformation.IsApplicable(context.get(), transformation_context)); - good_transformation.Apply(context.get(), &fact_manager); + good_transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -2389,9 +2471,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules5) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, RespectDominanceRules6) { @@ -2446,9 +2532,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules6) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) { @@ -2505,9 +2595,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, RespectDominanceRules8) { @@ -2551,9 +2645,13 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules8) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadBreakTest, @@ -2597,12 +2695,16 @@ TEST(TransformationAddDeadBreakTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Bad because 14 comes before 12 in the module, and 14 has no predecessors. // This means that an edge from 12 to 14 will lead to 12 dominating 14, which // is illegal if 12 appears after 14. auto bad_transformation = TransformationAddDeadBreak(12, 14, true, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_add_dead_continue_test.cpp b/test/fuzz/transformation_add_dead_continue_test.cpp index ff93da8a..07ee3b18 100644 --- a/test/fuzz/transformation_add_dead_continue_test.cpp +++ b/test/fuzz/transformation_add_dead_continue_test.cpp @@ -97,57 +97,63 @@ TEST(TransformationAddDeadContinueTest, SimpleExample) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // These are all possibilities. ASSERT_TRUE(TransformationAddDeadContinue(11, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadContinue(11, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadContinue(12, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadContinue(12, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadContinue(40, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationAddDeadContinue(40, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 100 is not a block id. ASSERT_FALSE(TransformationAddDeadContinue(100, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 10 is not in a loop. ASSERT_FALSE(TransformationAddDeadContinue(10, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 15 does not branch unconditionally to a single successor. ASSERT_FALSE(TransformationAddDeadContinue(15, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 13 is not in a loop and has no successor. ASSERT_FALSE(TransformationAddDeadContinue(13, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable: 14 is the loop continue target, so it's not OK to jump to // the loop continue from there. ASSERT_FALSE(TransformationAddDeadContinue(14, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // These are the transformations we will apply. auto transformation1 = TransformationAddDeadContinue(11, true, {}); auto transformation2 = TransformationAddDeadContinue(12, false, {}); auto transformation3 = TransformationAddDeadContinue(40, true, {}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -365,19 +371,24 @@ TEST(TransformationAddDeadContinueTest, LoopNest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); std::vector good = {6, 7, 18, 20, 34, 40, 45, 46, 47, 56, 57}; std::vector bad = {5, 8, 9, 19, 21, 22, 33, 41, 58, 59, 60}; for (uint32_t from_block : bad) { ASSERT_FALSE(TransformationAddDeadContinue(from_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } for (uint32_t from_block : good) { const TransformationAddDeadContinue transformation(from_block, true, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } std::string after_transformation = R"( @@ -600,19 +611,24 @@ TEST(TransformationAddDeadConditionalTest, LoopInContinueConstruct) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); std::vector good = {32, 33, 46, 52, 101}; std::vector bad = {5, 34, 36, 35, 47, 49, 48}; for (uint32_t from_block : bad) { ASSERT_FALSE(TransformationAddDeadContinue(from_block, false, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } for (uint32_t from_block : good) { const TransformationAddDeadContinue transformation(from_block, false, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } std::string after_transformation = R"( @@ -806,6 +822,9 @@ TEST(TransformationAddDeadContinueTest, PhiInstructions) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); std::vector bad = {5, 19, 20, 23, 31, 32, 33, 70}; @@ -813,24 +832,28 @@ TEST(TransformationAddDeadContinueTest, PhiInstructions) { for (uint32_t from_block : bad) { ASSERT_FALSE(TransformationAddDeadContinue(from_block, true, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } auto transformation1 = TransformationAddDeadContinue(29, true, {13, 21}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); auto transformation2 = TransformationAddDeadContinue(30, true, {22, 46}); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); // 75 already has the continue block as a successor, so we should not provide // phi ids. auto transformationBad = TransformationAddDeadContinue(75, true, {27, 46}); - ASSERT_FALSE(transformationBad.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformationBad.IsApplicable(context.get(), transformation_context)); auto transformation3 = TransformationAddDeadContinue(75, true, {}); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader @@ -974,26 +997,33 @@ TEST(TransformationAddDeadContinueTest, RespectDominanceRules1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // This transformation is not applicable because the dead continue from the // loop body prevents the definition of %23 later in the loop body from // dominating its use in the loop's continue target. auto bad_transformation = TransformationAddDeadContinue(13, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); auto good_transformation_1 = TransformationAddDeadContinue(7, false, {}); - ASSERT_TRUE(good_transformation_1.IsApplicable(context.get(), fact_manager)); - good_transformation_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(good_transformation_1.IsApplicable(context.get(), + transformation_context)); + good_transformation_1.Apply(context.get(), &transformation_context); auto good_transformation_2 = TransformationAddDeadContinue(22, false, {}); - ASSERT_TRUE(good_transformation_2.IsApplicable(context.get(), fact_manager)); - good_transformation_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(good_transformation_2.IsApplicable(context.get(), + transformation_context)); + good_transformation_2.Apply(context.get(), &transformation_context); // This transformation is OK, because the definition of %21 in the loop body // is only used in an OpPhi in the loop's continue target. auto good_transformation_3 = TransformationAddDeadContinue(6, false, {11}); - ASSERT_TRUE(good_transformation_3.IsApplicable(context.get(), fact_manager)); - good_transformation_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(good_transformation_3.IsApplicable(context.get(), + transformation_context)); + good_transformation_3.Apply(context.get(), &transformation_context); std::string after_transformations = R"( OpCapability Shader @@ -1083,11 +1113,15 @@ TEST(TransformationAddDeadContinueTest, RespectDominanceRules2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // This transformation would shortcut the part of the loop body that defines // an id used after the loop. auto bad_transformation = TransformationAddDeadContinue(100, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, RespectDominanceRules3) { @@ -1131,11 +1165,15 @@ TEST(TransformationAddDeadContinueTest, RespectDominanceRules3) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // This transformation would shortcut the part of the loop body that defines // an id used after the loop. auto bad_transformation = TransformationAddDeadContinue(100, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous1) { @@ -1270,11 +1308,15 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // This transformation would shortcut the part of the loop body that defines // an id used in the continue target. auto bad_transformation = TransformationAddDeadContinue(165, false, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous2) { @@ -1336,11 +1378,15 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // This transformation would introduce a branch from a continue target to // itself. auto bad_transformation = TransformationAddDeadContinue(1554, true, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous3) { @@ -1394,13 +1440,17 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous3) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadContinue(299, false, {}); // The continue edge would connect %299 to the previously-unreachable %236, // making %299 dominate %236, and breaking the rule that block ordering must // respect dominance. - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous4) { @@ -1454,13 +1504,17 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous4) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadContinue(10, false, {}); // The continue edge would connect %10 to the previously-unreachable %13, // making %10 dominate %13, and breaking the rule that block ordering must // respect dominance. - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous5) { @@ -1506,12 +1560,16 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous5) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadContinue(110, true, {}); // The continue edge would lead to the use of %200 in block %101 no longer // being dominated by its definition in block %111. - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddDeadContinueTest, Miscellaneous6) { @@ -1551,10 +1609,14 @@ TEST(TransformationAddDeadContinueTest, Miscellaneous6) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_transformation = TransformationAddDeadContinue(10, true, {}); - ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_transformation.IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_add_function_test.cpp b/test/fuzz/transformation_add_function_test.cpp index aed12dc0..0d1f2c44 100644 --- a/test/fuzz/transformation_add_function_test.cpp +++ b/test/fuzz/transformation_add_function_test.cpp @@ -59,13 +59,14 @@ std::vector GetInstructionsForFunction( } // Returns true if and only if every pointer parameter and variable associated -// with |function_id| in |context| is known by |fact_manager| to be irrelevant, -// with the exception of |loop_limiter_id|, which must not be irrelevant. (It -// can be 0 if no loop limiter is expected, and 0 should not be deemed -// irrelevant). +// with |function_id| in |context| is known by |transformation_context| to be +// irrelevant, with the exception of |loop_limiter_id|, which must not be +// irrelevant. (It can be 0 if no loop limiter is expected, and 0 should not be +// deemed irrelevant). bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - opt::IRContext* context, const FactManager& fact_manager, - uint32_t function_id, uint32_t loop_limiter_id) { + opt::IRContext* context, + const TransformationContext& transformation_context, uint32_t function_id, + uint32_t loop_limiter_id) { // Look at all the functions until the function of interest is found. for (auto& function : *context->module()) { if (function.result_id() != function_id) { @@ -73,15 +74,16 @@ bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( } // Check that the parameters are all irrelevant. bool found_non_irrelevant_parameter = false; - function.ForEachParam( - [context, &fact_manager, - &found_non_irrelevant_parameter](opt::Instruction* inst) { - if (context->get_def_use_mgr()->GetDef(inst->type_id())->opcode() == - SpvOpTypePointer && - !fact_manager.PointeeValueIsIrrelevant(inst->result_id())) { - found_non_irrelevant_parameter = true; - } - }); + function.ForEachParam([context, &transformation_context, + &found_non_irrelevant_parameter]( + opt::Instruction* inst) { + if (context->get_def_use_mgr()->GetDef(inst->type_id())->opcode() == + SpvOpTypePointer && + !transformation_context.GetFactManager()->PointeeValueIsIrrelevant( + inst->result_id())) { + found_non_irrelevant_parameter = true; + } + }); if (found_non_irrelevant_parameter) { // A non-irrelevant parameter was found. return false; @@ -96,7 +98,8 @@ bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( // The variable should be irrelevant if and only if it is not the loop // limiter. if ((inst.result_id() == loop_limiter_id) == - fact_manager.PointeeValueIsIrrelevant(inst.result_id())) { + transformation_context.GetFactManager()->PointeeValueIsIrrelevant( + inst.result_id())) { return false; } } @@ -142,6 +145,9 @@ TEST(TransformationAddFunctionTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationAddFunction transformation1(std::vector( {MakeInstructionMessage( @@ -212,8 +218,9 @@ TEST(TransformationAddFunctionTest, BasicTest) { {{SPV_OPERAND_TYPE_ID, {39}}}), MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation1 = R"( @@ -278,12 +285,12 @@ TEST(TransformationAddFunctionTest, BasicTest) { OpFunctionEnd )"; ASSERT_TRUE(IsEqual(env, after_transformation1, context.get())); - ASSERT_TRUE(fact_manager.BlockIsDead(14)); - ASSERT_TRUE(fact_manager.BlockIsDead(21)); - ASSERT_TRUE(fact_manager.BlockIsDead(22)); - ASSERT_TRUE(fact_manager.BlockIsDead(23)); - ASSERT_TRUE(fact_manager.BlockIsDead(24)); - ASSERT_TRUE(fact_manager.BlockIsDead(25)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(14)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(21)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(22)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(23)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(24)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(25)); TransformationAddFunction transformation2(std::vector( {MakeInstructionMessage( @@ -332,8 +339,9 @@ TEST(TransformationAddFunctionTest, BasicTest) { MakeInstructionMessage(SpvOpReturn, 0, 0, {}), MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation2 = R"( @@ -414,7 +422,7 @@ TEST(TransformationAddFunctionTest, BasicTest) { OpFunctionEnd )"; ASSERT_TRUE(IsEqual(env, after_transformation2, context.get())); - ASSERT_TRUE(fact_manager.BlockIsDead(16)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(16)); } TEST(TransformationAddFunctionTest, InapplicableTransformations) { @@ -486,11 +494,14 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // No instructions ASSERT_FALSE( TransformationAddFunction(std::vector({})) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No function begin ASSERT_FALSE( @@ -499,7 +510,7 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { {MakeInstructionMessage(SpvOpFunctionParameter, 7, 11, {}), MakeInstructionMessage(SpvOpFunctionParameter, 9, 12, {}), MakeInstructionMessage(SpvOpLabel, 0, 14, {})})) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No OpLabel ASSERT_FALSE( @@ -512,7 +523,7 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { MakeInstructionMessage(SpvOpReturnValue, 0, 0, {{SPV_OPERAND_TYPE_ID, {39}}}), MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Abrupt end of instructions ASSERT_FALSE(TransformationAddFunction( @@ -521,7 +532,7 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, {SPV_OPERAND_TYPE_ID, {10}}})})) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No function end ASSERT_FALSE( @@ -534,7 +545,7 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { MakeInstructionMessage(SpvOpLabel, 0, 14, {}), MakeInstructionMessage(SpvOpReturnValue, 0, 0, {{SPV_OPERAND_TYPE_ID, {39}}})})) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddFunctionTest, LoopLimiters) { @@ -622,20 +633,27 @@ TEST(TransformationAddFunctionTest, LoopLimiters) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The added function should not be deemed livesafe. - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(30)); + ASSERT_FALSE( + transformation_context1.GetFactManager()->FunctionIsLivesafe(30)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 30, 0)); + context1.get(), transformation_context1, 30, 0)); std::string added_as_dead_code = R"( OpCapability Shader @@ -711,16 +729,16 @@ TEST(TransformationAddFunctionTest, LoopLimiters) { TransformationAddFunction add_livesafe_function(instructions, 100, 10, loop_limiters, 0, {}); - ASSERT_TRUE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); - add_livesafe_function.Apply(context2.get(), &fact_manager2); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); + add_livesafe_function.Apply(context2.get(), &transformation_context2); ASSERT_TRUE(IsValid(env, context2.get())); // The added function should indeed be deemed livesafe. - ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(30)); + ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(30)); // All variables/parameters in the function should be deemed irrelevant, // except the loop limiter. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context2.get(), fact_manager2, 30, 100)); + context2.get(), transformation_context2, 30, 100)); std::string added_as_livesafe_code = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -837,20 +855,27 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInVoidFunction) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The added function should not be deemed livesafe. - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(10)); + ASSERT_FALSE( + transformation_context1.GetFactManager()->FunctionIsLivesafe(10)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 10, 0)); + context1.get(), transformation_context1, 10, 0)); std::string added_as_dead_code = R"( OpCapability Shader @@ -887,15 +912,15 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInVoidFunction) { TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0, {}); - ASSERT_TRUE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); - add_livesafe_function.Apply(context2.get(), &fact_manager2); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); + add_livesafe_function.Apply(context2.get(), &transformation_context2); ASSERT_TRUE(IsValid(env, context2.get())); // The added function should indeed be deemed livesafe. - ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(10)); + ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(10)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context2.get(), fact_manager2, 10, 0)); + context2.get(), transformation_context2, 10, 0)); std::string added_as_livesafe_code = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -985,20 +1010,27 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInNonVoidFunction) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The added function should not be deemed livesafe. - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(10)); + ASSERT_FALSE( + transformation_context1.GetFactManager()->FunctionIsLivesafe(10)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 10, 0)); + context1.get(), transformation_context1, 10, 0)); std::string added_as_dead_code = R"( OpCapability Shader @@ -1036,15 +1068,15 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInNonVoidFunction) { TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 13, {}); - ASSERT_TRUE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); - add_livesafe_function.Apply(context2.get(), &fact_manager2); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); + add_livesafe_function.Apply(context2.get(), &transformation_context2); ASSERT_TRUE(IsValid(env, context2.get())); // The added function should indeed be deemed livesafe. - ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(10)); + ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(10)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context2.get(), fact_manager2, 10, 0)); + context2.get(), transformation_context2, 10, 0)); std::string added_as_livesafe_code = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -1265,20 +1297,27 @@ TEST(TransformationAddFunctionTest, ClampedAccessChains) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The function should not be deemed livesafe - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(12)); + ASSERT_FALSE( + transformation_context1.GetFactManager()->FunctionIsLivesafe(12)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 12, 0)); + context1.get(), transformation_context1, 12, 0)); std::string added_as_dead_code = R"( OpCapability Shader @@ -1409,15 +1448,15 @@ TEST(TransformationAddFunctionTest, ClampedAccessChains) { TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 13, access_chain_clamping_info); - ASSERT_TRUE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); - add_livesafe_function.Apply(context2.get(), &fact_manager2); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); + add_livesafe_function.Apply(context2.get(), &transformation_context2); ASSERT_TRUE(IsValid(env, context2.get())); // The function should be deemed livesafe - ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(12)); + ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(12)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context2.get(), fact_manager2, 12, 0)); + context2.get(), transformation_context2, 12, 0)); std::string added_as_livesafe_code = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -1585,23 +1624,29 @@ TEST(TransformationAddFunctionTest, LivesafeCanCallLivesafe) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); // Mark function 6 as livesafe. - fact_manager2.AddFactFunctionIsLivesafe(6); + transformation_context2.GetFactManager()->AddFactFunctionIsLivesafe(6); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The function should not be deemed livesafe - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(8)); + ASSERT_FALSE(transformation_context1.GetFactManager()->FunctionIsLivesafe(8)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 8, 0)); + context1.get(), transformation_context1, 8, 0)); std::string added_as_live_or_dead_code = R"( OpCapability Shader @@ -1630,15 +1675,15 @@ TEST(TransformationAddFunctionTest, LivesafeCanCallLivesafe) { TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0, {}); - ASSERT_TRUE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); - add_livesafe_function.Apply(context2.get(), &fact_manager2); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); + add_livesafe_function.Apply(context2.get(), &transformation_context2); ASSERT_TRUE(IsValid(env, context2.get())); // The function should be deemed livesafe - ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(8)); + ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(8)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context2.get(), fact_manager2, 8, 0)); + context2.get(), transformation_context2, 8, 0)); ASSERT_TRUE(IsEqual(env, added_as_live_or_dead_code, context2.get())); } @@ -1679,20 +1724,26 @@ TEST(TransformationAddFunctionTest, LivesafeOnlyCallsLivesafe) { FactManager fact_manager1; FactManager fact_manager2; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context1(&fact_manager1, + validator_options); + TransformationContext transformation_context2(&fact_manager2, + validator_options); const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption); const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context1.get())); TransformationAddFunction add_dead_function(instructions); - ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1)); - add_dead_function.Apply(context1.get(), &fact_manager1); + ASSERT_TRUE( + add_dead_function.IsApplicable(context1.get(), transformation_context1)); + add_dead_function.Apply(context1.get(), &transformation_context1); ASSERT_TRUE(IsValid(env, context1.get())); // The function should not be deemed livesafe - ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(8)); + ASSERT_FALSE(transformation_context1.GetFactManager()->FunctionIsLivesafe(8)); // All variables/parameters in the function should be deemed irrelevant. ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( - context1.get(), fact_manager1, 8, 0)); + context1.get(), transformation_context1, 8, 0)); std::string added_as_dead_code = R"( OpCapability Shader @@ -1721,8 +1772,8 @@ TEST(TransformationAddFunctionTest, LivesafeOnlyCallsLivesafe) { TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0, {}); - ASSERT_FALSE( - add_livesafe_function.IsApplicable(context2.get(), fact_manager2)); + ASSERT_FALSE(add_livesafe_function.IsApplicable(context2.get(), + transformation_context2)); } TEST(TransformationAddFunctionTest, @@ -1804,6 +1855,9 @@ TEST(TransformationAddFunctionTest, const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -1821,8 +1875,9 @@ TEST(TransformationAddFunctionTest, loop_limiter_info.set_logical_op_id(105); TransformationAddFunction add_livesafe_function(instructions, 100, 32, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager)); - add_livesafe_function.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), + transformation_context)); + add_livesafe_function.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -1958,6 +2013,9 @@ TEST(TransformationAddFunctionTest, const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -1975,8 +2033,9 @@ TEST(TransformationAddFunctionTest, loop_limiter_info.set_logical_op_id(105); TransformationAddFunction add_livesafe_function(instructions, 100, 32, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager)); - add_livesafe_function.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), + transformation_context)); + add_livesafe_function.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -2110,6 +2169,9 @@ TEST(TransformationAddFunctionTest, LoopLimitersHeaderIsBackEdgeBlock) { const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -2127,8 +2189,9 @@ TEST(TransformationAddFunctionTest, LoopLimitersHeaderIsBackEdgeBlock) { loop_limiter_info.set_logical_op_id(105); TransformationAddFunction add_livesafe_function(instructions, 100, 32, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager)); - add_livesafe_function.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), + transformation_context)); + add_livesafe_function.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -2254,6 +2317,9 @@ TEST(TransformationAddFunctionTest, InfiniteLoop1) { const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -2271,8 +2337,9 @@ TEST(TransformationAddFunctionTest, InfiniteLoop1) { loop_limiter_info.set_logical_op_id(105); TransformationAddFunction add_livesafe_function(instructions, 100, 32, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager)); - add_livesafe_function.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), + transformation_context)); + add_livesafe_function.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -2408,6 +2475,9 @@ TEST(TransformationAddFunctionTest, UnreachableContinueConstruct) { const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -2425,8 +2495,9 @@ TEST(TransformationAddFunctionTest, UnreachableContinueConstruct) { loop_limiter_info.set_logical_op_id(105); TransformationAddFunction add_livesafe_function(instructions, 100, 32, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager)); - add_livesafe_function.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), + transformation_context)); + add_livesafe_function.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -2570,6 +2641,9 @@ TEST(TransformationAddFunctionTest, LoopLimitersAndOpPhi1) { const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -2590,15 +2664,17 @@ TEST(TransformationAddFunctionTest, LoopLimitersAndOpPhi1) { {loop_limiter_info}, 0, {}); // The loop limiter info is not good enough; it does not include ids to patch // up the OpPhi at the loop merge. - ASSERT_FALSE(no_op_phi_data.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + no_op_phi_data.IsApplicable(context.get(), transformation_context)); // Add a phi id for the new edge from the loop back edge block to the loop // merge. loop_limiter_info.add_phi_id(28); TransformationAddFunction with_op_phi_data(instructions, 100, 28, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(with_op_phi_data.IsApplicable(context.get(), fact_manager)); - with_op_phi_data.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + with_op_phi_data.IsApplicable(context.get(), transformation_context)); + with_op_phi_data.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader @@ -2758,6 +2834,9 @@ TEST(TransformationAddFunctionTest, LoopLimitersAndOpPhi2) { const auto consumer = nullptr; FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); @@ -2776,8 +2855,9 @@ TEST(TransformationAddFunctionTest, LoopLimitersAndOpPhi2) { TransformationAddFunction transformation(instructions, 100, 28, {loop_limiter_info}, 0, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string expected = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_global_undef_test.cpp b/test/fuzz/transformation_add_global_undef_test.cpp index c14f7e91..8c06db02 100644 --- a/test/fuzz/transformation_add_global_undef_test.cpp +++ b/test/fuzz/transformation_add_global_undef_test.cpp @@ -47,17 +47,20 @@ TEST(TransformationAddGlobalUndefTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use - ASSERT_FALSE(TransformationAddGlobalUndef(4, 11).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddGlobalUndef(4, 11).IsApplicable( + context.get(), transformation_context)); // %1 is not a type - ASSERT_FALSE(TransformationAddGlobalUndef(100, 1).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddGlobalUndef(100, 1).IsApplicable( + context.get(), transformation_context)); // %3 is a function type - ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable( + context.get(), transformation_context)); TransformationAddGlobalUndef transformations[] = { // %100 = OpUndef %6 @@ -79,8 +82,9 @@ TEST(TransformationAddGlobalUndefTest, BasicTest) { TransformationAddGlobalUndef(105, 11)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_global_variable_test.cpp b/test/fuzz/transformation_add_global_variable_test.cpp index 619f068f..9b8faa4c 100644 --- a/test/fuzz/transformation_add_global_variable_test.cpp +++ b/test/fuzz/transformation_add_global_variable_test.cpp @@ -60,49 +60,52 @@ TEST(TransformationAddGlobalVariableTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use ASSERT_FALSE(TransformationAddGlobalVariable(4, 10, 0, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddGlobalVariable(100, 1, 0, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %7 is not a pointer type ASSERT_FALSE(TransformationAddGlobalVariable(100, 7, 0, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %9 does not have Private storage class ASSERT_FALSE(TransformationAddGlobalVariable(100, 9, 0, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %15 does not have Private storage class ASSERT_FALSE(TransformationAddGlobalVariable(100, 15, 0, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %10 is a pointer to float, while %16 is an int constant ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, 16, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %10 is a Private pointer to float, while %15 is a variable with type // Uniform float pointer ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, 15, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %12 is a Private pointer to int, while %10 is a variable with type // Private float pointer ASSERT_FALSE(TransformationAddGlobalVariable(100, 12, 10, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %10 is pointer-to-float, and %14 has type pointer-to-float; that's not OK // since the initializer's type should be the *pointee* type. ASSERT_FALSE(TransformationAddGlobalVariable(104, 10, 14, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // This would work in principle, but logical addressing does not allow // a pointer to a pointer. ASSERT_FALSE(TransformationAddGlobalVariable(104, 17, 14, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddGlobalVariable transformations[] = { // %100 = OpVariable %12 Private @@ -124,15 +127,22 @@ TEST(TransformationAddGlobalVariableTest, BasicTest) { TransformationAddGlobalVariable(105, 19, 22, false)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(104)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(103)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(105)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105)); ASSERT_TRUE(IsValid(env, context.get())); @@ -223,6 +233,9 @@ TEST(TransformationAddGlobalVariableTest, TestEntryPointInterfaceEnlargement) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationAddGlobalVariable transformations[] = { // %100 = OpVariable %12 Private @@ -235,12 +248,16 @@ TEST(TransformationAddGlobalVariableTest, TestEntryPointInterfaceEnlargement) { TransformationAddGlobalVariable(102, 19, 21, true)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( diff --git a/test/fuzz/transformation_add_local_variable_test.cpp b/test/fuzz/transformation_add_local_variable_test.cpp index fd7047f8..e989b33e 100644 --- a/test/fuzz/transformation_add_local_variable_test.cpp +++ b/test/fuzz/transformation_add_local_variable_test.cpp @@ -79,66 +79,81 @@ TEST(TransformationAddLocalVariableTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // A few cases of inapplicable transformations: // Id 4 is already in use ASSERT_FALSE(TransformationAddLocalVariable(4, 50, 4, 51, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Type mismatch between initializer and pointer ASSERT_FALSE(TransformationAddLocalVariable(105, 46, 4, 51, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Id 5 is not a function ASSERT_FALSE(TransformationAddLocalVariable(105, 50, 5, 51, true) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %105 = OpVariable %50 Function %51 { TransformationAddLocalVariable transformation(105, 50, 4, 51, true); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } // %104 = OpVariable %41 Function %46 { TransformationAddLocalVariable transformation(104, 41, 4, 46, false); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } // %103 = OpVariable %35 Function %38 { TransformationAddLocalVariable transformation(103, 35, 4, 38, true); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } // %102 = OpVariable %31 Function %33 { TransformationAddLocalVariable transformation(102, 31, 4, 33, false); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } // %101 = OpVariable %19 Function %29 { TransformationAddLocalVariable transformation(101, 19, 4, 29, true); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } // %100 = OpVariable %8 Function %12 { TransformationAddLocalVariable transformation(100, 8, 4, 12, false); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(101)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(102)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(103)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(104)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(105)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105)); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_no_contraction_decoration_test.cpp b/test/fuzz/transformation_add_no_contraction_decoration_test.cpp index b1a87ead..46841a52 100644 --- a/test/fuzz/transformation_add_no_contraction_decoration_test.cpp +++ b/test/fuzz/transformation_add_no_contraction_decoration_test.cpp @@ -94,23 +94,27 @@ TEST(TransformationAddNoContractionDecorationTest, BasicScenarios) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Invalid: 200 is not an id ASSERT_FALSE(TransformationAddNoContractionDecoration(200).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // Invalid: 17 is a block id ASSERT_FALSE(TransformationAddNoContractionDecoration(17).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // Invalid: 24 is not arithmetic ASSERT_FALSE(TransformationAddNoContractionDecoration(24).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // It is valid to add NoContraction to each of these ids (and it's fine to // have duplicates of the decoration, in the case of 32). for (uint32_t result_id : {32u, 32u, 27u, 29u, 39u}) { TransformationAddNoContractionDecoration transformation(result_id); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_add_type_array_test.cpp b/test/fuzz/transformation_add_type_array_test.cpp index 2bcbe73e..4392f99f 100644 --- a/test/fuzz/transformation_add_type_array_test.cpp +++ b/test/fuzz/transformation_add_type_array_test.cpp @@ -54,37 +54,40 @@ TEST(TransformationAddTypeArrayTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use ASSERT_FALSE(TransformationAddTypeArray(4, 10, 16).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddTypeArray(100, 1, 16) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %3 is a function type ASSERT_FALSE(TransformationAddTypeArray(100, 3, 16) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %2 is not a constant ASSERT_FALSE(TransformationAddTypeArray(100, 11, 2) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %18 is not an integer ASSERT_FALSE(TransformationAddTypeArray(100, 11, 18) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %13 is signed 0 ASSERT_FALSE(TransformationAddTypeArray(100, 11, 13) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %14 is negative ASSERT_FALSE(TransformationAddTypeArray(100, 11, 14) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %17 is unsigned 0 ASSERT_FALSE(TransformationAddTypeArray(100, 11, 17) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddTypeArray transformations[] = { // %100 = OpTypeArray %10 %16 @@ -94,8 +97,9 @@ TEST(TransformationAddTypeArrayTest, BasicTest) { TransformationAddTypeArray(101, 7, 12)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_type_boolean_test.cpp b/test/fuzz/transformation_add_type_boolean_test.cpp index 9975953b..60eabd9d 100644 --- a/test/fuzz/transformation_add_type_boolean_test.cpp +++ b/test/fuzz/transformation_add_type_boolean_test.cpp @@ -42,19 +42,23 @@ TEST(TransformationAddTypeBooleanTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Not applicable because id 1 is already in use. - ASSERT_FALSE(TransformationAddTypeBoolean(1).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeBoolean(1).IsApplicable( + context.get(), transformation_context)); auto add_type_bool = TransformationAddTypeBoolean(100); - ASSERT_TRUE(add_type_bool.IsApplicable(context.get(), fact_manager)); - add_type_bool.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_type_bool.IsApplicable(context.get(), transformation_context)); + add_type_bool.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Not applicable as we already have this type now. - ASSERT_FALSE(TransformationAddTypeBoolean(101).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeBoolean(101).IsApplicable( + context.get(), transformation_context)); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_type_float_test.cpp b/test/fuzz/transformation_add_type_float_test.cpp index 67408da5..7d172667 100644 --- a/test/fuzz/transformation_add_type_float_test.cpp +++ b/test/fuzz/transformation_add_type_float_test.cpp @@ -42,19 +42,23 @@ TEST(TransformationAddTypeFloatTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Not applicable because id 1 is already in use. - ASSERT_FALSE(TransformationAddTypeFloat(1, 32).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeFloat(1, 32).IsApplicable( + context.get(), transformation_context)); auto add_type_float_32 = TransformationAddTypeFloat(100, 32); - ASSERT_TRUE(add_type_float_32.IsApplicable(context.get(), fact_manager)); - add_type_float_32.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + add_type_float_32.IsApplicable(context.get(), transformation_context)); + add_type_float_32.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Not applicable as we already have this type now. - ASSERT_FALSE(TransformationAddTypeFloat(101, 32).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeFloat(101, 32).IsApplicable( + context.get(), transformation_context)); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_type_function_test.cpp b/test/fuzz/transformation_add_type_function_test.cpp index 46bd436b..1557bb81 100644 --- a/test/fuzz/transformation_add_type_function_test.cpp +++ b/test/fuzz/transformation_add_type_function_test.cpp @@ -59,21 +59,24 @@ TEST(TransformationAddTypeFunctionTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use ASSERT_FALSE(TransformationAddTypeFunction(4, 12, {12, 16, 14}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddTypeFunction(100, 1, {12, 16, 14}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %18 is a function type ASSERT_FALSE(TransformationAddTypeFunction(100, 12, {18}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // A function of this signature already exists ASSERT_FALSE(TransformationAddTypeFunction(100, 17, {14, 16}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddTypeFunction transformations[] = { // %100 = OpTypeFunction %12 %12 %16 %14 @@ -86,8 +89,9 @@ TEST(TransformationAddTypeFunctionTest, BasicTest) { TransformationAddTypeFunction(102, 17, {200, 16})}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_type_int_test.cpp b/test/fuzz/transformation_add_type_int_test.cpp index c6f884c2..63b17c22 100644 --- a/test/fuzz/transformation_add_type_int_test.cpp +++ b/test/fuzz/transformation_add_type_int_test.cpp @@ -42,10 +42,13 @@ TEST(TransformationAddTypeIntTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Not applicable because id 1 is already in use. ASSERT_FALSE(TransformationAddTypeInt(1, 32, false) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto add_type_signed_int_32 = TransformationAddTypeInt(100, 32, true); auto add_type_unsigned_int_32 = TransformationAddTypeInt(101, 32, false); @@ -53,20 +56,21 @@ TEST(TransformationAddTypeIntTest, BasicTest) { auto add_type_unsigned_int_32_again = TransformationAddTypeInt(103, 32, false); - ASSERT_TRUE(add_type_signed_int_32.IsApplicable(context.get(), fact_manager)); - add_type_signed_int_32.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_type_signed_int_32.IsApplicable(context.get(), + transformation_context)); + add_type_signed_int_32.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE( - add_type_unsigned_int_32.IsApplicable(context.get(), fact_manager)); - add_type_unsigned_int_32.Apply(context.get(), &fact_manager); + ASSERT_TRUE(add_type_unsigned_int_32.IsApplicable(context.get(), + transformation_context)); + add_type_unsigned_int_32.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Not applicable as we already have these types now. - ASSERT_FALSE( - add_type_signed_int_32_again.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - add_type_unsigned_int_32_again.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(add_type_signed_int_32_again.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(add_type_unsigned_int_32_again.IsApplicable( + context.get(), transformation_context)); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_add_type_matrix_test.cpp b/test/fuzz/transformation_add_type_matrix_test.cpp index 84f27e96..e925012e 100644 --- a/test/fuzz/transformation_add_type_matrix_test.cpp +++ b/test/fuzz/transformation_add_type_matrix_test.cpp @@ -47,17 +47,20 @@ TEST(TransformationAddTypeMatrixTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use - ASSERT_FALSE(TransformationAddTypeMatrix(4, 9, 2).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeMatrix(4, 9, 2).IsApplicable( + context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddTypeMatrix(100, 1, 2).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // %11 is not a floating-point vector ASSERT_FALSE(TransformationAddTypeMatrix(100, 11, 2) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationAddTypeMatrix transformations[] = { // %100 = OpTypeMatrix %8 2 @@ -88,8 +91,9 @@ TEST(TransformationAddTypeMatrixTest, BasicTest) { TransformationAddTypeMatrix(108, 10, 4)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_type_pointer_test.cpp b/test/fuzz/transformation_add_type_pointer_test.cpp index e36707f5..35303e41 100644 --- a/test/fuzz/transformation_add_type_pointer_test.cpp +++ b/test/fuzz/transformation_add_type_pointer_test.cpp @@ -97,6 +97,9 @@ TEST(TransformationAddTypePointerTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto bad_type_id_does_not_exist = TransformationAddTypePointer(100, SpvStorageClassFunction, 101); @@ -122,12 +125,12 @@ TEST(TransformationAddTypePointerTest, BasicTest) { auto good_new_private_pointer_to_uniform_pointer_to_vec2 = TransformationAddTypePointer(108, SpvStorageClassPrivate, 107); - ASSERT_FALSE( - bad_type_id_does_not_exist.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - bad_type_id_is_not_type.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - bad_result_id_is_not_fresh.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_type_id_does_not_exist.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(bad_type_id_is_not_type.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(bad_result_id_is_not_fresh.IsApplicable(context.get(), + transformation_context)); for (auto& transformation : {good_new_private_pointer_to_t, good_new_uniform_pointer_to_t, @@ -136,8 +139,9 @@ TEST(TransformationAddTypePointerTest, BasicTest) { good_new_private_pointer_to_private_pointer_to_float, good_new_uniform_pointer_to_vec2, good_new_private_pointer_to_uniform_pointer_to_vec2}) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_add_type_struct_test.cpp b/test/fuzz/transformation_add_type_struct_test.cpp index ae68c9a2..06f78cd3 100644 --- a/test/fuzz/transformation_add_type_struct_test.cpp +++ b/test/fuzz/transformation_add_type_struct_test.cpp @@ -47,17 +47,20 @@ TEST(TransformationAddTypeStructTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use - ASSERT_FALSE(TransformationAddTypeStruct(4, {}).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeStruct(4, {}).IsApplicable( + context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddTypeStruct(100, {1}).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // %3 is a function type ASSERT_FALSE(TransformationAddTypeStruct(100, {3}).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); TransformationAddTypeStruct transformations[] = { // %100 = OpTypeStruct %6 %7 %8 %9 %10 %11 @@ -73,8 +76,9 @@ TEST(TransformationAddTypeStructTest, BasicTest) { TransformationAddTypeStruct(103, {6, 6})}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_add_type_vector_test.cpp b/test/fuzz/transformation_add_type_vector_test.cpp index 6ac4498e..f1252a30 100644 --- a/test/fuzz/transformation_add_type_vector_test.cpp +++ b/test/fuzz/transformation_add_type_vector_test.cpp @@ -45,13 +45,16 @@ TEST(TransformationAddTypeVectorTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Id already in use - ASSERT_FALSE(TransformationAddTypeVector(4, 6, 2).IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(TransformationAddTypeVector(4, 6, 2).IsApplicable( + context.get(), transformation_context)); // %1 is not a type ASSERT_FALSE(TransformationAddTypeVector(100, 1, 2).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); TransformationAddTypeVector transformations[] = { // %100 = OpTypeVector %6 2 @@ -67,8 +70,9 @@ TEST(TransformationAddTypeVectorTest, BasicTest) { TransformationAddTypeVector(103, 9, 2)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); diff --git a/test/fuzz/transformation_composite_construct_test.cpp b/test/fuzz/transformation_composite_construct_test.cpp index d303368a..e9d7610f 100644 --- a/test/fuzz/transformation_composite_construct_test.cpp +++ b/test/fuzz/transformation_composite_construct_test.cpp @@ -129,6 +129,9 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Make a vec2[3] TransformationCompositeConstruct make_vec2_array_length_3( @@ -138,17 +141,17 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { TransformationCompositeConstruct make_vec2_array_length_3_bad( 37, {41, 45, 27, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 200); - ASSERT_TRUE( - make_vec2_array_length_3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - make_vec2_array_length_3_bad.IsApplicable(context.get(), fact_manager)); - make_vec2_array_length_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_vec2_array_length_3.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(make_vec2_array_length_3_bad.IsApplicable( + context.get(), transformation_context)); + make_vec2_array_length_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2}), context.get())); // Make a float[2] @@ -157,15 +160,15 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { // Bad: %41 does not have type float TransformationCompositeConstruct make_float_array_length_2_bad( 9, {41, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201); - ASSERT_TRUE( - make_float_array_length_2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - make_float_array_length_2_bad.IsApplicable(context.get(), fact_manager)); - make_float_array_length_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_float_array_length_2.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(make_float_array_length_2_bad.IsApplicable( + context.get(), transformation_context)); + make_float_array_length_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1}), context.get())); // Make a bool[3] @@ -176,17 +179,17 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { TransformationCompositeConstruct make_bool_array_length_3_bad( 47, {33, 54, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0), 202); - ASSERT_TRUE( - make_bool_array_length_3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - make_bool_array_length_3_bad.IsApplicable(context.get(), fact_manager)); - make_bool_array_length_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_bool_array_length_3.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(make_bool_array_length_3_bad.IsApplicable( + context.get(), transformation_context)); + make_bool_array_length_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2}), context.get())); // make a uvec3[2][2] @@ -195,17 +198,17 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { // Bad: Skip count 100 is too large. TransformationCompositeConstruct make_uvec3_array_length_2_2_bad( 58, {33, 54}, MakeInstructionDescriptor(64, SpvOpStore, 100), 203); - ASSERT_TRUE( - make_uvec3_array_length_2_2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable(context.get(), - fact_manager)); - make_uvec3_array_length_2_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_uvec3_array_length_2_2.IsApplicable(context.get(), + transformation_context)); + ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable( + context.get(), transformation_context)); + make_uvec3_array_length_2_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}), - MakeDataDescriptor(203, {1}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(100, {}), MakeDataDescriptor(203, {1}), + context.get())); std::string after_transformation = R"( OpCapability Shader @@ -393,6 +396,9 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // make a mat3x4 TransformationCompositeConstruct make_mat34( @@ -400,15 +406,16 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) { // Bad: %35 is mat4x3, not mat3x4. TransformationCompositeConstruct make_mat34_bad( 35, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); - ASSERT_TRUE(make_mat34.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_mat34_bad.IsApplicable(context.get(), fact_manager)); - make_mat34.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_mat34.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_mat34_bad.IsApplicable(context.get(), transformation_context)); + make_mat34.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2}), context.get())); // make a mat4x3 @@ -417,19 +424,20 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) { // Bad: %25 does not match the matrix's column type. TransformationCompositeConstruct make_mat43_bad( 35, {25, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201); - ASSERT_TRUE(make_mat43.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_mat43_bad.IsApplicable(context.get(), fact_manager)); - make_mat43.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_mat43.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_mat43_bad.IsApplicable(context.get(), transformation_context)); + make_mat43.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}), - MakeDataDescriptor(201, {3}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(100, {}), MakeDataDescriptor(201, {3}), + context.get())); std::string after_transformation = R"( OpCapability Shader @@ -602,6 +610,9 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // make an Inner TransformationCompositeConstruct make_inner( @@ -609,13 +620,14 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) { // Bad: Too few fields to make the struct. TransformationCompositeConstruct make_inner_bad( 9, {25}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200); - ASSERT_TRUE(make_inner.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_inner_bad.IsApplicable(context.get(), fact_manager)); - make_inner.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_inner.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_inner_bad.IsApplicable(context.get(), transformation_context)); + make_inner.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1}), context.get())); // make an Outer @@ -626,16 +638,17 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) { TransformationCompositeConstruct make_outer_bad( 33, {46, 200, 56}, MakeInstructionDescriptor(200, SpvOpCompositeConstruct, 0), 201); - ASSERT_TRUE(make_outer.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_outer_bad.IsApplicable(context.get(), fact_manager)); - make_outer.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_outer.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_outer_bad.IsApplicable(context.get(), transformation_context)); + make_outer.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(200, {}), - MakeDataDescriptor(201, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(200, {}), MakeDataDescriptor(201, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2}), context.get())); std::string after_transformation = R"( @@ -922,19 +935,23 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationCompositeConstruct make_vec2( 7, {17, 11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200); // Bad: not enough data for a vec2 TransformationCompositeConstruct make_vec2_bad( 7, {11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200); - ASSERT_TRUE(make_vec2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_vec2_bad.IsApplicable(context.get(), fact_manager)); - make_vec2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_vec2.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_vec2_bad.IsApplicable(context.get(), transformation_context)); + make_vec2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1}), context.get())); TransformationCompositeConstruct make_vec3( @@ -944,17 +961,18 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_vec3_bad( 25, {12, 32, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), 201); - ASSERT_TRUE(make_vec3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_vec3_bad.IsApplicable(context.get(), fact_manager)); - make_vec3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_vec3.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_vec3_bad.IsApplicable(context.get(), transformation_context)); + make_vec3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {0}), - MakeDataDescriptor(201, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {1}), - MakeDataDescriptor(201, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(12, {0}), MakeDataDescriptor(201, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(12, {1}), MakeDataDescriptor(201, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2}), context.get())); TransformationCompositeConstruct make_vec4( @@ -964,17 +982,18 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_vec4_bad( 44, {48, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0), 202); - ASSERT_TRUE(make_vec4.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_vec4_bad.IsApplicable(context.get(), fact_manager)); - make_vec4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_vec4.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_vec4_bad.IsApplicable(context.get(), transformation_context)); + make_vec4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3}), context.get())); TransformationCompositeConstruct make_ivec2( @@ -982,16 +1001,17 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { // Bad: if 128 is not available at the instruction that defines 128 TransformationCompositeConstruct make_ivec2_bad( 51, {128, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203); - ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_ivec2_bad.IsApplicable(context.get(), fact_manager)); - make_ivec2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_ivec2_bad.IsApplicable(context.get(), transformation_context)); + make_ivec2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(126, {}), - MakeDataDescriptor(203, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(120, {}), - MakeDataDescriptor(203, {1}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(126, {}), MakeDataDescriptor(203, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(120, {}), MakeDataDescriptor(203, {1}), + context.get())); TransformationCompositeConstruct make_ivec3( 114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0), @@ -1000,16 +1020,17 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_ivec3_bad( 114, {56, 117, 1300}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0), 204); - ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_ivec3_bad.IsApplicable(context.get(), fact_manager)); - make_ivec3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_ivec3_bad.IsApplicable(context.get(), transformation_context)); + make_ivec3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}), - MakeDataDescriptor(204, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(117, {}), MakeDataDescriptor(204, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2}), context.get())); TransformationCompositeConstruct make_ivec4( @@ -1019,33 +1040,35 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_ivec4_bad( 86, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0), 205); - ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_ivec4_bad.IsApplicable(context.get(), fact_manager)); - make_ivec4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_ivec4_bad.IsApplicable(context.get(), transformation_context)); + make_ivec4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}), - MakeDataDescriptor(205, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}), - MakeDataDescriptor(205, {2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}), - MakeDataDescriptor(205, {3}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {3}), + context.get())); TransformationCompositeConstruct make_uvec2( 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206); TransformationCompositeConstruct make_uvec2_bad( 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 200), 206); - ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_uvec2_bad.IsApplicable(context.get(), fact_manager)); - make_uvec2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_uvec2_bad.IsApplicable(context.get(), transformation_context)); + make_uvec2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1}), context.get())); TransformationCompositeConstruct make_uvec3( @@ -1053,17 +1076,18 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { // Bad because 1300 is not an id TransformationCompositeConstruct make_uvec3_bad( 59, {14, 18, 1300}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207); - ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_uvec3_bad.IsApplicable(context.get(), fact_manager)); - make_uvec3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_uvec3_bad.IsApplicable(context.get(), transformation_context)); + make_uvec3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}), - MakeDataDescriptor(207, {2}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(136, {}), MakeDataDescriptor(207, {2}), + context.get())); TransformationCompositeConstruct make_uvec4( 131, {14, 18, 136, 136}, @@ -1072,20 +1096,21 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_uvec4_bad( 86, {14, 18, 136, 136}, MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208); - ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_uvec4_bad.IsApplicable(context.get(), fact_manager)); - make_uvec4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_uvec4_bad.IsApplicable(context.get(), transformation_context)); + make_uvec4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}), - MakeDataDescriptor(208, {2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}), - MakeDataDescriptor(208, {3}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {3}), + context.get())); TransformationCompositeConstruct make_bvec2( 102, @@ -1102,14 +1127,15 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { 41, }, MakeInstructionDescriptor(0, SpvOpExtInstImport, 0), 209); - ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_bvec2_bad.IsApplicable(context.get(), fact_manager)); - make_bvec2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_bvec2_bad.IsApplicable(context.get(), transformation_context)); + make_bvec2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(111, {}), - MakeDataDescriptor(209, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(111, {}), MakeDataDescriptor(209, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1}), context.get())); TransformationCompositeConstruct make_bvec3( @@ -1117,17 +1143,18 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { // Bad because there are too many components for a bvec3 TransformationCompositeConstruct make_bvec3_bad( 93, {108, 108}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210); - ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_bvec3_bad.IsApplicable(context.get(), fact_manager)); - make_bvec3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_bvec3_bad.IsApplicable(context.get(), transformation_context)); + make_bvec3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}), - MakeDataDescriptor(210, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}), - MakeDataDescriptor(210, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {0}), MakeDataDescriptor(210, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {1}), MakeDataDescriptor(210, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2}), context.get())); TransformationCompositeConstruct make_bvec4( @@ -1135,22 +1162,23 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { // Bad because 21 is a type, not a result id TransformationCompositeConstruct make_bvec4_bad( 70, {21, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211); - ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(make_bvec4_bad.IsApplicable(context.get(), fact_manager)); - make_bvec4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + make_bvec4_bad.IsApplicable(context.get(), transformation_context)); + make_bvec4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}), - MakeDataDescriptor(211, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}), - MakeDataDescriptor(211, {1}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}), - MakeDataDescriptor(211, {2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}), - MakeDataDescriptor(211, {3}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {1}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {3}), + context.get())); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_composite_extract_test.cpp b/test/fuzz/transformation_composite_extract_test.cpp index 5cc21151..d57b62c9 100644 --- a/test/fuzz/transformation_composite_extract_test.cpp +++ b/test/fuzz/transformation_composite_extract_test.cpp @@ -96,100 +96,109 @@ TEST(TransformationCompositeExtractTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Instruction does not exist. ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(36, SpvOpIAdd, 0), 200, 101, {0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Id for composite is not a composite. ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(36, SpvOpIAdd, 0), 200, 27, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Composite does not dominate instruction being inserted before. ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 200, 101, {0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too many indices for extraction from struct composite. ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 200, 101, {0, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too many indices for extraction from struct composite. ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 0, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Out of bounds index for extraction from struct composite. ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Result id already used. ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(35, SpvOpFAdd, 0), 80, 103, {0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationCompositeExtract transformation_1( MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2}); - ASSERT_TRUE(transformation_1.IsApplicable(context.get(), fact_manager)); - transformation_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_1.IsApplicable(context.get(), transformation_context)); + transformation_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); TransformationCompositeExtract transformation_2( MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 202, 104, {0, 2}); - ASSERT_TRUE(transformation_2.IsApplicable(context.get(), fact_manager)); - transformation_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_2.IsApplicable(context.get(), transformation_context)); + transformation_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); TransformationCompositeExtract transformation_3( MakeInstructionDescriptor(29, SpvOpAccessChain, 0), 203, 104, {0}); - ASSERT_TRUE(transformation_3.IsApplicable(context.get(), fact_manager)); - transformation_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_3.IsApplicable(context.get(), transformation_context)); + transformation_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); TransformationCompositeExtract transformation_4( MakeInstructionDescriptor(24, SpvOpStore, 0), 204, 101, {0}); - ASSERT_TRUE(transformation_4.IsApplicable(context.get(), fact_manager)); - transformation_4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_4.IsApplicable(context.get(), transformation_context)); + transformation_4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); TransformationCompositeExtract transformation_5( MakeInstructionDescriptor(29, SpvOpBranch, 0), 205, 102, {2}); - ASSERT_TRUE(transformation_5.IsApplicable(context.get(), fact_manager)); - transformation_5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_5.IsApplicable(context.get(), transformation_context)); + transformation_5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); TransformationCompositeExtract transformation_6( MakeInstructionDescriptor(37, SpvOpReturn, 0), 206, 103, {1}); - ASSERT_TRUE(transformation_6.IsApplicable(context.get(), fact_manager)); - transformation_6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation_6.IsApplicable(context.get(), transformation_context)); + transformation_6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(201, {}), - MakeDataDescriptor(100, {2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(202, {}), - MakeDataDescriptor(104, {0, 2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(203, {}), - MakeDataDescriptor(104, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(204, {}), - MakeDataDescriptor(101, {0}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(205, {}), - MakeDataDescriptor(102, {2}), - context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(206, {}), - MakeDataDescriptor(103, {1}), - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2}), + context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1}), + context.get())); std::string after_transformation = R"( OpCapability Shader @@ -348,49 +357,52 @@ TEST(TransformationCompositeExtractTest, IllegalInsertionPoints) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Cannot insert before the OpVariables of a function. ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, {0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, {1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationCompositeExtract( MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, {1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK to insert right after the OpVariables. ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, {1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before the OpPhis of a block. ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(60, SpvOpPhi, 0), 200, 14, {2}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(59, SpvOpPhi, 0), 200, 14, {3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK to insert after the OpPhis. ASSERT_TRUE( TransformationCompositeExtract( MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14, {3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpLoopMerge ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(33, SpvOpBranchConditional, 0), 200, 14, {3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpSelectionMerge ASSERT_FALSE(TransformationCompositeExtract( MakeInstructionDescriptor(21, SpvOpBranchConditional, 0), 200, 14, {2}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_copy_object_test.cpp b/test/fuzz/transformation_copy_object_test.cpp index b85f75b4..fa5a5b12 100644 --- a/test/fuzz/transformation_copy_object_test.cpp +++ b/test/fuzz/transformation_copy_object_test.cpp @@ -51,77 +51,95 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - ASSERT_EQ(0, - fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()).size()); + ASSERT_EQ(0, transformation_context.GetFactManager() + ->GetIdsForWhichSynonymsAreKnown(context.get()) + .size()); { TransformationCopyObject copy_true( 7, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100); - ASSERT_TRUE(copy_true.IsApplicable(context.get(), fact_manager)); - copy_true.Apply(context.get(), &fact_manager); + ASSERT_TRUE(copy_true.IsApplicable(context.get(), transformation_context)); + copy_true.Apply(context.get(), &transformation_context); std::vector ids_for_which_synonyms_are_known = - fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()); + transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( + context.get()); ASSERT_EQ(2, ids_for_which_synonyms_are_known.size()); ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ids_for_which_synonyms_are_known.end(), 7) != ids_for_which_synonyms_are_known.end()); - ASSERT_EQ(2, fact_manager.GetSynonymsForId(7, context.get()).size()); + ASSERT_EQ(2, transformation_context.GetFactManager() + ->GetSynonymsForId(7, context.get()) + .size()); protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}), - descriptor_100, context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(7, {}), descriptor_100, context.get())); } { TransformationCopyObject copy_false( 8, MakeInstructionDescriptor(100, SpvOpReturn, 0), 101); - ASSERT_TRUE(copy_false.IsApplicable(context.get(), fact_manager)); - copy_false.Apply(context.get(), &fact_manager); + ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context)); + copy_false.Apply(context.get(), &transformation_context); std::vector ids_for_which_synonyms_are_known = - fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()); + transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( + context.get()); ASSERT_EQ(4, ids_for_which_synonyms_are_known.size()); ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ids_for_which_synonyms_are_known.end(), 8) != ids_for_which_synonyms_are_known.end()); - ASSERT_EQ(2, fact_manager.GetSynonymsForId(8, context.get()).size()); + ASSERT_EQ(2, transformation_context.GetFactManager() + ->GetSynonymsForId(8, context.get()) + .size()); protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(8, {}), - descriptor_101, context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(8, {}), descriptor_101, context.get())); } { TransformationCopyObject copy_false_again( 101, MakeInstructionDescriptor(5, SpvOpReturn, 0), 102); - ASSERT_TRUE(copy_false_again.IsApplicable(context.get(), fact_manager)); - copy_false_again.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + copy_false_again.IsApplicable(context.get(), transformation_context)); + copy_false_again.Apply(context.get(), &transformation_context); std::vector ids_for_which_synonyms_are_known = - fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()); + transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( + context.get()); ASSERT_EQ(5, ids_for_which_synonyms_are_known.size()); ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ids_for_which_synonyms_are_known.end(), 101) != ids_for_which_synonyms_are_known.end()); - ASSERT_EQ(3, fact_manager.GetSynonymsForId(101, context.get()).size()); + ASSERT_EQ(3, transformation_context.GetFactManager() + ->GetSynonymsForId(101, context.get()) + .size()); protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(101, {}), - descriptor_102, context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(101, {}), descriptor_102, context.get())); } { TransformationCopyObject copy_true_again( 7, MakeInstructionDescriptor(102, SpvOpReturn, 0), 103); - ASSERT_TRUE(copy_true_again.IsApplicable(context.get(), fact_manager)); - copy_true_again.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + copy_true_again.IsApplicable(context.get(), transformation_context)); + copy_true_again.Apply(context.get(), &transformation_context); std::vector ids_for_which_synonyms_are_known = - fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()); + transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( + context.get()); ASSERT_EQ(6, ids_for_which_synonyms_are_known.size()); ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ids_for_which_synonyms_are_known.end(), 7) != ids_for_which_synonyms_are_known.end()); - ASSERT_EQ(3, fact_manager.GetSynonymsForId(7, context.get()).size()); + ASSERT_EQ(3, transformation_context.GetFactManager() + ->GetSynonymsForId(7, context.get()) + .size()); protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}), - descriptor_103, context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(7, {}), descriptor_103, context.get())); } std::string after_transformation = R"( @@ -340,116 +358,119 @@ TEST(TransformationCopyObjectTest, CheckIllegalCases) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Inapplicable because %18 is decorated. ASSERT_FALSE(TransformationCopyObject( 18, MakeInstructionDescriptor(21, SpvOpAccessChain, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because %77 is decorated. ASSERT_FALSE(TransformationCopyObject( 77, MakeInstructionDescriptor(77, SpvOpBranch, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because %80 is decorated. ASSERT_FALSE(TransformationCopyObject( 80, MakeInstructionDescriptor(77, SpvOpIAdd, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because %84 is not available at the requested point ASSERT_FALSE( TransformationCopyObject( 84, MakeInstructionDescriptor(32, SpvOpCompositeExtract, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Fine because %84 is available at the requested point ASSERT_TRUE( TransformationCopyObject( 84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because id %9 is already in use ASSERT_FALSE( TransformationCopyObject( 84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 9) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the requested point does not exist ASSERT_FALSE(TransformationCopyObject( 84, MakeInstructionDescriptor(86, SpvOpReturn, 2), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because %9 is not in a function ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(9, SpvOpTypeInt, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right before, or inside, a chunk // of OpPhis ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(30, SpvOpPhi, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(99, SpvOpPhi, 1), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is just after a chunk of OpPhis. ASSERT_TRUE(TransformationCopyObject( 9, MakeInstructionDescriptor(96, SpvOpAccessChain, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right after an OpSelectionMerge ASSERT_FALSE( TransformationCopyObject( 9, MakeInstructionDescriptor(58, SpvOpBranchConditional, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is right before the OpSelectionMerge ASSERT_TRUE(TransformationCopyObject( 9, MakeInstructionDescriptor(58, SpvOpSelectionMerge, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right after an OpSelectionMerge ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(43, SpvOpSwitch, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is right before the OpSelectionMerge ASSERT_TRUE(TransformationCopyObject( 9, MakeInstructionDescriptor(43, SpvOpSelectionMerge, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right after an OpLoopMerge ASSERT_FALSE( TransformationCopyObject( 9, MakeInstructionDescriptor(40, SpvOpBranchConditional, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is right before the OpLoopMerge ASSERT_TRUE(TransformationCopyObject( 9, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because id %300 does not exist ASSERT_FALSE(TransformationCopyObject( 300, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the following instruction is OpVariable ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(180, SpvOpVariable, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(181, SpvOpVariable, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(182, SpvOpVariable, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK, because this is just past the group of OpVariable instructions. ASSERT_TRUE(TransformationCopyObject( 9, MakeInstructionDescriptor(182, SpvOpAccessChain, 0), 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationCopyObjectTest, MiscellaneousCopies) { @@ -515,6 +536,9 @@ TEST(TransformationCopyObjectTest, MiscellaneousCopies) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); std::vector transformations = { TransformationCopyObject(19, MakeInstructionDescriptor(22, SpvOpStore, 0), @@ -533,8 +557,9 @@ TEST(TransformationCopyObjectTest, MiscellaneousCopies) { 17, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 106)}; for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); } ASSERT_TRUE(IsValid(env, context.get())); @@ -614,16 +639,19 @@ TEST(TransformationCopyObjectTest, DoNotCopyNullOrUndefPointers) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Illegal to copy null. ASSERT_FALSE(TransformationCopyObject( 8, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Illegal to copy an OpUndef of pointer type. ASSERT_FALSE(TransformationCopyObject( 9, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationCopyObjectTest, PropagateIrrelevantPointeeFact) { @@ -655,7 +683,11 @@ TEST(TransformationCopyObjectTest, PropagateIrrelevantPointeeFact) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFactValueOfPointeeIsIrrelevant(8); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(8); TransformationCopyObject transformation1( 8, MakeInstructionDescriptor(9, SpvOpReturn, 0), 100); @@ -664,18 +696,26 @@ TEST(TransformationCopyObjectTest, PropagateIrrelevantPointeeFact) { TransformationCopyObject transformation3( 100, MakeInstructionDescriptor(9, SpvOpReturn, 0), 102); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(8)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(9)); - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(8)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(9)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); } } // namespace diff --git a/test/fuzz/transformation_equation_instruction_test.cpp b/test/fuzz/transformation_equation_instruction_test.cpp index 81d849b4..be9024e0 100644 --- a/test/fuzz/transformation_equation_instruction_test.cpp +++ b/test/fuzz/transformation_equation_instruction_test.cpp @@ -48,6 +48,9 @@ TEST(TransformationEquationInstructionTest, SignedNegate) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); protobufs::InstructionDescriptor return_instruction = MakeInstructionDescriptor(13, SpvOpReturn, 0); @@ -55,58 +58,60 @@ TEST(TransformationEquationInstructionTest, SignedNegate) { // Bad: id already in use. ASSERT_FALSE(TransformationEquationInstruction(7, SpvOpSNegate, {7}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: identified instruction does not exist. ASSERT_FALSE( TransformationEquationInstruction( 14, SpvOpSNegate, {7}, MakeInstructionDescriptor(13, SpvOpLoad, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: id 100 does not exist ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {100}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: id 20 is an OpUndef ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {20}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: id 30 is not available right before its definition ASSERT_FALSE(TransformationEquationInstruction( 14, SpvOpSNegate, {30}, MakeInstructionDescriptor(30, SpvOpCopyObject, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: too many arguments to OpSNegate. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {7, 7}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: 40 is a type id. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {40}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: wrong type of argument to OpSNegate. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {41}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( 14, SpvOpSNegate, {7}, return_instruction); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation2 = TransformationEquationInstruction( 15, SpvOpSNegate, {14}, return_instruction); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get())); std::string after_transformation = R"( @@ -161,6 +166,9 @@ TEST(TransformationEquationInstructionTest, LogicalNot) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); protobufs::InstructionDescriptor return_instruction = MakeInstructionDescriptor(13, SpvOpReturn, 0); @@ -168,31 +176,33 @@ TEST(TransformationEquationInstructionTest, LogicalNot) { // Bad: too few arguments to OpLogicalNot. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: 6 is a type id. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {6}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: wrong type of argument to OpLogicalNot. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {21}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( 14, SpvOpLogicalNot, {7}, return_instruction); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation2 = TransformationEquationInstruction( 15, SpvOpLogicalNot, {14}, return_instruction); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get())); std::string after_transformation = R"( @@ -248,6 +258,9 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); protobufs::InstructionDescriptor return_instruction = MakeInstructionDescriptor(13, SpvOpReturn, 0); @@ -255,58 +268,63 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { // Bad: too many arguments to OpIAdd. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 16, 16}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: boolean argument to OpIAdd. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 32}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: type as argument to OpIAdd. ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {33, 16}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: arguments of mismatched widths ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 31}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: arguments of mismatched widths ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {31, 15}, return_instruction) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( 14, SpvOpIAdd, {15, 16}, return_instruction); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation2 = TransformationEquationInstruction( 19, SpvOpISub, {14, 16}, return_instruction); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {}), context.get())); auto transformation3 = TransformationEquationInstruction( 20, SpvOpISub, {14, 15}, return_instruction); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); auto transformation4 = TransformationEquationInstruction( 22, SpvOpISub, {16, 14}, return_instruction); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation5 = TransformationEquationInstruction( 24, SpvOpSNegate, {22}, return_instruction); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get())); std::string after_transformation = R"( @@ -364,68 +382,79 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); protobufs::InstructionDescriptor return_instruction = MakeInstructionDescriptor(13, SpvOpReturn, 0); auto transformation1 = TransformationEquationInstruction( 14, SpvOpISub, {15, 16}, return_instruction); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation2 = TransformationEquationInstruction( 17, SpvOpIAdd, {14, 16}, return_instruction); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get())); auto transformation3 = TransformationEquationInstruction( 18, SpvOpIAdd, {16, 14}, return_instruction); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get())); auto transformation4 = TransformationEquationInstruction( 19, SpvOpISub, {14, 15}, return_instruction); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation5 = TransformationEquationInstruction( 20, SpvOpSNegate, {19}, return_instruction); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); auto transformation6 = TransformationEquationInstruction( 21, SpvOpISub, {14, 19}, return_instruction); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get())); auto transformation7 = TransformationEquationInstruction( 22, SpvOpISub, {14, 18}, return_instruction); - ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager)); - transformation7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation7.IsApplicable(context.get(), transformation_context)); + transformation7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto transformation8 = TransformationEquationInstruction( 23, SpvOpSNegate, {22}, return_instruction); - ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager)); - transformation8.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation8.IsApplicable(context.get(), transformation_context)); + transformation8.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.IsSynonymous( + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get())); std::string after_transformation = R"( diff --git a/test/fuzz/transformation_function_call_test.cpp b/test/fuzz/transformation_function_call_test.cpp index 9bd971e2..d7305f87 100644 --- a/test/fuzz/transformation_function_call_test.cpp +++ b/test/fuzz/transformation_function_call_test.cpp @@ -134,24 +134,36 @@ TEST(TransformationFunctionCallTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFactBlockIsDead(59); - fact_manager.AddFactBlockIsDead(11); - fact_manager.AddFactBlockIsDead(18); - fact_manager.AddFactBlockIsDead(25); - fact_manager.AddFactBlockIsDead(96); - fact_manager.AddFactBlockIsDead(205); - fact_manager.AddFactFunctionIsLivesafe(21); - fact_manager.AddFactFunctionIsLivesafe(200); - fact_manager.AddFactValueOfPointeeIsIrrelevant(71); - fact_manager.AddFactValueOfPointeeIsIrrelevant(72); - fact_manager.AddFactValueOfPointeeIsIrrelevant(19); - fact_manager.AddFactValueOfPointeeIsIrrelevant(20); - fact_manager.AddFactValueOfPointeeIsIrrelevant(23); - fact_manager.AddFactValueOfPointeeIsIrrelevant(44); - fact_manager.AddFactValueOfPointeeIsIrrelevant(46); - fact_manager.AddFactValueOfPointeeIsIrrelevant(51); - fact_manager.AddFactValueOfPointeeIsIrrelevant(52); + transformation_context.GetFactManager()->AddFactBlockIsDead(59); + transformation_context.GetFactManager()->AddFactBlockIsDead(11); + transformation_context.GetFactManager()->AddFactBlockIsDead(18); + transformation_context.GetFactManager()->AddFactBlockIsDead(25); + transformation_context.GetFactManager()->AddFactBlockIsDead(96); + transformation_context.GetFactManager()->AddFactBlockIsDead(205); + transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(21); + transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(200); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 71); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 72); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 19); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 20); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 23); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 44); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 46); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 51); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 52); // Livesafe functions with argument types: 21(7, 13), 200(7, 13) // Non-livesafe functions with argument types: 4(), 10(7), 17(7, 13), 24(7) @@ -164,127 +176,133 @@ TEST(TransformationFunctionCallTest, BasicTest) { ASSERT_FALSE( TransformationFunctionCall(100, 21, {71, 72, 71}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too few arguments ASSERT_FALSE(TransformationFunctionCall( 100, 21, {71}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Arguments are the wrong way around (types do not match) ASSERT_FALSE( TransformationFunctionCall(100, 21, {72, 71}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // 21 is not an appropriate argument ASSERT_FALSE( TransformationFunctionCall(100, 21, {21, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // 300 does not exist ASSERT_FALSE( TransformationFunctionCall(100, 21, {300, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // 71 is not a function ASSERT_FALSE( TransformationFunctionCall(100, 71, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // 500 does not exist ASSERT_FALSE( TransformationFunctionCall(100, 500, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Id is not fresh ASSERT_FALSE( TransformationFunctionCall(21, 21, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Access chain as pointer parameter ASSERT_FALSE( TransformationFunctionCall(100, 21, {98, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Copied object as pointer parameter ASSERT_FALSE( TransformationFunctionCall(100, 21, {99, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Non-livesafe called from original live block ASSERT_FALSE( TransformationFunctionCall( 100, 10, {71}, MakeInstructionDescriptor(99, SpvOpSelectionMerge, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Non-livesafe called from livesafe function ASSERT_FALSE( TransformationFunctionCall( 100, 10, {19}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Livesafe function called with pointer to non-arbitrary local variable ASSERT_FALSE( TransformationFunctionCall( 100, 21, {61, 72}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Direct recursion ASSERT_FALSE(TransformationFunctionCall( 100, 4, {}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Indirect recursion ASSERT_FALSE(TransformationFunctionCall( 100, 24, {9}, MakeInstructionDescriptor(96, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Parameter 23 is not available at the call site ASSERT_FALSE( TransformationFunctionCall(104, 10, {23}, MakeInstructionDescriptor(205, SpvOpBranch, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Good transformations { // Livesafe called from dead block: fine TransformationFunctionCall transformation( 100, 21, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { // Livesafe called from original live block: fine TransformationFunctionCall transformation( 101, 21, {71, 72}, MakeInstructionDescriptor(98, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { // Livesafe called from livesafe function: fine TransformationFunctionCall transformation( 102, 200, {19, 20}, MakeInstructionDescriptor(36, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { // Dead called from dead block in injected function: fine TransformationFunctionCall transformation( 103, 10, {23}, MakeInstructionDescriptor(45, SpvOpLoad, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { // Non-livesafe called from dead block in livesafe function: OK TransformationFunctionCall transformation( 104, 10, {201}, MakeInstructionDescriptor(205, SpvOpBranch, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { // Livesafe called from dead block with non-arbitrary parameter TransformationFunctionCall transformation( 105, 21, {62, 65}, MakeInstructionDescriptor(59, SpvOpBranch, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -429,13 +447,16 @@ TEST(TransformationFunctionCallTest, DoNotInvokeEntryPoint) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFactBlockIsDead(11); + transformation_context.GetFactManager()->AddFactBlockIsDead(11); // 4 is an entry point, so it is not legal for it to be the target of a call. ASSERT_FALSE(TransformationFunctionCall( 100, 4, {}, MakeInstructionDescriptor(11, SpvOpReturn, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_load_test.cpp b/test/fuzz/transformation_load_test.cpp index 1f728ffc..18ca195e 100644 --- a/test/fuzz/transformation_load_test.cpp +++ b/test/fuzz/transformation_load_test.cpp @@ -85,14 +85,22 @@ TEST(TransformationLoadTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFactValueOfPointeeIsIrrelevant(27); - fact_manager.AddFactValueOfPointeeIsIrrelevant(11); - fact_manager.AddFactValueOfPointeeIsIrrelevant(46); - fact_manager.AddFactValueOfPointeeIsIrrelevant(16); - fact_manager.AddFactValueOfPointeeIsIrrelevant(52); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 27); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 11); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 46); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 16); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 52); - fact_manager.AddFactBlockIsDead(36); + transformation_context.GetFactManager()->AddFactBlockIsDead(36); // Variables with pointee types: // 52 - ptr_to(7) @@ -125,86 +133,90 @@ TEST(TransformationLoadTest, BasicTest) { // Bad: id is not fresh ASSERT_FALSE(TransformationLoad( 33, 33, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to load from 11 from outside its function ASSERT_FALSE(TransformationLoad( 100, 11, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is not available ASSERT_FALSE(TransformationLoad( 100, 33, MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before OpVariable ASSERT_FALSE(TransformationLoad( 100, 27, MakeInstructionDescriptor(27, SpvOpVariable, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist ASSERT_FALSE( TransformationLoad(100, 1000, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists but does not have a type ASSERT_FALSE(TransformationLoad( 100, 5, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists and has a type, but is not a pointer ASSERT_FALSE(TransformationLoad( 100, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to load from null pointer ASSERT_FALSE(TransformationLoad( 100, 60, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to load from undefined pointer ASSERT_FALSE(TransformationLoad( 100, 61, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: %40 is not available at the program point ASSERT_FALSE( TransformationLoad(100, 40, MakeInstructionDescriptor(37, SpvOpReturn, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: The described instruction does not exist ASSERT_FALSE(TransformationLoad( 100, 33, MakeInstructionDescriptor(1000, SpvOpReturn, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); { TransformationLoad transformation( 100, 33, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { TransformationLoad transformation( 101, 46, MakeInstructionDescriptor(16, SpvOpReturnValue, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { TransformationLoad transformation( 102, 16, MakeInstructionDescriptor(16, SpvOpReturnValue, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { TransformationLoad transformation( 103, 40, MakeInstructionDescriptor(43, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_merge_blocks_test.cpp b/test/fuzz/transformation_merge_blocks_test.cpp index e2b4aa65..4500445b 100644 --- a/test/fuzz/transformation_merge_blocks_test.cpp +++ b/test/fuzz/transformation_merge_blocks_test.cpp @@ -45,11 +45,14 @@ TEST(TransformationMergeBlocksTest, BlockDoesNotExist) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - ASSERT_FALSE( - TransformationMergeBlocks(3).IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE( - TransformationMergeBlocks(7).IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(TransformationMergeBlocks(3).IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(TransformationMergeBlocks(7).IsApplicable( + context.get(), transformation_context)); } TEST(TransformationMergeBlocksTest, DoNotMergeFirstBlockHasMultipleSuccessors) { @@ -84,9 +87,12 @@ TEST(TransformationMergeBlocksTest, DoNotMergeFirstBlockHasMultipleSuccessors) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - ASSERT_FALSE( - TransformationMergeBlocks(6).IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(TransformationMergeBlocks(6).IsApplicable( + context.get(), transformation_context)); } TEST(TransformationMergeBlocksTest, @@ -122,9 +128,12 @@ TEST(TransformationMergeBlocksTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - ASSERT_FALSE( - TransformationMergeBlocks(10).IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(TransformationMergeBlocks(10).IsApplicable( + context.get(), transformation_context)); } TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionMerge) { @@ -161,10 +170,14 @@ TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionMerge) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationMergeBlocks transformation(10); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -231,10 +244,14 @@ TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsLoopMerge) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationMergeBlocks transformation(10); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -306,10 +323,14 @@ TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsLoopContinue) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationMergeBlocks transformation(11); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -377,10 +398,14 @@ TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockStartsWithOpPhi) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationMergeBlocks transformation(6); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -454,12 +479,16 @@ TEST(TransformationMergeBlocksTest, BasicMerge) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); for (auto& transformation : {TransformationMergeBlocks(100), TransformationMergeBlocks(101), TransformationMergeBlocks(102), TransformationMergeBlocks(103)}) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -542,11 +571,15 @@ TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionHeader) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); for (auto& transformation : {TransformationMergeBlocks(101), TransformationMergeBlocks(100)}) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -629,10 +662,14 @@ TEST(TransformationMergeBlocksTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationMergeBlocks transformation(101); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( diff --git a/test/fuzz/transformation_move_block_down_test.cpp b/test/fuzz/transformation_move_block_down_test.cpp index 02761a2c..662e88c0 100644 --- a/test/fuzz/transformation_move_block_down_test.cpp +++ b/test/fuzz/transformation_move_block_down_test.cpp @@ -53,9 +53,13 @@ TEST(TransformationMoveBlockDownTest, NoMovePossible1) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto transformation = TransformationMoveBlockDown(11); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationMoveBlockDownTest, NoMovePossible2) { @@ -90,9 +94,13 @@ TEST(TransformationMoveBlockDownTest, NoMovePossible2) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto transformation = TransformationMoveBlockDown(5); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationMoveBlockDownTest, NoMovePossible3) { @@ -129,9 +137,13 @@ TEST(TransformationMoveBlockDownTest, NoMovePossible3) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto transformation = TransformationMoveBlockDown(100); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationMoveBlockDownTest, NoMovePossible4) { @@ -172,9 +184,13 @@ TEST(TransformationMoveBlockDownTest, NoMovePossible4) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto transformation = TransformationMoveBlockDown(12); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationMoveBlockDownTest, ManyMovesPossible) { @@ -277,6 +293,9 @@ TEST(TransformationMoveBlockDownTest, ManyMovesPossible) { BuildModule(env, consumer, before_transformation, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // The block ids are: 5 14 20 23 21 25 29 32 30 15 // We make a transformation to move each of them down, plus a transformation @@ -306,110 +325,130 @@ TEST(TransformationMoveBlockDownTest, ManyMovesPossible) { // 15 dominates nothing // Current ordering: 5 14 20 23 21 25 29 32 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); // Let's bubble 20 all the way down. - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 20 21 25 29 32 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 21 20 25 29 32 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 21 25 20 29 32 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 21 25 29 20 32 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 21 25 29 32 20 30 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 23 21 25 29 32 30 20 15 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_15.IsApplicable(context.get(), transformation_context)); - move_down_20.Apply(context.get(), &fact_manager); + move_down_20.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_bubbling_20_down = R"( @@ -485,63 +524,72 @@ TEST(TransformationMoveBlockDownTest, ManyMovesPossible) { ASSERT_TRUE(IsEqual(env, after_bubbling_20_down, context.get())); // Current ordering: 5 14 23 21 25 29 32 30 15 20 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_20.IsApplicable(context.get(), transformation_context)); - move_down_23.Apply(context.get(), &fact_manager); + move_down_23.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 21 23 25 29 32 30 15 20 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_20.IsApplicable(context.get(), transformation_context)); - move_down_23.Apply(context.get(), &fact_manager); + move_down_23.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 21 25 23 29 32 30 15 20 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_20.IsApplicable(context.get(), transformation_context)); - move_down_21.Apply(context.get(), &fact_manager); + move_down_21.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Current ordering: 5 14 25 21 23 29 32 30 15 20 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_20.IsApplicable(context.get(), transformation_context)); - move_down_14.Apply(context.get(), &fact_manager); + move_down_14.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_more_shuffling = R"( @@ -617,16 +665,18 @@ TEST(TransformationMoveBlockDownTest, ManyMovesPossible) { ASSERT_TRUE(IsEqual(env, after_more_shuffling, context.get())); // Final ordering: 5 25 14 21 23 29 32 30 15 20 - ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager)); - ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_14.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + move_down_20.IsApplicable(context.get(), transformation_context)); } TEST(TransformationMoveBlockDownTest, DoNotMoveUnreachable) { @@ -660,9 +710,13 @@ TEST(TransformationMoveBlockDownTest, DoNotMoveUnreachable) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto transformation = TransformationMoveBlockDown(6); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_outline_function_test.cpp b/test/fuzz/transformation_outline_function_test.cpp index 40aaebc9..7beed851 100644 --- a/test/fuzz/transformation_outline_function_test.cpp +++ b/test/fuzz/transformation_outline_function_test.cpp @@ -44,12 +44,16 @@ TEST(TransformationOutlineFunctionTest, TrivialOutline) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(5, 5, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -105,11 +109,15 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(5, 5, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, OutlineInterestingControlFlowNoState) { @@ -158,12 +166,16 @@ TEST(TransformationOutlineFunctionTest, OutlineInterestingControlFlowNoState) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 13, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -243,12 +255,16 @@ TEST(TransformationOutlineFunctionTest, OutlineCodeThatGeneratesUnusedIds) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 6, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -317,11 +333,15 @@ TEST(TransformationOutlineFunctionTest, OutlineCodeThatGeneratesSingleUsedId) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 6, 99, 100, 101, 102, 103, 105, {}, {{9, 104}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -412,12 +432,16 @@ TEST(TransformationOutlineFunctionTest, OutlineDiamondThatGeneratesSeveralIds) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( 6, 80, 100, 101, 102, 103, 104, 105, {}, {{15, 106}, {9, 107}, {7, 108}, {8, 109}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -508,11 +532,15 @@ TEST(TransformationOutlineFunctionTest, OutlineCodeThatUsesASingleId) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 6, 100, 101, 102, 103, 104, 105, {{7, 106}}, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -582,11 +610,15 @@ TEST(TransformationOutlineFunctionTest, OutlineCodeThatUsesAVariable) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 6, 100, 101, 102, 103, 104, 105, {{13, 106}}, {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -666,11 +698,15 @@ TEST(TransformationOutlineFunctionTest, OutlineCodeThatUsesAParameter) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(11, 11, 100, 101, 102, 103, 104, 105, {{9, 106}}, {{14, 107}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -752,10 +788,14 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 8, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesReturn) { @@ -798,11 +838,15 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesReturn) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesKill) { @@ -845,11 +889,15 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesKill) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -893,11 +941,15 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200, 100, 101, 102, 103, /* not relevant */ 201, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -933,10 +985,14 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 8, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, DoNotOutlineIfLoopHeadIsOutsideRegion) { @@ -973,10 +1029,14 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineIfLoopHeadIsOutsideRegion) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(7, 8, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1012,10 +1072,14 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 7, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1053,10 +1117,14 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(6, 7, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1094,10 +1162,14 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation(8, 11, 100, 101, 102, 103, 104, 105, {}, {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnVoid) { @@ -1132,6 +1204,9 @@ TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnVoid) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 54, @@ -1145,8 +1220,9 @@ TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnVoid) { /*input_id_to_fresh_id*/ {{22, 206}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1219,6 +1295,9 @@ TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnValue) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 9, @@ -1232,8 +1311,9 @@ TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnValue) { /*input_id_to_fresh_id*/ {{31, 206}}, /*output_id_to_fresh_id*/ {{32, 207}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1310,6 +1390,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 54, @@ -1323,8 +1406,9 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {{}}, /*output_id_to_fresh_id*/ {{6, 206}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1396,6 +1480,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 54, @@ -1409,8 +1496,9 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1478,6 +1566,9 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatStartsWithOpPhi) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 21, @@ -1491,7 +1582,8 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatStartsWithOpPhi) { /*input_id_to_fresh_id*/ {{22, 207}}, /*output_id_to_fresh_id*/ {{23, 208}}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1531,6 +1623,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 21, @@ -1544,7 +1639,8 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {}, /*output_id_to_fresh_id*/ {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1584,6 +1680,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 5, @@ -1597,7 +1696,8 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {}, /*output_id_to_fresh_id*/ {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatUsesAccessChain) { @@ -1640,6 +1740,9 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatUsesAccessChain) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 13, @@ -1653,7 +1756,8 @@ TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatUsesAccessChain) { /*input_id_to_fresh_id*/ {{12, 207}}, /*output_id_to_fresh_id*/ {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1698,6 +1802,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 13, @@ -1711,7 +1818,8 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {{20, 207}}, /*output_id_to_fresh_id*/ {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, @@ -1761,6 +1869,9 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 11, @@ -1774,8 +1885,9 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {{9, 207}}, /*output_id_to_fresh_id*/ {{14, 208}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -1913,9 +2025,15 @@ TEST(TransformationOutlineFunctionTest, OutlineLivesafe) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFactFunctionIsLivesafe(30); - fact_manager.AddFactValueOfPointeeIsIrrelevant(200); - fact_manager.AddFactValueOfPointeeIsIrrelevant(201); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(30); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 200); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 201); TransformationOutlineFunction transformation( /*entry_block*/ 198, @@ -1929,24 +2047,31 @@ TEST(TransformationOutlineFunctionTest, OutlineLivesafe) { /*input_id_to_fresh_id*/ {{100, 407}, {200, 408}, {201, 409}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // The original function should still be livesafe. - ASSERT_TRUE(fact_manager.FunctionIsLivesafe(30)); + ASSERT_TRUE(transformation_context.GetFactManager()->FunctionIsLivesafe(30)); // The outlined function should be livesafe. - ASSERT_TRUE(fact_manager.FunctionIsLivesafe(402)); + ASSERT_TRUE(transformation_context.GetFactManager()->FunctionIsLivesafe(402)); // The variable and parameter that were originally irrelevant should still be. - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(200)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(201)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(200)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(201)); // The loop limiter should still be non-irrelevant. - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); // The parameters for the original irrelevant variables should be irrelevant. - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(408)); - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(409)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(408)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(409)); // The parameter for the loop limiter should not be irrelevant. - ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(407)); + ASSERT_FALSE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant(407)); std::string after_transformation = R"( OpCapability Shader @@ -2129,8 +2254,12 @@ TEST(TransformationOutlineFunctionTest, OutlineWithDeadBlocks1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + for (uint32_t block_id : {16u, 23u, 24u, 26u, 27u, 34u, 35u, 50u}) { - fact_manager.AddFactBlockIsDead(block_id); + transformation_context.GetFactManager()->AddFactBlockIsDead(block_id); } TransformationOutlineFunction transformation( @@ -2145,12 +2274,13 @@ TEST(TransformationOutlineFunctionTest, OutlineWithDeadBlocks1) { /*input_id_to_fresh_id*/ {{9, 206}, {12, 207}, {21, 208}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // All the original blocks, plus the new function entry block, should be dead. for (uint32_t block_id : {16u, 23u, 24u, 26u, 27u, 34u, 35u, 50u, 203u}) { - ASSERT_TRUE(fact_manager.BlockIsDead(block_id)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(block_id)); } } @@ -2208,8 +2338,12 @@ TEST(TransformationOutlineFunctionTest, OutlineWithDeadBlocks2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + for (uint32_t block_id : {32u, 34u, 35u}) { - fact_manager.AddFactBlockIsDead(block_id); + transformation_context.GetFactManager()->AddFactBlockIsDead(block_id); } TransformationOutlineFunction transformation( @@ -2224,15 +2358,17 @@ TEST(TransformationOutlineFunctionTest, OutlineWithDeadBlocks2) { /*input_id_to_fresh_id*/ {{11, 206}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // The blocks that were originally dead, but not others, should be dead. for (uint32_t block_id : {32u, 34u, 35u}) { - ASSERT_TRUE(fact_manager.BlockIsDead(block_id)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(block_id)); } for (uint32_t block_id : {5u, 30u, 31u, 33u, 36u, 37u, 203u}) { - ASSERT_FALSE(fact_manager.BlockIsDead(block_id)); + ASSERT_FALSE( + transformation_context.GetFactManager()->BlockIsDead(block_id)); } } @@ -2287,8 +2423,13 @@ TEST(TransformationOutlineFunctionTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - fact_manager.AddFactValueOfPointeeIsIrrelevant(9); - fact_manager.AddFactValueOfPointeeIsIrrelevant(14); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(9); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 14); TransformationOutlineFunction transformation( /*entry_block*/ 50, @@ -2302,16 +2443,20 @@ TEST(TransformationOutlineFunctionTest, /*input_id_to_fresh_id*/ {{9, 206}, {10, 207}, {14, 208}, {20, 209}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // The variables that were originally irrelevant, plus input parameters // corresponding to them, should be irrelevant. The rest should not be. for (uint32_t variable_id : {9u, 14u, 206u, 208u}) { - ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(variable_id)); + ASSERT_TRUE( + transformation_context.GetFactManager()->PointeeValueIsIrrelevant( + variable_id)); } for (uint32_t variable_id : {10u, 20u, 207u, 209u}) { - ASSERT_FALSE(fact_manager.BlockIsDead(variable_id)); + ASSERT_FALSE( + transformation_context.GetFactManager()->BlockIsDead(variable_id)); } } @@ -2423,6 +2568,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous1) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 150, @@ -2436,8 +2584,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous1) { /*input_id_to_fresh_id*/ {{102, 300}, {103, 301}, {40, 302}}, /*output_id_to_fresh_id*/ {{106, 400}, {107, 401}}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -2588,6 +2737,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous2) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 38, @@ -2601,7 +2753,8 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous2) { /*input_id_to_fresh_id*/ {}, /*output_id_to_fresh_id*/ {}); - ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationOutlineFunctionTest, Miscellaneous3) { @@ -2643,6 +2796,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous3) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 80, @@ -2656,8 +2812,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous3) { /*input_id_to_fresh_id*/ {}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( @@ -2732,6 +2889,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous4) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationOutlineFunction transformation( /*entry_block*/ 80, @@ -2745,8 +2905,9 @@ TEST(TransformationOutlineFunctionTest, Miscellaneous4) { /*input_id_to_fresh_id*/ {{104, 307}}, /*output_id_to_fresh_id*/ {}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_transformation = R"( diff --git a/test/fuzz/transformation_permute_function_parameters_test.cpp b/test/fuzz/transformation_permute_function_parameters_test.cpp index 1af4699c..a4a7c00b 100644 --- a/test/fuzz/transformation_permute_function_parameters_test.cpp +++ b/test/fuzz/transformation_permute_function_parameters_test.cpp @@ -200,52 +200,57 @@ TEST(TransformationPermuteFunctionParametersTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Can't permute main function ASSERT_FALSE(TransformationPermuteFunctionParameters(4, 0, {}).IsApplicable( - context.get(), fact_manager)); + context.get(), transformation_context)); // Can't permute invalid instruction ASSERT_FALSE(TransformationPermuteFunctionParameters(101, 0, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Permutation has too many values ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {2, 1, 0, 3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Permutation has too few values ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {0, 1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Permutation has invalid values ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {3, 1, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Type id is not an OpTypeFunction instruction ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 42, {2, 1, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Type id has incorrect number of operands ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 9, {2, 1, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OpTypeFunction has operands out of order ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 18, {2, 1, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Successful transformations { // Function has two operands of the same type: // initial OpTypeFunction should be enough TransformationPermuteFunctionParameters transformation(12, 9, {1, 0}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } { TransformationPermuteFunctionParameters transformation(28, 105, {1, 0}); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp index 527a7b7d..b320308f 100644 --- a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp +++ b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp @@ -163,6 +163,9 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); std::vector uses_of_true = { MakeIdUseDescriptor(41, MakeInstructionDescriptor(44, SpvOpStore, 12), 1), @@ -197,10 +200,10 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, #define CHECK_OPERATOR(USE_DESCRIPTOR, LHS_ID, RHS_ID, OPCODE, FRESH_ID) \ ASSERT_TRUE(TransformationReplaceBooleanConstantWithConstantBinary( \ USE_DESCRIPTOR, LHS_ID, RHS_ID, OPCODE, FRESH_ID) \ - .IsApplicable(context.get(), fact_manager)); \ + .IsApplicable(context.get(), transformation_context)); \ ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( \ USE_DESCRIPTOR, RHS_ID, LHS_ID, OPCODE, FRESH_ID) \ - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); #define CHECK_TRANSFORMATION_APPLICABILITY(GT_OPCODES, LT_OPCODES, SMALL_ID, \ LARGE_ID) \ @@ -252,27 +255,27 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // Target id is not fresh ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 15, 17, SpvOpFOrdLessThan, 15) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // LHS id does not exist ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 300, 17, SpvOpFOrdLessThan, 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // RHS id does not exist ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 15, 300, SpvOpFOrdLessThan, 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // LHS and RHS ids do not match type ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 11, 17, SpvOpFOrdLessThan, 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Opcode not appropriate ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 15, 17, SpvOpFDiv, 200) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto replace_true_with_double_comparison = TransformationReplaceBooleanConstantWithConstantBinary( @@ -287,21 +290,25 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, TransformationReplaceBooleanConstantWithConstantBinary( uses_of_false[1], 33, 31, SpvOpSLessThan, 103); - ASSERT_TRUE(replace_true_with_double_comparison.IsApplicable(context.get(), - fact_manager)); - replace_true_with_double_comparison.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replace_true_with_double_comparison.IsApplicable( + context.get(), transformation_context)); + replace_true_with_double_comparison.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(replace_true_with_uint32_comparison.IsApplicable(context.get(), - fact_manager)); - replace_true_with_uint32_comparison.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replace_true_with_uint32_comparison.IsApplicable( + context.get(), transformation_context)); + replace_true_with_uint32_comparison.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(replace_false_with_float_comparison.IsApplicable(context.get(), - fact_manager)); - replace_false_with_float_comparison.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replace_false_with_float_comparison.IsApplicable( + context.get(), transformation_context)); + replace_false_with_float_comparison.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(replace_false_with_sint64_comparison.IsApplicable(context.get(), - fact_manager)); - replace_false_with_sint64_comparison.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replace_false_with_sint64_comparison.IsApplicable( + context.get(), transformation_context)); + replace_false_with_sint64_comparison.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after = R"( @@ -419,7 +426,7 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // The transformation is not applicable because %200 is NaN. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 11, 200, SpvOpFOrdLessThan, 300) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } if (std::numeric_limits::has_infinity) { double positive_infinity_double = std::numeric_limits::infinity(); @@ -436,7 +443,7 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // transformation is restricted to only apply to finite values. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 11, 201, SpvOpFOrdLessThan, 300) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } if (std::numeric_limits::has_infinity) { float positive_infinity_float = std::numeric_limits::infinity(); @@ -461,7 +468,7 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // values. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( uses_of_true[0], 203, 202, SpvOpFOrdLessThan, 300) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } @@ -531,6 +538,9 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto use_of_true_in_if = MakeIdUseDescriptor( 13, MakeInstructionDescriptor(10, SpvOpBranchConditional, 0), 0); @@ -542,12 +552,14 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, auto replacement_2 = TransformationReplaceBooleanConstantWithConstantBinary( use_of_false_in_while, 9, 11, SpvOpSGreaterThanEqual, 101); - ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager)); - replacement_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_1.IsApplicable(context.get(), transformation_context)); + replacement_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager)); - replacement_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement_2.IsApplicable(context.get(), transformation_context)); + replacement_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after = R"( @@ -642,12 +654,15 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, OpPhi) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto replacement = TransformationReplaceBooleanConstantWithConstantBinary( MakeIdUseDescriptor(9, MakeInstructionDescriptor(23, SpvOpPhi, 0), 0), 13, 15, SpvOpSLessThan, 100); - ASSERT_FALSE(replacement.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(replacement.IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, @@ -681,12 +696,15 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( MakeIdUseDescriptor( 9, MakeInstructionDescriptor(50, SpvOpVariable, 0), 1), 13, 15, SpvOpSLessThan, 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp index 58d4a895..8cbba465 100644 --- a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp +++ b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp @@ -22,7 +22,8 @@ namespace fuzz { namespace { bool AddFactHelper( - FactManager* fact_manager, opt::IRContext* context, uint32_t word, + TransformationContext* transformation_context, opt::IRContext* context, + uint32_t word, const protobufs::UniformBufferElementDescriptor& descriptor) { protobufs::FactConstantUniform constant_uniform_fact; constant_uniform_fact.add_constant_word(word); @@ -30,7 +31,7 @@ bool AddFactHelper( descriptor; protobufs::Fact fact; *fact.mutable_constant_uniform_fact() = constant_uniform_fact; - return fact_manager->AddFact(fact, context); + return transformation_context->GetFactManager()->AddFact(fact, context); } TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { @@ -104,6 +105,10 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_a = MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_b = @@ -111,9 +116,12 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { protobufs::UniformBufferElementDescriptor blockname_c = MakeUniformBufferElementDescriptor(0, 0, {2}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_a)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_b)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, blockname_c)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 1, blockname_a)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 2, blockname_b)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 3, blockname_c)); // The constant ids are 9, 11 and 14, for 1, 2 and 3 respectively. protobufs::IdUseDescriptor use_of_9_in_store = @@ -127,30 +135,30 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { auto transformation_use_of_9_in_store = TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_a, 100, 101); - ASSERT_TRUE(transformation_use_of_9_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_9_in_store.IsApplicable( + context.get(), transformation_context)); auto transformation_use_of_11_in_add = TransformationReplaceConstantWithUniform(use_of_11_in_add, blockname_b, 102, 103); - ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable( + context.get(), transformation_context)); auto transformation_use_of_14_in_add = TransformationReplaceConstantWithUniform(use_of_14_in_add, blockname_c, 104, 105); - ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable( + context.get(), transformation_context)); // The transformations are not applicable if we change which uniforms are // applied to which constants. ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_b, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add, blockname_c, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_14_in_add, blockname_a, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The following transformations do not apply because the uniform descriptors // are not sensible. @@ -160,10 +168,10 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { MakeUniformBufferElementDescriptor(0, 0, {5}); ASSERT_FALSE(TransformationReplaceConstantWithUniform( use_of_9_in_store, nonsense_uniform_descriptor1, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationReplaceConstantWithUniform( use_of_9_in_store, nonsense_uniform_descriptor2, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The following transformation does not apply because the id descriptor is // not sensible. @@ -171,18 +179,19 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { MakeIdUseDescriptor(9, MakeInstructionDescriptor(15, SpvOpIAdd, 0), 0); ASSERT_FALSE(TransformationReplaceConstantWithUniform( nonsense_id_use_descriptor, blockname_a, 101, 102) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The following transformations do not apply because the ids are not fresh. ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add, blockname_b, 15, 103) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add, blockname_b, 102, 15) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Apply the use of 9 in a store. - transformation_use_of_9_in_store.Apply(context.get(), &fact_manager); + transformation_use_of_9_in_store.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_replacing_use_of_9_in_store = R"( OpCapability Shader @@ -233,10 +242,10 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { )"; ASSERT_TRUE(IsEqual(env, after_replacing_use_of_9_in_store, context.get())); - ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable( + context.get(), transformation_context)); // Apply the use of 11 in an add. - transformation_use_of_11_in_add.Apply(context.get(), &fact_manager); + transformation_use_of_11_in_add.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_replacing_use_of_11_in_add = R"( OpCapability Shader @@ -289,10 +298,10 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { )"; ASSERT_TRUE(IsEqual(env, after_replacing_use_of_11_in_add, context.get())); - ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable( + context.get(), transformation_context)); // Apply the use of 15 in an add. - transformation_use_of_14_in_add.Apply(context.get(), &fact_manager); + transformation_use_of_14_in_add.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_replacing_use_of_14_in_add = R"( OpCapability Shader @@ -462,6 +471,10 @@ TEST(TransformationReplaceConstantWithUniformTest, NestedStruct) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_1 = MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_2 = @@ -471,10 +484,14 @@ TEST(TransformationReplaceConstantWithUniformTest, NestedStruct) { protobufs::UniformBufferElementDescriptor blockname_4 = MakeUniformBufferElementDescriptor(0, 0, {1, 0, 1, 0}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_1)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_2)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, blockname_3)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 4, blockname_4)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 1, blockname_1)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 2, blockname_2)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 3, blockname_3)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 4, blockname_4)); // The constant ids are 13, 15, 17 and 20, for 1, 2, 3 and 4 respectively. protobufs::IdUseDescriptor use_of_13_in_store = @@ -490,76 +507,78 @@ TEST(TransformationReplaceConstantWithUniformTest, NestedStruct) { auto transformation_use_of_13_in_store = TransformationReplaceConstantWithUniform(use_of_13_in_store, blockname_1, 100, 101); - ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); auto transformation_use_of_15_in_add = TransformationReplaceConstantWithUniform(use_of_15_in_add, blockname_2, 102, 103); - ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); auto transformation_use_of_17_in_add = TransformationReplaceConstantWithUniform(use_of_17_in_add, blockname_3, 104, 105); - ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); auto transformation_use_of_20_in_store = TransformationReplaceConstantWithUniform(use_of_20_in_store, blockname_4, 106, 107); - ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); - ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); - transformation_use_of_13_in_store.Apply(context.get(), &fact_manager); + transformation_use_of_13_in_store.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); - transformation_use_of_15_in_add.Apply(context.get(), &fact_manager); + transformation_use_of_15_in_add.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); - transformation_use_of_17_in_add.Apply(context.get(), &fact_manager); + transformation_use_of_17_in_add.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); - transformation_use_of_20_in_store.Apply(context.get(), &fact_manager); + transformation_use_of_20_in_store.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(context.get(), - fact_manager)); - ASSERT_FALSE(transformation_use_of_20_in_store.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable( + context.get(), transformation_context)); + ASSERT_FALSE(transformation_use_of_20_in_store.IsApplicable( + context.get(), transformation_context)); std::string after = R"( OpCapability Shader @@ -697,10 +716,15 @@ TEST(TransformationReplaceConstantWithUniformTest, NoUniformIntPointerPresent) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_0 = MakeUniformBufferElementDescriptor(0, 0, {0}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 0, blockname_0)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 0, blockname_0)); // The constant id is 9 for 0. protobufs::IdUseDescriptor use_of_9_in_store = @@ -710,7 +734,7 @@ TEST(TransformationReplaceConstantWithUniformTest, NoUniformIntPointerPresent) { // type is present: ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_0, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) { @@ -770,12 +794,17 @@ TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_0 = MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_9 = MakeUniformBufferElementDescriptor(0, 0, {1}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 9, blockname_9)); // The constant id is 9 for 9. protobufs::IdUseDescriptor use_of_9_in_store = @@ -785,7 +814,7 @@ TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) { // index 1 required to index into the uniform buffer: ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_9, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceConstantWithUniformTest, @@ -842,14 +871,18 @@ TEST(TransformationReplaceConstantWithUniformTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_3 = MakeUniformBufferElementDescriptor(0, 0, {0}); uint32_t float_data[1]; float temp = 3.0; memcpy(&float_data[0], &temp, sizeof(float)); - ASSERT_TRUE( - AddFactHelper(&fact_manager, context.get(), float_data[0], blockname_3)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_data[0], blockname_3)); // The constant id is 9 for 3.0. protobufs::IdUseDescriptor use_of_9_in_store = @@ -859,7 +892,7 @@ TEST(TransformationReplaceConstantWithUniformTest, // allow a constant index to be expressed: ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_3, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceConstantWithUniformTest, @@ -928,13 +961,19 @@ TEST(TransformationReplaceConstantWithUniformTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_9 = MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_10 = MakeUniformBufferElementDescriptor(0, 0, {1}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 10, blockname_10)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 9, blockname_9)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 10, blockname_10)); // The constant ids for 9 and 10 are 9 and 11 respectively protobufs::IdUseDescriptor use_of_9_in_store = @@ -945,19 +984,19 @@ TEST(TransformationReplaceConstantWithUniformTest, // These are right: ASSERT_TRUE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_9, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationReplaceConstantWithUniform(use_of_11_in_store, blockname_10, 102, 103) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // These are wrong because the constants do not match the facts about // uniforms. ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_store, blockname_9, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_10, 102, 103) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { @@ -1141,6 +1180,9 @@ TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); const float float_array_values[5] = {1.0, 1.5, 1.75, 1.875, 1.9375}; uint32_t float_array_data[5]; @@ -1188,35 +1230,43 @@ TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { protobufs::UniformBufferElementDescriptor uniform_h_y = MakeUniformBufferElementDescriptor(0, 0, {2, 1}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[0], - uniform_f_a_0)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[1], - uniform_f_a_1)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[2], - uniform_f_a_2)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[3], - uniform_f_a_3)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[4], - uniform_f_a_4)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_array_data[0], uniform_f_a_0)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_array_data[1], uniform_f_a_1)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_array_data[2], uniform_f_a_2)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_array_data[3], uniform_f_a_3)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_array_data[4], uniform_f_a_4)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, uniform_f_b_x)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, uniform_f_b_y)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, uniform_f_b_z)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 4, uniform_f_b_w)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 1, uniform_f_b_x)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 2, uniform_f_b_y)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 3, uniform_f_b_z)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 4, uniform_f_b_w)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[0], - uniform_f_c_x)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[1], - uniform_f_c_y)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[2], - uniform_f_c_z)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_vector_data[0], uniform_f_c_x)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_vector_data[1], uniform_f_c_y)); + ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(), + float_vector_data[2], uniform_f_c_z)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 42, uniform_f_d)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 42, uniform_f_d)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 22, uniform_g)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 22, uniform_g)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 100, uniform_h_x)); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 200, uniform_h_y)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 100, uniform_h_x)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 200, uniform_h_y)); std::vector transformations; @@ -1275,8 +1325,9 @@ TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { uniform_g, 218, 219)); for (auto& transformation : transformations) { - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -1480,16 +1531,21 @@ TEST(TransformationReplaceConstantWithUniformTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + protobufs::UniformBufferElementDescriptor blockname_a = MakeUniformBufferElementDescriptor(0, 0, {0}); - ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 0, blockname_a)); + ASSERT_TRUE( + AddFactHelper(&transformation_context, context.get(), 0, blockname_a)); ASSERT_FALSE(TransformationReplaceConstantWithUniform( MakeIdUseDescriptor( 50, MakeInstructionDescriptor(8, SpvOpVariable, 0), 1), blockname_a, 100, 101) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/test/fuzz/transformation_replace_id_with_synonym_test.cpp index 41b61166..d563afa7 100644 --- a/test/fuzz/transformation_replace_id_with_synonym_test.cpp +++ b/test/fuzz/transformation_replace_id_with_synonym_test.cpp @@ -220,15 +220,19 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - SetUpIdSynonyms(&fact_manager, context.get()); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + SetUpIdSynonyms(transformation_context.GetFactManager(), context.get()); // %202 cannot replace %15 as in-operand 0 of %300, since %202 does not // dominate %300. auto synonym_does_not_dominate_use = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(15, MakeInstructionDescriptor(300, SpvOpIAdd, 0), 0), 202); - ASSERT_FALSE( - synonym_does_not_dominate_use.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(synonym_does_not_dominate_use.IsApplicable( + context.get(), transformation_context)); // %202 cannot replace %15 as in-operand 2 of %301, since this is the OpPhi's // incoming value for block %72, and %202 does not dominate %72. @@ -237,22 +241,23 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { MakeIdUseDescriptor(15, MakeInstructionDescriptor(301, SpvOpPhi, 0), 2), 202); - ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable( + context.get(), transformation_context)); // %200 is not a synonym for %84 auto id_in_use_is_not_synonymous = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( 84, MakeInstructionDescriptor(67, SpvOpSGreaterThan, 0), 0), 200); - ASSERT_FALSE( - id_in_use_is_not_synonymous.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(id_in_use_is_not_synonymous.IsApplicable( + context.get(), transformation_context)); // %86 is not a synonym for anything (and in particular not for %74) auto id_has_no_synonyms = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(86, MakeInstructionDescriptor(84, SpvOpPhi, 0), 2), 74); - ASSERT_FALSE(id_has_no_synonyms.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + id_has_no_synonyms.IsApplicable(context.get(), transformation_context)); // This would lead to %207 = 'OpCopyObject %type %207' if it were allowed auto synonym_use_is_in_synonym_definition = @@ -260,8 +265,8 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { MakeIdUseDescriptor( 84, MakeInstructionDescriptor(207, SpvOpCopyObject, 0), 0), 207); - ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable(context.get(), - fact_manager)); + ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable( + context.get(), transformation_context)); // The id use descriptor does not lead to a use (%84 is not used in the // definition of %207) @@ -269,7 +274,8 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { MakeIdUseDescriptor( 84, MakeInstructionDescriptor(200, SpvOpCopyObject, 0), 0), 207); - ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(), + transformation_context)); // This replacement would lead to an access chain into a struct using a // non-constant index. @@ -277,7 +283,8 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { MakeIdUseDescriptor( 12, MakeInstructionDescriptor(14, SpvOpAccessChain, 0), 1), 209); - ASSERT_FALSE(bad_access_chain.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + bad_access_chain.IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { @@ -288,23 +295,28 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - SetUpIdSynonyms(&fact_manager, context.get()); + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); + + SetUpIdSynonyms(transformation_context.GetFactManager(), context.get()); auto global_constant_synonym = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(19, MakeInstructionDescriptor(47, SpvOpStore, 0), 1), 210); - ASSERT_TRUE( - global_constant_synonym.IsApplicable(context.get(), fact_manager)); - global_constant_synonym.Apply(context.get(), &fact_manager); + ASSERT_TRUE(global_constant_synonym.IsApplicable(context.get(), + transformation_context)); + global_constant_synonym.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto replace_vector_access_chain_index = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( 54, MakeInstructionDescriptor(55, SpvOpAccessChain, 0), 1), 204); - ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable(context.get(), - fact_manager)); - replace_vector_access_chain_index.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable( + context.get(), transformation_context)); + replace_vector_access_chain_index.Apply(context.get(), + &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // This is an interesting case because it replaces something that is being @@ -313,22 +325,24 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { MakeIdUseDescriptor( 15, MakeInstructionDescriptor(202, SpvOpCopyObject, 0), 0), 201); - ASSERT_TRUE(regular_replacement.IsApplicable(context.get(), fact_manager)); - regular_replacement.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + regular_replacement.IsApplicable(context.get(), transformation_context)); + regular_replacement.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto regular_replacement2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(55, MakeInstructionDescriptor(203, SpvOpStore, 0), 0), 203); - ASSERT_TRUE(regular_replacement2.IsApplicable(context.get(), fact_manager)); - regular_replacement2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + regular_replacement2.IsApplicable(context.get(), transformation_context)); + regular_replacement2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); auto good_op_phi = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(74, MakeInstructionDescriptor(86, SpvOpPhi, 0), 2), 205); - ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), fact_manager)); - good_op_phi.Apply(context.get(), &fact_manager); + ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), transformation_context)); + good_op_phi.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( @@ -504,17 +518,22 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFact(MakeSynonymFact(10, 100), context.get()); - fact_manager.AddFact(MakeSynonymFact(8, 101), context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(10, 100), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 101), + context.get()); // Replace %10 with %100 in: // %11 = OpLoad %6 %10 auto replacement1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(10, MakeInstructionDescriptor(11, SpvOpLoad, 0), 0), 100); - ASSERT_TRUE(replacement1.IsApplicable(context.get(), fact_manager)); - replacement1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context)); + replacement1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %8 with %101 in: @@ -522,8 +541,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { auto replacement2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(8, MakeInstructionDescriptor(11, SpvOpStore, 0), 0), 101); - ASSERT_TRUE(replacement2.IsApplicable(context.get(), fact_manager)); - replacement2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context)); + replacement2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %8 with %101 in: @@ -531,8 +550,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { auto replacement3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(8, MakeInstructionDescriptor(12, SpvOpLoad, 0), 0), 101); - ASSERT_TRUE(replacement3.IsApplicable(context.get(), fact_manager)); - replacement3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement3.IsApplicable(context.get(), transformation_context)); + replacement3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replace %10 with %100 in: @@ -540,8 +559,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { auto replacement4 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor(10, MakeInstructionDescriptor(12, SpvOpStore, 0), 0), 100); - ASSERT_TRUE(replacement4.IsApplicable(context.get(), fact_manager)); - replacement4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context)); + replacement4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( @@ -633,8 +652,12 @@ TEST(TransformationReplaceIdWithSynonymTest, ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFact(MakeSynonymFact(14, 100), context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(14, 100), + context.get()); // Replace %14 with %100 in: // %16 = OpFunctionCall %2 %10 %14 @@ -642,7 +665,7 @@ TEST(TransformationReplaceIdWithSynonymTest, MakeIdUseDescriptor( 14, MakeInstructionDescriptor(16, SpvOpFunctionCall, 0), 1), 100); - ASSERT_FALSE(replacement.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE(replacement.IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { @@ -795,22 +818,38 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Add synonym facts corresponding to the OpCopyObject operations that have // been applied to all constants in the module. - fact_manager.AddFact(MakeSynonymFact(16, 100), context.get()); - fact_manager.AddFact(MakeSynonymFact(21, 101), context.get()); - fact_manager.AddFact(MakeSynonymFact(17, 102), context.get()); - fact_manager.AddFact(MakeSynonymFact(57, 103), context.get()); - fact_manager.AddFact(MakeSynonymFact(18, 104), context.get()); - fact_manager.AddFact(MakeSynonymFact(40, 105), context.get()); - fact_manager.AddFact(MakeSynonymFact(32, 106), context.get()); - fact_manager.AddFact(MakeSynonymFact(43, 107), context.get()); - fact_manager.AddFact(MakeSynonymFact(55, 108), context.get()); - fact_manager.AddFact(MakeSynonymFact(8, 109), context.get()); - fact_manager.AddFact(MakeSynonymFact(47, 110), context.get()); - fact_manager.AddFact(MakeSynonymFact(28, 111), context.get()); - fact_manager.AddFact(MakeSynonymFact(45, 112), context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(16, 100), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(21, 101), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(17, 102), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(57, 103), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(18, 104), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(40, 105), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(32, 106), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(43, 107), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(55, 108), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 109), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(47, 110), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(28, 111), + context.get()); + transformation_context.GetFactManager()->AddFact(MakeSynonymFact(45, 112), + context.get()); // Replacements of the form %16 -> %100 @@ -821,7 +860,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 1), 100); - ASSERT_FALSE(replacement1.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement1.IsApplicable(context.get(), transformation_context)); // %39 = OpAccessChain %23 %37 *%16* // Corresponds to h.*f* @@ -830,7 +870,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(39, SpvOpAccessChain, 0), 1), 100); - ASSERT_FALSE(replacement2.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement2.IsApplicable(context.get(), transformation_context)); // %41 = OpAccessChain %19 %37 %21 *%16* %21 // Corresponds to h.g.*a*[1] @@ -839,7 +880,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 2), 100); - ASSERT_FALSE(replacement3.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement3.IsApplicable(context.get(), transformation_context)); // %52 = OpAccessChain %23 %50 *%16* %16 // Corresponds to i[*0*].f @@ -848,8 +890,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 1), 100); - ASSERT_TRUE(replacement4.IsApplicable(context.get(), fact_manager)); - replacement4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context)); + replacement4.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // %52 = OpAccessChain %23 %50 %16 *%16* @@ -859,7 +901,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 2), 100); - ASSERT_FALSE(replacement5.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement5.IsApplicable(context.get(), transformation_context)); // %53 = OpAccessChain %19 %50 %21 %21 *%16* %16 // Corresponds to i[1].g.*a*[0] @@ -868,7 +911,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 3), 100); - ASSERT_FALSE(replacement6.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement6.IsApplicable(context.get(), transformation_context)); // %53 = OpAccessChain %19 %50 %21 %21 %16 *%16* // Corresponds to i[1].g.a[*0*] @@ -877,8 +921,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 4), 100); - ASSERT_TRUE(replacement7.IsApplicable(context.get(), fact_manager)); - replacement7.Apply(context.get(), &fact_manager); + ASSERT_TRUE(replacement7.IsApplicable(context.get(), transformation_context)); + replacement7.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replacements of the form %21 -> %101 @@ -890,7 +934,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 1), 101); - ASSERT_FALSE(replacement8.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement8.IsApplicable(context.get(), transformation_context)); // %41 = OpAccessChain %19 %37 *%21* %16 %21 // Corresponds to h.*g*.a[1] @@ -899,7 +944,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 1), 101); - ASSERT_FALSE(replacement9.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement9.IsApplicable(context.get(), transformation_context)); // %41 = OpAccessChain %19 %37 %21 %16 *%21* // Corresponds to h.g.a[*1*] @@ -908,8 +954,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 3), 101); - ASSERT_TRUE(replacement10.IsApplicable(context.get(), fact_manager)); - replacement10.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement10.IsApplicable(context.get(), transformation_context)); + replacement10.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // %44 = OpAccessChain %23 %37 *%21* %21 %43 @@ -919,7 +966,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 1), 101); - ASSERT_FALSE(replacement11.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement11.IsApplicable(context.get(), transformation_context)); // %44 = OpAccessChain %23 %37 %21 *%21* %43 // Corresponds to h.g.*b*[0] @@ -928,7 +976,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 2), 101); - ASSERT_FALSE(replacement12.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement12.IsApplicable(context.get(), transformation_context)); // %46 = OpAccessChain %26 %37 *%21* %17 // Corresponds to h.*g*.c @@ -937,7 +986,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 1), 101); - ASSERT_FALSE(replacement13.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement13.IsApplicable(context.get(), transformation_context)); // %53 = OpAccessChain %19 %50 *%21* %21 %16 %16 // Corresponds to i[*1*].g.a[0] @@ -946,8 +996,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 1), 101); - ASSERT_TRUE(replacement14.IsApplicable(context.get(), fact_manager)); - replacement14.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement14.IsApplicable(context.get(), transformation_context)); + replacement14.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // %53 = OpAccessChain %19 %50 %21 *%21* %16 %16 @@ -957,7 +1008,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 2), 101); - ASSERT_FALSE(replacement15.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement15.IsApplicable(context.get(), transformation_context)); // %56 = OpAccessChain %23 %50 %17 *%21* %21 %55 // Corresponds to i[2].*g*.b[1] @@ -966,7 +1018,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 2), 101); - ASSERT_FALSE(replacement16.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement16.IsApplicable(context.get(), transformation_context)); // %56 = OpAccessChain %23 %50 %17 %21 *%21* %55 // Corresponds to i[2].g.*b*[1] @@ -975,7 +1028,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 3), 101); - ASSERT_FALSE(replacement17.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement17.IsApplicable(context.get(), transformation_context)); // %58 = OpAccessChain %26 %50 %57 *%21* %17 // Corresponds to i[3].*g*.c @@ -984,7 +1038,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 21, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 2), 101); - ASSERT_FALSE(replacement18.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement18.IsApplicable(context.get(), transformation_context)); // Replacements of the form %17 -> %102 @@ -995,8 +1050,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 17, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 2), 102); - ASSERT_TRUE(replacement19.IsApplicable(context.get(), fact_manager)); - replacement19.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement19.IsApplicable(context.get(), transformation_context)); + replacement19.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // %27 = OpAccessChain %26 %15 %17 @@ -1006,7 +1062,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 17, MakeInstructionDescriptor(27, SpvOpAccessChain, 0), 1), 102); - ASSERT_FALSE(replacement20.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement20.IsApplicable(context.get(), transformation_context)); // %46 = OpAccessChain %26 %37 %21 %17 // Corresponds to h.g.*c* @@ -1015,7 +1072,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 17, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 2), 102); - ASSERT_FALSE(replacement21.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement21.IsApplicable(context.get(), transformation_context)); // %56 = OpAccessChain %23 %50 %17 %21 %21 %55 // Corresponds to i[*2*].g.b[1] @@ -1024,8 +1082,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 17, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 1), 102); - ASSERT_TRUE(replacement22.IsApplicable(context.get(), fact_manager)); - replacement22.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement22.IsApplicable(context.get(), transformation_context)); + replacement22.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // %58 = OpAccessChain %26 %50 %57 %21 %17 @@ -1035,7 +1094,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 17, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 3), 102); - ASSERT_FALSE(replacement23.IsApplicable(context.get(), fact_manager)); + ASSERT_FALSE( + replacement23.IsApplicable(context.get(), transformation_context)); // Replacements of the form %57 -> %103 @@ -1046,8 +1106,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 57, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 1), 103); - ASSERT_TRUE(replacement24.IsApplicable(context.get(), fact_manager)); - replacement24.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement24.IsApplicable(context.get(), transformation_context)); + replacement24.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replacements of the form %32 -> %106 @@ -1059,8 +1120,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 32, MakeInstructionDescriptor(34, SpvOpAccessChain, 0), 1), 106); - ASSERT_TRUE(replacement25.IsApplicable(context.get(), fact_manager)); - replacement25.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement25.IsApplicable(context.get(), transformation_context)); + replacement25.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replacements of the form %43 -> %107 @@ -1072,8 +1134,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 43, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 3), 107); - ASSERT_TRUE(replacement26.IsApplicable(context.get(), fact_manager)); - replacement26.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement26.IsApplicable(context.get(), transformation_context)); + replacement26.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replacements of the form %55 -> %108 @@ -1085,8 +1148,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor( 55, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 4), 108); - ASSERT_TRUE(replacement27.IsApplicable(context.get(), fact_manager)); - replacement27.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement27.IsApplicable(context.get(), transformation_context)); + replacement27.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); // Replacements of the form %8 -> %109 @@ -1098,8 +1162,9 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { MakeIdUseDescriptor(8, MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 2), 109); - ASSERT_TRUE(replacement28.IsApplicable(context.get(), fact_manager)); - replacement28.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + replacement28.IsApplicable(context.get(), transformation_context)); + replacement28.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); const std::string after_transformation = R"( diff --git a/test/fuzz/transformation_set_function_control_test.cpp b/test/fuzz/transformation_set_function_control_test.cpp index 536e965e..be7f2be4 100644 --- a/test/fuzz/transformation_set_function_control_test.cpp +++ b/test/fuzz/transformation_set_function_control_test.cpp @@ -118,41 +118,48 @@ TEST(TransformationSetFunctionControlTest, VariousScenarios) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // %36 is not a function ASSERT_FALSE(TransformationSetFunctionControl(36, SpvFunctionControlMaskNone) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot add the Pure function control to %4 as it did not already have it ASSERT_FALSE(TransformationSetFunctionControl(4, SpvFunctionControlPureMask) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot add the Const function control to %21 as it did not already // have it ASSERT_FALSE(TransformationSetFunctionControl(21, SpvFunctionControlConstMask) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Set to None, removing Const TransformationSetFunctionControl transformation1(11, SpvFunctionControlMaskNone); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); // Set to Inline; silly to do it on an entry point, but it is allowed TransformationSetFunctionControl transformation2( 4, SpvFunctionControlInlineMask); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); // Set to Pure, removing DontInline TransformationSetFunctionControl transformation3(17, SpvFunctionControlPureMask); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); // Change from Inline to DontInline TransformationSetFunctionControl transformation4( 13, SpvFunctionControlDontInlineMask); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_set_loop_control_test.cpp b/test/fuzz/transformation_set_loop_control_test.cpp index 83953ec0..531aa7ad 100644 --- a/test/fuzz/transformation_set_loop_control_test.cpp +++ b/test/fuzz/transformation_set_loop_control_test.cpp @@ -256,6 +256,9 @@ TEST(TransformationSetLoopControlTest, VariousScenarios) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // These are the loop headers together with the selection controls of their // merge instructions: @@ -275,310 +278,310 @@ TEST(TransformationSetLoopControlTest, VariousScenarios) { // 2 5 90 4 7 14 ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(10, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 10, SpvLoopControlDependencyInfiniteMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(10, SpvLoopControlDependencyLengthMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(10, SpvLoopControlMinIterationsMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(10, SpvLoopControlMaxIterationsMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 10, SpvLoopControlIterationMultipleMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 0, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 10, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl(10, SpvLoopControlDontUnrollMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 23, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(23, SpvLoopControlMaxIterationsMask, 2, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(33, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(33, SpvLoopControlMinIterationsMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 33, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl(33, SpvLoopControlDontUnrollMask | SpvLoopControlPartialCountMask, 0, 10) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(43, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 43, SpvLoopControlMaskNone | SpvLoopControlDependencyInfiniteMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 43, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 43, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(43, SpvLoopControlDependencyInfiniteMask | SpvLoopControlDependencyLengthMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 43, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(53, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(53, SpvLoopControlMaxIterationsMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 53, SpvLoopControlMaskNone | SpvLoopControlDependencyLengthMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl( 53, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 53, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyLengthMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(53, SpvLoopControlDependencyInfiniteMask | SpvLoopControlDependencyLengthMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 53, SpvLoopControlUnrollMask | SpvLoopControlDependencyLengthMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 5, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(63, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 5, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask, 23, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 63, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask, 2, 23) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(73, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 73, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 5, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPeelCountMask, 23, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 73, SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPeelCountMask, 2, 23) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 83, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 5, 3) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(83, SpvLoopControlUnrollMask | SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 23, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(83, SpvLoopControlUnrollMask | SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 2, 23) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(93, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 8) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(93, SpvLoopControlPartialCountMask, 0, 8) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 93, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, 8) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(103, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl(103, SpvLoopControlDontUnrollMask | SpvLoopControlPartialCountMask, 0, 60) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(113, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl( 113, SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 12, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlMaskNone, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl(123, SpvLoopControlDontUnrollMask, 0, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( TransformationSetLoopControl( 123, @@ -586,72 +589,72 @@ TEST(TransformationSetLoopControlTest, VariousScenarios) { SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 7, 8) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, 0, 9) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 123, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, 7, 9) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSetLoopControl( 123, SpvLoopControlDontUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, 7, 9) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationSetLoopControl(10, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl( 43, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask, 0, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(63, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlPeelCountMask, 23, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(73, SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPeelCountMask, 23, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl( 93, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, 8) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); TransformationSetLoopControl( 123, SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, 0, 9) - .Apply(context.get(), &fact_manager); + .Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader @@ -942,25 +945,28 @@ TEST(TransformationSetLoopControlTest, CheckSPIRVVersionsRespected) { BuildModule(SPV_ENV_UNIVERSAL_1_5, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationSetLoopControl set_peel_and_partial( 10, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 4, 4); // PeelCount and PartialCount were introduced in SPIRV 1.4, so are not valid // in the context of older versions. - ASSERT_FALSE( - set_peel_and_partial.IsApplicable(context_1_0.get(), fact_manager)); - ASSERT_FALSE( - set_peel_and_partial.IsApplicable(context_1_1.get(), fact_manager)); - ASSERT_FALSE( - set_peel_and_partial.IsApplicable(context_1_2.get(), fact_manager)); - ASSERT_FALSE( - set_peel_and_partial.IsApplicable(context_1_3.get(), fact_manager)); + ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_0.get(), + transformation_context)); + ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_1.get(), + transformation_context)); + ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_2.get(), + transformation_context)); + ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_3.get(), + transformation_context)); - ASSERT_TRUE( - set_peel_and_partial.IsApplicable(context_1_4.get(), fact_manager)); - ASSERT_TRUE( - set_peel_and_partial.IsApplicable(context_1_5.get(), fact_manager)); + ASSERT_TRUE(set_peel_and_partial.IsApplicable(context_1_4.get(), + transformation_context)); + ASSERT_TRUE(set_peel_and_partial.IsApplicable(context_1_5.get(), + transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_set_memory_operands_mask_test.cpp b/test/fuzz/transformation_set_memory_operands_mask_test.cpp index ad4dc256..c02d8d40 100644 --- a/test/fuzz/transformation_set_memory_operands_mask_test.cpp +++ b/test/fuzz/transformation_set_memory_operands_mask_test.cpp @@ -92,37 +92,41 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Not OK: the instruction is not a memory access. ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpAccessChain, 0), SpvMemoryAccessMaskNone, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to remove Aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(147, SpvOpLoad, 0), SpvMemoryAccessVolatileMask | SpvMemoryAccessNontemporalMask, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationSetMemoryOperandsMask transformation1( MakeInstructionDescriptor(147, SpvOpLoad, 0), SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); // Not OK to remove Aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), SpvMemoryAccessMaskNone, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK: leaves the mask as is ASSERT_TRUE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), SpvMemoryAccessAlignedMask, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK: adds Nontemporal and Volatile TransformationSetMemoryOperandsMask transformation2( @@ -130,41 +134,45 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); // Not OK to remove Volatile ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), SpvMemoryAccessNontemporalMask, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Not OK to add Aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK: adds Nontemporal TransformationSetMemoryOperandsMask transformation3( MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); // OK: adds Nontemporal and Volatile TransformationSetMemoryOperandsMask transformation4( MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); // OK: removes Nontemporal, adds Volatile TransformationSetMemoryOperandsMask transformation5( MakeInstructionDescriptor(148, SpvOpStore, 0), SpvMemoryAccessVolatileMask, 0); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader @@ -306,6 +314,9 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); TransformationSetMemoryOperandsMask transformation1( MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), @@ -314,9 +325,10 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14) { ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), SpvMemoryAccessVolatileMask, 1) - .IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); TransformationSetMemoryOperandsMask transformation2( MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), @@ -325,9 +337,10 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14) { ASSERT_FALSE(TransformationSetMemoryOperandsMask( MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), SpvMemoryAccessNontemporalMask, 0) - .IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); TransformationSetMemoryOperandsMask transformation3( MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), @@ -337,27 +350,31 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14) { MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask, 0) - .IsApplicable(context.get(), fact_manager)); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); TransformationSetMemoryOperandsMask transformation4( MakeInstructionDescriptor(138, SpvOpCopyMemory, 1), SpvMemoryAccessVolatileMask, 1); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); TransformationSetMemoryOperandsMask transformation5( MakeInstructionDescriptor(147, SpvOpLoad, 0), SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask, 0); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); TransformationSetMemoryOperandsMask transformation6( MakeInstructionDescriptor(148, SpvOpStore, 0), SpvMemoryAccessMaskNone, 0); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_set_selection_control_test.cpp b/test/fuzz/transformation_set_selection_control_test.cpp index 9696417b..9afb89d6 100644 --- a/test/fuzz/transformation_set_selection_control_test.cpp +++ b/test/fuzz/transformation_set_selection_control_test.cpp @@ -103,39 +103,46 @@ TEST(TransformationSetSelectionControlTest, VariousScenarios) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // %44 is not a block ASSERT_FALSE( TransformationSetSelectionControl(44, SpvSelectionControlFlattenMask) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %13 does not end with OpSelectionMerge ASSERT_FALSE( TransformationSetSelectionControl(13, SpvSelectionControlMaskNone) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // %10 ends in OpLoopMerge, not OpSelectionMerge ASSERT_FALSE( TransformationSetSelectionControl(10, SpvSelectionControlMaskNone) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); TransformationSetSelectionControl transformation1( 11, SpvSelectionControlDontFlattenMask); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); TransformationSetSelectionControl transformation2( 23, SpvSelectionControlFlattenMask); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); TransformationSetSelectionControl transformation3( 31, SpvSelectionControlMaskNone); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); TransformationSetSelectionControl transformation4( 31, SpvSelectionControlFlattenMask); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader diff --git a/test/fuzz/transformation_split_block_test.cpp b/test/fuzz/transformation_split_block_test.cpp index 09007a5b..8e9e8a4f 100644 --- a/test/fuzz/transformation_split_block_test.cpp +++ b/test/fuzz/transformation_split_block_test.cpp @@ -89,57 +89,60 @@ TEST(TransformationSplitBlockTest, NotApplicable) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // No split before OpVariable ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(8, SpvOpVariable, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(8, SpvOpVariable, 1), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split before OpLabel ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(14, SpvOpLabel, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split if base instruction is outside a function ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(1, SpvOpLabel, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(1, SpvOpExecutionMode, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split if block is loop header ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split if base instruction does not exist ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(88, SpvOpIAdd, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(88, SpvOpIMul, 22), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split if too many instructions with the desired opcode are skipped ASSERT_FALSE( TransformationSplitBlock( MakeInstructionDescriptor(18, SpvOpBranchConditional, 1), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // No split if id in use ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 27) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 14) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { @@ -199,11 +202,14 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto split_1 = TransformationSplitBlock( MakeInstructionDescriptor(5, SpvOpStore, 0), 100); - ASSERT_TRUE(split_1.IsApplicable(context.get(), fact_manager)); - split_1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split_1.IsApplicable(context.get(), transformation_context)); + split_1.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split_1 = R"( @@ -250,8 +256,8 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { auto split_2 = TransformationSplitBlock( MakeInstructionDescriptor(11, SpvOpStore, 0), 101); - ASSERT_TRUE(split_2.IsApplicable(context.get(), fact_manager)); - split_2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split_2.IsApplicable(context.get(), transformation_context)); + split_2.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split_2 = R"( @@ -300,8 +306,8 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { auto split_3 = TransformationSplitBlock( MakeInstructionDescriptor(14, SpvOpLoad, 0), 102); - ASSERT_TRUE(split_3.IsApplicable(context.get(), fact_manager)); - split_3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split_3.IsApplicable(context.get(), transformation_context)); + split_3.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split_3 = R"( @@ -412,21 +418,24 @@ TEST(TransformationSplitBlockTest, SplitBlockBeforeSelectBranch) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Illegal to split between the merge and the conditional branch. ASSERT_FALSE( TransformationSplitBlock( MakeInstructionDescriptor(14, SpvOpBranchConditional, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSplitBlock( MakeInstructionDescriptor(12, SpvOpBranchConditional, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto split = TransformationSplitBlock( MakeInstructionDescriptor(14, SpvOpSelectionMerge, 0), 100); - ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager)); - split.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); + split.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split = R"( @@ -541,19 +550,22 @@ TEST(TransformationSplitBlockTest, SplitBlockBeforeSwitchBranch) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Illegal to split between the merge and the conditional branch. ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(9, SpvOpSwitch, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( MakeInstructionDescriptor(15, SpvOpSwitch, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); auto split = TransformationSplitBlock( MakeInstructionDescriptor(9, SpvOpSelectionMerge, 0), 100); - ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager)); - split.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); + split.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split = R"( @@ -674,18 +686,21 @@ TEST(TransformationSplitBlockTest, NoSplitDuringOpPhis) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // We cannot split before OpPhi instructions, since the number of incoming // blocks may not appropriately match after splitting. ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(26, SpvOpPhi, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationSplitBlockTest, SplitOpPhiWithSinglePredecessor) { @@ -726,16 +741,19 @@ TEST(TransformationSplitBlockTest, SplitOpPhiWithSinglePredecessor) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); ASSERT_TRUE( TransformationSplitBlock(MakeInstructionDescriptor(21, SpvOpPhi, 0), 100) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // An equivalent transformation to the above, just described with respect to a // different base instruction. auto split = TransformationSplitBlock(MakeInstructionDescriptor(20, SpvOpPhi, 0), 100); - ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager)); - split.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); + split.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); std::string after_split = R"( @@ -805,18 +823,21 @@ TEST(TransformationSplitBlockTest, DeadBlockShouldSplitToTwoDeadBlocks) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Record the fact that block 8 is dead. - fact_manager.AddFactBlockIsDead(8); + transformation_context.GetFactManager()->AddFactBlockIsDead(8); auto split = TransformationSplitBlock( MakeInstructionDescriptor(8, SpvOpBranch, 0), 100); - ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager)); - split.Apply(context.get(), &fact_manager); + ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); + split.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); - ASSERT_TRUE(fact_manager.BlockIsDead(8)); - ASSERT_TRUE(fact_manager.BlockIsDead(100)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(8)); + ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100)); std::string after_split = R"( OpCapability Shader diff --git a/test/fuzz/transformation_store_test.cpp b/test/fuzz/transformation_store_test.cpp index 3fb9b615..067a5a11 100644 --- a/test/fuzz/transformation_store_test.cpp +++ b/test/fuzz/transformation_store_test.cpp @@ -94,16 +94,26 @@ TEST(TransformationStoreTest, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFactValueOfPointeeIsIrrelevant(27); - fact_manager.AddFactValueOfPointeeIsIrrelevant(11); - fact_manager.AddFactValueOfPointeeIsIrrelevant(46); - fact_manager.AddFactValueOfPointeeIsIrrelevant(16); - fact_manager.AddFactValueOfPointeeIsIrrelevant(52); - fact_manager.AddFactValueOfPointeeIsIrrelevant(81); - fact_manager.AddFactValueOfPointeeIsIrrelevant(82); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 27); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 11); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 46); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 16); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 52); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 81); + transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant( + 82); - fact_manager.AddFactBlockIsDead(36); + transformation_context.GetFactManager()->AddFactBlockIsDead(36); // Variables with pointee types: // 52 - ptr_to(7) @@ -139,90 +149,91 @@ TEST(TransformationStoreTest, BasicTest) { // Bad: attempt to store to 11 from outside its function ASSERT_FALSE(TransformationStore( 11, 80, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is not available ASSERT_FALSE(TransformationStore( 81, 80, MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before OpVariable ASSERT_FALSE(TransformationStore( 52, 24, MakeInstructionDescriptor(27, SpvOpVariable, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist ASSERT_FALSE(TransformationStore( 1000, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists but does not have a type ASSERT_FALSE(TransformationStore( 5, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists and has a type, but is not a pointer ASSERT_FALSE(TransformationStore( 24, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to a null pointer ASSERT_FALSE(TransformationStore( 60, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to an undefined pointer ASSERT_FALSE(TransformationStore( 61, 21, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: %82 is not available at the program point ASSERT_FALSE( TransformationStore(82, 80, MakeInstructionDescriptor(37, SpvOpReturn, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: value id does not exist ASSERT_FALSE(TransformationStore( 27, 1000, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: value id exists but does not have a type ASSERT_FALSE(TransformationStore( 27, 15, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: value id exists but has the wrong type ASSERT_FALSE(TransformationStore( 27, 14, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to read-only variable ASSERT_FALSE(TransformationStore( 92, 93, MakeInstructionDescriptor(40, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: value is not available ASSERT_FALSE(TransformationStore( 27, 95, MakeInstructionDescriptor(40, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Bad: variable being stored to does not have an irrelevant pointee value, // and the store is not in a dead block. ASSERT_FALSE(TransformationStore( 20, 95, MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The described instruction does not exist. ASSERT_FALSE(TransformationStore( 27, 80, MakeInstructionDescriptor(1000, SpvOpAccessChain, 0)) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); { // Store to irrelevant variable from dead block. TransformationStore transformation( 27, 80, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -230,8 +241,9 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 11, 95, MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -239,8 +251,9 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 46, 80, MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -248,8 +261,9 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 16, 21, MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } @@ -257,8 +271,9 @@ TEST(TransformationStoreTest, BasicTest) { // Store to non-irrelevant variable from dead block. TransformationStore transformation( 53, 21, MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); - ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager)); - transformation.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + transformation.Apply(context.get(), &transformation_context); ASSERT_TRUE(IsValid(env, context.get())); } diff --git a/test/fuzz/transformation_swap_commutable_operands_test.cpp b/test/fuzz/transformation_swap_commutable_operands_test.cpp index f0591cf1..c213dfea 100644 --- a/test/fuzz/transformation_swap_commutable_operands_test.cpp +++ b/test/fuzz/transformation_swap_commutable_operands_test.cpp @@ -111,113 +111,140 @@ TEST(TransformationSwapCommutableOperandsTest, IsApplicableTest) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); - FactManager factManager; + FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Tests existing commutative instructions auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0); auto transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests existing non-commutative instructions instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(8, SpvOpConstant, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(11, SpvOpVariable, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(14, SpvOpConstantComposite, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests the base instruction id not existing instructionDescriptor = MakeInstructionDescriptor(67, SpvOpIAddCarry, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(68, SpvOpIEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(69, SpvOpINotEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(70, SpvOpFOrdEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(71, SpvOpPtrEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests there being no instruction with the desired opcode after the base // instruction id instructionDescriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(38, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(45, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(66, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests there being an instruction with the desired opcode after the base // instruction id, but the skip count associated with the instruction // descriptor being so high. instructionDescriptor = MakeInstructionDescriptor(11, SpvOpIAdd, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(16, SpvOpIMul, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(23, SpvOpFAdd, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(32, SpvOpFMul, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(37, SpvOpDot, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationSwapCommutableOperandsTest, ApplyTest) { @@ -311,28 +338,31 @@ TEST(TransformationSwapCommutableOperandsTest, ApplyTest) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); - FactManager factManager; + FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0); auto transformation = TransformationSwapCommutableOperands(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); std::string variantShader = R"( OpCapability Shader diff --git a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp index 98e0a644..b20f59e0 100644 --- a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp +++ b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp @@ -111,78 +111,93 @@ TEST(TransformationToggleAccessChainInstructionTest, IsApplicableTest) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); - FactManager factManager; + FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Tests existing access chain instructions auto instructionDescriptor = MakeInstructionDescriptor(18, SpvOpAccessChain, 0); auto transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests existing non-access chain instructions instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(14, SpvOpConstantComposite, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests the base instruction id not existing instructionDescriptor = MakeInstructionDescriptor(67, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(68, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(69, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests there being no instruction with the desired opcode after the base // instruction id instructionDescriptor = MakeInstructionDescriptor(65, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(66, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); // Tests there being an instruction with the desired opcode after the base // instruction id, but the skip count associated with the instruction @@ -190,13 +205,15 @@ TEST(TransformationToggleAccessChainInstructionTest, IsApplicableTest) { instructionDescriptor = MakeInstructionDescriptor(11, SpvOpAccessChain, 100); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = MakeInstructionDescriptor(16, SpvOpInBoundsAccessChain, 100); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager)); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); } TEST(TransformationToggleAccessChainInstructionTest, ApplyTest) { @@ -290,35 +307,38 @@ TEST(TransformationToggleAccessChainInstructionTest, ApplyTest) { const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); ASSERT_TRUE(IsValid(env, context.get())); - FactManager factManager; + FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); auto instructionDescriptor = MakeInstructionDescriptor(18, SpvOpAccessChain, 0); auto transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); instructionDescriptor = MakeInstructionDescriptor(38, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); - transformation.Apply(context.get(), &factManager); + transformation.Apply(context.get(), &transformation_context); std::string variantShader = R"( OpCapability Shader diff --git a/test/fuzz/transformation_vector_shuffle_test.cpp b/test/fuzz/transformation_vector_shuffle_test.cpp index 385c38b4..e3c7fd44 100644 --- a/test/fuzz/transformation_vector_shuffle_test.cpp +++ b/test/fuzz/transformation_vector_shuffle_test.cpp @@ -86,249 +86,259 @@ TEST(TransformationVectorShuffle, BasicTest) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), - MakeDataDescriptor(12, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}), - MakeDataDescriptor(12, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(10, {}), MakeDataDescriptor(12, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(11, {}), MakeDataDescriptor(12, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), - MakeDataDescriptor(16, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}), - MakeDataDescriptor(16, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), - MakeDataDescriptor(16, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(10, {}), MakeDataDescriptor(16, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(11, {}), MakeDataDescriptor(16, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(10, {}), MakeDataDescriptor(16, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), - MakeDataDescriptor(20, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}), - MakeDataDescriptor(20, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), - MakeDataDescriptor(20, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}), - MakeDataDescriptor(20, {3}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(10, {}), MakeDataDescriptor(20, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(11, {}), MakeDataDescriptor(20, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(10, {}), MakeDataDescriptor(20, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(11, {}), MakeDataDescriptor(20, {3}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}), - MakeDataDescriptor(27, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}), - MakeDataDescriptor(27, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(25, {}), MakeDataDescriptor(27, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(26, {}), MakeDataDescriptor(27, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}), - MakeDataDescriptor(31, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}), - MakeDataDescriptor(31, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}), - MakeDataDescriptor(31, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(25, {}), MakeDataDescriptor(31, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(26, {}), MakeDataDescriptor(31, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(25, {}), MakeDataDescriptor(31, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}), - MakeDataDescriptor(35, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}), - MakeDataDescriptor(35, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}), - MakeDataDescriptor(35, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}), - MakeDataDescriptor(35, {3}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(25, {}), MakeDataDescriptor(35, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(26, {}), MakeDataDescriptor(35, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(25, {}), MakeDataDescriptor(35, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(26, {}), MakeDataDescriptor(35, {3}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}), - MakeDataDescriptor(42, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}), - MakeDataDescriptor(42, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(40, {}), MakeDataDescriptor(42, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(41, {}), MakeDataDescriptor(42, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}), - MakeDataDescriptor(46, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}), - MakeDataDescriptor(46, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}), - MakeDataDescriptor(46, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(40, {}), MakeDataDescriptor(46, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(41, {}), MakeDataDescriptor(46, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(40, {}), MakeDataDescriptor(46, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}), - MakeDataDescriptor(50, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}), - MakeDataDescriptor(50, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}), - MakeDataDescriptor(50, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}), - MakeDataDescriptor(50, {3}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(40, {}), MakeDataDescriptor(50, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(41, {}), MakeDataDescriptor(50, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(40, {}), MakeDataDescriptor(50, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(41, {}), MakeDataDescriptor(50, {3}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}), - MakeDataDescriptor(61, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}), - MakeDataDescriptor(61, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}), - MakeDataDescriptor(61, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(55, {}), MakeDataDescriptor(61, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(56, {}), MakeDataDescriptor(61, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(55, {}), MakeDataDescriptor(61, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}), - MakeDataDescriptor(65, {0}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}), - MakeDataDescriptor(65, {1}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}), - MakeDataDescriptor(65, {2}), context.get()); - fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}), - MakeDataDescriptor(65, {3}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(55, {}), MakeDataDescriptor(65, {0}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(56, {}), MakeDataDescriptor(65, {1}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(55, {}), MakeDataDescriptor(65, {2}), context.get()); + transformation_context.GetFactManager()->AddFactDataSynonym( + MakeDataDescriptor(56, {}), MakeDataDescriptor(65, {3}), context.get()); // %103 does not dominate the return instruction. ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 103, 65, {3, 5, 7}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Illegal to shuffle a bvec2 and a vec3 ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 112, 61, {0, 2, 4}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Illegal to shuffle an ivec2 and a uvec4 ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 50, {1, 3, 5}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Vector 1 does not exist ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 300, 50, {1, 3, 5}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Vector 2 does not exist ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 300, {1, 3, 5}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Index out of range ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0, 20}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too many indices ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0, 1, 0, 1, 0, 1, 0, 1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too few indices ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Too few indices again ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Indices define unknown type: we do not have vec2 ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 65, 65, {0, 1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The instruction to insert before does not exist ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpCompositeConstruct, 1), 201, 20, 12, {0xFFFFFFFF, 3, 5}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // The 'fresh' id is already in use ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(100, SpvOpReturn, 0), 12, 12, 112, {}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); protobufs::DataDescriptor temp_dd; TransformationVectorShuffle transformation1( MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {1, 0}); - ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager)); - transformation1.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + transformation1.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(200, {0}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(11, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(200, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(10, {}), temp_dd, context.get())); TransformationVectorShuffle transformation2( MakeInstructionDescriptor(100, SpvOpReturn, 0), 201, 20, 12, {0xFFFFFFFF, 3, 5}); - ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager)); - transformation2.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + transformation2.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(201, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(11, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(201, {2}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(11, {}), temp_dd, context.get())); TransformationVectorShuffle transformation3( MakeInstructionDescriptor(100, SpvOpReturn, 0), 202, 27, 35, {5, 4, 1}); - ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager)); - transformation3.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation3.IsApplicable(context.get(), transformation_context)); + transformation3.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(202, {0}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(26, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(26, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(202, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(25, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(25, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(202, {2}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(26, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(26, {}), temp_dd, context.get())); TransformationVectorShuffle transformation4( MakeInstructionDescriptor(100, SpvOpReturn, 0), 203, 42, 46, {0, 1}); - ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager)); - transformation4.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation4.IsApplicable(context.get(), transformation_context)); + transformation4.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(203, {0}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(40, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(203, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(41, {}), temp_dd, context.get())); TransformationVectorShuffle transformation5( MakeInstructionDescriptor(100, SpvOpReturn, 0), 204, 42, 46, {2, 3, 4}); - ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager)); - transformation5.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation5.IsApplicable(context.get(), transformation_context)); + transformation5.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(204, {0}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(40, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(204, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(41, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(204, {2}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(40, {}), temp_dd, context.get())); TransformationVectorShuffle transformation6( MakeInstructionDescriptor(100, SpvOpReturn, 0), 205, 42, 42, {0, 1, 2, 3}); - ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager)); - transformation6.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation6.IsApplicable(context.get(), transformation_context)); + transformation6.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(205, {0}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(40, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(205, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(41, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(205, {2}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(40, {}), temp_dd, context.get())); temp_dd = MakeDataDescriptor(205, {3}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(41, {}), temp_dd, context.get())); // swizzle vec4 from vec4 and vec4 using some undefs TransformationVectorShuffle transformation7( MakeInstructionDescriptor(100, SpvOpReturn, 0), 206, 65, 65, {0xFFFFFFFF, 3, 6, 0xFFFFFFFF}); - ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager)); - transformation7.Apply(context.get(), &fact_manager); + ASSERT_TRUE( + transformation7.IsApplicable(context.get(), transformation_context)); + transformation7.Apply(context.get(), &transformation_context); temp_dd = MakeDataDescriptor(206, {1}); - ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(56, {}), temp_dd, - context.get())); + ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(56, {}), temp_dd, context.get())); std::string after_transformation = R"( OpCapability Shader @@ -479,52 +489,55 @@ TEST(TransformationVectorShuffleTest, IllegalInsertionPoints) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; + spvtools::ValidatorOptions validator_options; + TransformationContext transformation_context(&fact_manager, + validator_options); // Cannot insert before the OpVariables of a function. ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, 14, {0, 1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, 14, {1, 2}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, 14, {1, 2}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK to insert right after the OpVariables. ASSERT_FALSE( TransformationVectorShuffle( MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, 14, {1, 1}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before the OpPhis of a block. ASSERT_FALSE( TransformationVectorShuffle(MakeInstructionDescriptor(60, SpvOpPhi, 0), 200, 14, 14, {2, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationVectorShuffle(MakeInstructionDescriptor(59, SpvOpPhi, 0), 200, 14, 14, {3, 0}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // OK to insert after the OpPhis. ASSERT_TRUE(TransformationVectorShuffle( MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14, 14, {3, 4}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpLoopMerge ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(33, SpvOpBranchConditional, 0), 200, 14, 14, {3}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpSelectionMerge ASSERT_FALSE(TransformationVectorShuffle( MakeInstructionDescriptor(21, SpvOpBranchConditional, 0), 200, 14, 14, {2}) - .IsApplicable(context.get(), fact_manager)); + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index 469c81b4..2c9807d1 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -580,7 +580,8 @@ int main(int argc, const char** argv) { switch (status.action) { case FuzzActions::FORCE_RENDER_RED: - if (!spvtools::fuzz::ForceRenderRed(target_env, binary_in, initial_facts, + if (!spvtools::fuzz::ForceRenderRed(target_env, validator_options, + binary_in, initial_facts, &binary_out)) { return 1; }