diff options
Diffstat (limited to '3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp')
-rw-r--r-- | 3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp | 109 |
1 files changed, 26 insertions, 83 deletions
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp index cfd97aeb812..af1e81c37e9 100644 --- a/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp +++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/fuzz/transformation_copy_object.cpp @@ -14,7 +14,9 @@ #include "source/fuzz/transformation_copy_object.h" +#include "source/fuzz/data_descriptor.h" #include "source/fuzz/fuzzer_util.h" +#include "source/fuzz/instruction_descriptor.h" #include "source/opt/instruction.h" #include "source/util/make_unique.h" @@ -25,13 +27,13 @@ TransformationCopyObject::TransformationCopyObject( const protobufs::TransformationCopyObject& message) : message_(message) {} -TransformationCopyObject::TransformationCopyObject(uint32_t object, - uint32_t base_instruction_id, - uint32_t offset, - uint32_t fresh_id) { +TransformationCopyObject::TransformationCopyObject( + uint32_t object, + const protobufs::InstructionDescriptor& instruction_to_insert_before, + uint32_t fresh_id) { message_.set_object(object); - message_.set_base_instruction_id(base_instruction_id); - message_.set_offset(offset); + *message_.mutable_instruction_to_insert_before() = + instruction_to_insert_before; message_.set_fresh_id(fresh_id); } @@ -46,32 +48,19 @@ bool TransformationCopyObject::IsApplicable( if (!object_inst) { return false; } - if (!IsCopyable(context, object_inst)) { - return false; - } - - auto base_instruction = - context->get_def_use_mgr()->GetDef(message_.base_instruction_id()); - if (!base_instruction) { - // The given id to insert after is not defined. + if (!fuzzerutil::CanMakeSynonymOf(context, object_inst)) { return false; } - auto destination_block = context->get_instr_block(base_instruction); - if (!destination_block) { - // The given id to insert after is not in a block. + auto insert_before = + FindInstruction(message_.instruction_to_insert_before(), context); + if (!insert_before) { + // The instruction before which the copy should be inserted was not found. return false; } - auto insert_before = fuzzerutil::GetIteratorForBaseInstructionAndOffset( - destination_block, base_instruction, message_.offset()); - - if (insert_before == destination_block->end()) { - // The offset was inappropriate. - return false; - } - - if (!CanInsertCopyBefore(insert_before)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyObject, + insert_before)) { return false; } @@ -85,28 +74,22 @@ bool TransformationCopyObject::IsApplicable( // insert it before the object's defining instruction. return !context->get_instr_block(object_inst) || (object_inst != &*insert_before && - context->GetDominatorAnalysis(destination_block->GetParent()) + context + ->GetDominatorAnalysis( + context->get_instr_block(insert_before)->GetParent()) ->Dominates(object_inst, &*insert_before)); } void TransformationCopyObject::Apply(opt::IRContext* context, FactManager* fact_manager) const { - // - 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 the fact manager. - // The id of the object to be copied must exist auto object_inst = context->get_def_use_mgr()->GetDef(message_.object()); assert(object_inst && "The object to be copied must exist."); - auto base_instruction = - context->get_def_use_mgr()->GetDef(message_.base_instruction_id()); - assert(base_instruction && "The base instruction must exist."); - auto destination_block = context->get_instr_block(base_instruction); + auto insert_before_inst = + FindInstruction(message_.instruction_to_insert_before(), context); + auto destination_block = context->get_instr_block(insert_before_inst); assert(destination_block && "The base instruction must be in a block."); - auto insert_before = fuzzerutil::GetIteratorForBaseInstructionAndOffset( - destination_block, base_instruction, message_.offset()); + auto insert_before = fuzzerutil::GetIteratorForInstruction( + destination_block, insert_before_inst); assert(insert_before != destination_block->end() && "There must be an instruction before which the copy can be inserted."); @@ -119,11 +102,9 @@ void TransformationCopyObject::Apply(opt::IRContext* context, fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id()); context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); - protobufs::Fact fact; - fact.mutable_id_synonym_fact()->set_id(message_.object()); - fact.mutable_id_synonym_fact()->mutable_data_descriptor()->set_object( - message_.fresh_id()); - fact_manager->AddFact(fact, context); + fact_manager->AddFactDataSynonym(MakeDataDescriptor(message_.object(), {}), + MakeDataDescriptor(message_.fresh_id(), {}), + context); } protobufs::Transformation TransformationCopyObject::ToMessage() const { @@ -132,43 +113,5 @@ protobufs::Transformation TransformationCopyObject::ToMessage() const { return result; } -bool TransformationCopyObject::IsCopyable(opt::IRContext* ir_context, - opt::Instruction* inst) { - if (!inst->HasResultId()) { - // We can only apply OpCopyObject to instructions that generate ids. - return false; - } - if (!inst->type_id()) { - // We can only apply OpCopyObject to instructions that have types. - return false; - } - // We do not copy objects that have decorations: if the copy is not - // decorated analogously, using the original object vs. its copy may not be - // equivalent. - // TODO(afd): it would be possible to make the copy but not add an id - // synonym. - return ir_context->get_decoration_mgr() - ->GetDecorationsFor(inst->result_id(), true) - .empty(); -} - -bool TransformationCopyObject::CanInsertCopyBefore( - const opt::BasicBlock::iterator& instruction_in_block) { - if (instruction_in_block->PreviousNode() && - (instruction_in_block->PreviousNode()->opcode() == SpvOpLoopMerge || - instruction_in_block->PreviousNode()->opcode() == SpvOpSelectionMerge)) { - // We cannot insert a copy directly after a merge instruction. - return false; - } - if (instruction_in_block->opcode() == SpvOpVariable) { - // We cannot insert a copy directly before a variable; variables in a - // function must be contiguous in the entry block. - return false; - } - // We cannot insert a copy directly before OpPhi, because OpPhi instructions - // need to be contiguous at the start of a block. - return instruction_in_block->opcode() != SpvOpPhi; -} - } // namespace fuzz } // namespace spvtools |