mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-25 01:01:04 +00:00
spirv-fuzz: Remove AddType methods from fuzzerutil (#4204)
Types should only be added to the module by spirv-fuzz via transformations, so this change removes the AddType methods from fuzzerutil, which were only called once each from the appropriate transformation. The transformations have been adapted so that they avoid redundantly invalidating all analyses - they now update the def-use manager and invalidate only the type manager.
This commit is contained in:
parent
f2a19b0150
commit
75d7c14cfb
@ -1414,74 +1414,6 @@ uint32_t MaybeGetBoolConstant(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddIntegerType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t width, bool is_signed) {
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeInt, 0, result_id,
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {width}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {is_signed ? 1u : 0u}}}));
|
||||
|
||||
UpdateModuleIdBound(ir_context, result_id);
|
||||
}
|
||||
|
||||
void AddFloatType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t width) {
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeFloat, 0, result_id,
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {width}}}));
|
||||
|
||||
UpdateModuleIdBound(ir_context, result_id);
|
||||
}
|
||||
|
||||
void AddVectorType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t component_type_id, uint32_t element_count) {
|
||||
const auto* component_type =
|
||||
ir_context->get_type_mgr()->GetType(component_type_id);
|
||||
(void)component_type; // Make compiler happy in release mode.
|
||||
assert(component_type &&
|
||||
(component_type->AsInteger() || component_type->AsFloat() ||
|
||||
component_type->AsBool()) &&
|
||||
"|component_type_id| is invalid");
|
||||
assert(element_count >= 2 && element_count <= 4 &&
|
||||
"Precondition: component count must be in range [2, 4].");
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeVector, 0, result_id,
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_ID, {component_type_id}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {element_count}}}));
|
||||
|
||||
UpdateModuleIdBound(ir_context, result_id);
|
||||
}
|
||||
|
||||
void AddStructType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
const std::vector<uint32_t>& component_type_ids) {
|
||||
opt::Instruction::OperandList operands;
|
||||
operands.reserve(component_type_ids.size());
|
||||
|
||||
for (auto type_id : component_type_ids) {
|
||||
const auto* type = ir_context->get_type_mgr()->GetType(type_id);
|
||||
(void)type; // Make compiler happy in release mode.
|
||||
assert(type && !type->AsFunction() && "Component's type id is invalid");
|
||||
|
||||
if (type->AsStruct()) {
|
||||
// From the spec for the BuiltIn decoration:
|
||||
// - When applied to a structure-type member, that structure type cannot
|
||||
// be contained as a member of another structure type.
|
||||
assert(!MembersHaveBuiltInDecoration(ir_context, type_id) &&
|
||||
"A member struct has BuiltIn members");
|
||||
}
|
||||
|
||||
operands.push_back({SPV_OPERAND_TYPE_ID, {type_id}});
|
||||
}
|
||||
|
||||
ir_context->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeStruct, 0, result_id, std::move(operands)));
|
||||
|
||||
UpdateModuleIdBound(ir_context, result_id);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> IntToWords(uint64_t value, uint32_t width,
|
||||
bool is_signed) {
|
||||
assert(width <= 64 && "The bit width should not be more than 64 bits");
|
||||
|
@ -495,30 +495,6 @@ uint32_t MaybeGetBoolConstant(
|
||||
const TransformationContext& transformation_context, bool value,
|
||||
bool is_irrelevant);
|
||||
|
||||
// Creates a new OpTypeInt instruction in the module. Updates module's id bound
|
||||
// to accommodate for |result_id|.
|
||||
void AddIntegerType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t width, bool is_signed);
|
||||
|
||||
// Creates a new OpTypeFloat instruction in the module. Updates module's id
|
||||
// bound to accommodate for |result_id|.
|
||||
void AddFloatType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t width);
|
||||
|
||||
// Creates a new OpTypeVector instruction in the module. |component_type_id|
|
||||
// must be a valid result id of an OpTypeInt, OpTypeFloat or OpTypeBool
|
||||
// instruction in the module. |element_count| must be in the range [2, 4].
|
||||
// Updates module's id bound to accommodate for |result_id|.
|
||||
void AddVectorType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
uint32_t component_type_id, uint32_t element_count);
|
||||
|
||||
// Creates a new OpTypeStruct instruction in the module. Updates module's id
|
||||
// bound to accommodate for |result_id|. |component_type_ids| may not contain
|
||||
// a result id of an OpTypeFunction. if |component_type_ids| contains a result
|
||||
// of an OpTypeStruct instruction, that struct may not have BuiltIn members.
|
||||
void AddStructType(opt::IRContext* ir_context, uint32_t result_id,
|
||||
const std::vector<uint32_t>& component_type_ids);
|
||||
|
||||
// Returns a vector of words representing the integer |value|, only considering
|
||||
// the last |width| bits. The last |width| bits are sign-extended if the value
|
||||
// is signed, zero-extended if it is unsigned.
|
||||
|
@ -69,13 +69,17 @@ void TransformationAddTypeArray::Apply(
|
||||
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()}});
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeArray, 0, message_.fresh_id(), in_operands));
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeArray, 0, message_.fresh_id(), in_operands);
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
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.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeArray::ToMessage() const {
|
||||
|
@ -42,13 +42,17 @@ bool TransformationAddTypeBoolean::IsApplicable(
|
||||
void TransformationAddTypeBoolean::Apply(
|
||||
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||
opt::Instruction::OperandList empty_operands;
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeBool, 0, message_.fresh_id(), empty_operands));
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeBool, 0, message_.fresh_id(), empty_operands);
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
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.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeBoolean::ToMessage() const {
|
||||
|
@ -65,11 +65,18 @@ bool TransformationAddTypeFloat::IsApplicable(
|
||||
|
||||
void TransformationAddTypeFloat::Apply(
|
||||
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||
fuzzerutil::AddFloatType(ir_context, message_.fresh_id(), message_.width());
|
||||
// We have added an instruction to the module, so need to be careful about the
|
||||
// validity of existing analyses.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeFloat, 0, message_.fresh_id(),
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}}});
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||
|
||||
// Inform the def use manager that there is a new definition, and invalidate
|
||||
// the type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeFloat::ToMessage() const {
|
||||
|
@ -74,12 +74,21 @@ bool TransformationAddTypeInt::IsApplicable(
|
||||
|
||||
void TransformationAddTypeInt::Apply(opt::IRContext* ir_context,
|
||||
TransformationContext* /*unused*/) const {
|
||||
fuzzerutil::AddIntegerType(ir_context, message_.fresh_id(), message_.width(),
|
||||
message_.is_signed());
|
||||
// We have added an instruction to the module, so need to be careful about the
|
||||
// validity of existing analyses.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeInt, 0, message_.fresh_id(),
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER,
|
||||
{message_.is_signed() ? 1u : 0u}}});
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeInt::ToMessage() const {
|
||||
|
@ -52,13 +52,17 @@ void TransformationAddTypeMatrix::Apply(
|
||||
in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.column_type_id()}});
|
||||
in_operands.push_back(
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.column_count()}});
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeMatrix, 0, message_.fresh_id(), in_operands));
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeMatrix, 0, message_.fresh_id(), in_operands);
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
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.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeMatrix::ToMessage() const {
|
||||
|
@ -47,13 +47,17 @@ void TransformationAddTypePointer::Apply(
|
||||
opt::Instruction::OperandList in_operands = {
|
||||
{SPV_OPERAND_TYPE_STORAGE_CLASS, {message_.storage_class()}},
|
||||
{SPV_OPERAND_TYPE_ID, {message_.base_type_id()}}};
|
||||
ir_context->module()->AddType(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypePointer, 0, message_.fresh_id(), in_operands));
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypePointer, 0, message_.fresh_id(), in_operands);
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
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.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypePointer::ToMessage() const {
|
||||
|
@ -58,14 +58,36 @@ bool TransformationAddTypeStruct::IsApplicable(
|
||||
|
||||
void TransformationAddTypeStruct::Apply(
|
||||
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||
fuzzerutil::AddStructType(
|
||||
ir_context, message_.fresh_id(),
|
||||
std::vector<uint32_t>(message_.member_type_id().begin(),
|
||||
message_.member_type_id().end()));
|
||||
// We have added an instruction to the module, so need to be careful about the
|
||||
// validity of existing analyses.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
opt::Instruction::OperandList operands;
|
||||
operands.reserve(message_.member_type_id().size());
|
||||
|
||||
for (auto type_id : message_.member_type_id()) {
|
||||
const auto* type = ir_context->get_type_mgr()->GetType(type_id);
|
||||
(void)type; // Make compiler happy in release mode.
|
||||
assert(type && !type->AsFunction() && "Component's type id is invalid");
|
||||
|
||||
if (type->AsStruct()) {
|
||||
// From the spec for the BuiltIn decoration:
|
||||
// - When applied to a structure-type member, that structure type cannot
|
||||
// be contained as a member of another structure type.
|
||||
assert(!fuzzerutil::MembersHaveBuiltInDecoration(ir_context, type_id) &&
|
||||
"A member struct has BuiltIn members");
|
||||
}
|
||||
|
||||
operands.push_back({SPV_OPERAND_TYPE_ID, {type_id}});
|
||||
}
|
||||
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeStruct, 0, message_.fresh_id(), std::move(operands));
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->AddType(std::move(type_instruction));
|
||||
|
||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeStruct::ToMessage() const {
|
||||
|
@ -46,13 +46,30 @@ bool TransformationAddTypeVector::IsApplicable(
|
||||
|
||||
void TransformationAddTypeVector::Apply(
|
||||
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||
fuzzerutil::AddVectorType(ir_context, message_.fresh_id(),
|
||||
message_.component_type_id(),
|
||||
message_.component_count());
|
||||
// We have added an instruction to the module, so need to be careful about the
|
||||
// validity of existing analyses.
|
||||
ir_context->InvalidateAnalysesExceptFor(
|
||||
opt::IRContext::Analysis::kAnalysisNone);
|
||||
const auto* component_type =
|
||||
ir_context->get_type_mgr()->GetType(message_.component_type_id());
|
||||
(void)component_type; // Make compiler happy in release mode.
|
||||
assert(component_type &&
|
||||
(component_type->AsInteger() || component_type->AsFloat() ||
|
||||
component_type->AsBool()) &&
|
||||
"|component_type_id| is invalid");
|
||||
assert(message_.component_count() >= 2 && message_.component_count() <= 4 &&
|
||||
"Precondition: component count must be in range [2, 4].");
|
||||
|
||||
auto type_instruction = MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpTypeVector, 0, message_.fresh_id(),
|
||||
opt::Instruction::OperandList{
|
||||
{SPV_OPERAND_TYPE_ID, {message_.component_type_id()}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.component_count()}}});
|
||||
auto type_instruction_ptr = type_instruction.get();
|
||||
ir_context->module()->AddType(std::move(type_instruction));
|
||||
|
||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||
|
||||
// Inform the def use manager that there is a new definition. Invalidate the
|
||||
// type manager since we have added a new type.
|
||||
ir_context->get_def_use_mgr()->AnalyzeInstDef(type_instruction_ptr);
|
||||
ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisTypes);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationAddTypeVector::ToMessage() const {
|
||||
|
Loading…
Reference in New Issue
Block a user