Updated spirv-tools.
This commit is contained in:
parent
a3598c6d28
commit
2d3a057a68
@ -1 +1 @@
|
||||
"v2023.2", "SPIRV-Tools v2023.2 v2022.4-192-ge472626b"
|
||||
"v2023.2", "SPIRV-Tools v2023.2 v2022.4-196-g1b88382e"
|
||||
|
@ -156,7 +156,8 @@ bool AggressiveDCEPass::AllExtensionsSupported() const {
|
||||
"Expecting an import of an extension's instruction set.");
|
||||
const std::string extension_name = inst.GetInOperand(0).AsString();
|
||||
if (spvtools::utils::starts_with(extension_name, "NonSemantic.") &&
|
||||
extension_name != "NonSemantic.Shader.DebugInfo.100") {
|
||||
(extension_name != "NonSemantic.Shader.DebugInfo.100") &&
|
||||
(extension_name != "NonSemantic.DebugPrintf")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,13 @@ bool ConvertToHalfPass::IsFloat(Instruction* inst, uint32_t width) {
|
||||
return Pass::IsFloat(ty_id, width);
|
||||
}
|
||||
|
||||
bool ConvertToHalfPass::IsStruct(Instruction* inst) {
|
||||
uint32_t ty_id = inst->type_id();
|
||||
if (ty_id == 0) return false;
|
||||
Instruction* ty_inst = Pass::GetBaseType(ty_id);
|
||||
return (ty_inst->opcode() == spv::Op::OpTypeStruct);
|
||||
}
|
||||
|
||||
bool ConvertToHalfPass::IsDecoratedRelaxed(Instruction* inst) {
|
||||
uint32_t r_id = inst->result_id();
|
||||
for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false))
|
||||
@ -294,6 +301,7 @@ bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) {
|
||||
bool relax = true;
|
||||
inst->ForEachInId([&relax, this](uint32_t* idp) {
|
||||
Instruction* op_inst = get_def_use_mgr()->GetDef(*idp);
|
||||
if (IsStruct(op_inst)) relax = false;
|
||||
if (!IsFloat(op_inst, 32)) return;
|
||||
if (!IsRelaxed(*idp)) relax = false;
|
||||
});
|
||||
|
@ -45,6 +45,7 @@ class ConvertToHalfPass : public Pass {
|
||||
// Return true if |inst| returns scalar, vector or matrix type with base
|
||||
// float and |width|
|
||||
bool IsFloat(Instruction* inst, uint32_t width);
|
||||
bool IsStruct(Instruction* inst);
|
||||
|
||||
// Return true if |inst| is decorated with RelaxedPrecision
|
||||
bool IsDecoratedRelaxed(Instruction* inst);
|
||||
|
@ -466,9 +466,9 @@ void ScalarReplacementPass::TransferAnnotations(
|
||||
}
|
||||
|
||||
void ScalarReplacementPass::CreateVariable(
|
||||
uint32_t typeId, Instruction* varInst, uint32_t index,
|
||||
uint32_t type_id, Instruction* var_inst, uint32_t index,
|
||||
std::vector<Instruction*>* replacements) {
|
||||
uint32_t ptrId = GetOrCreatePointerType(typeId);
|
||||
uint32_t ptr_id = GetOrCreatePointerType(type_id);
|
||||
uint32_t id = TakeNextId();
|
||||
|
||||
if (id == 0) {
|
||||
@ -476,51 +476,22 @@ void ScalarReplacementPass::CreateVariable(
|
||||
}
|
||||
|
||||
std::unique_ptr<Instruction> variable(
|
||||
new Instruction(context(), spv::Op::OpVariable, ptrId, id,
|
||||
new Instruction(context(), spv::Op::OpVariable, ptr_id, id,
|
||||
std::initializer_list<Operand>{
|
||||
{SPV_OPERAND_TYPE_STORAGE_CLASS,
|
||||
{uint32_t(spv::StorageClass::Function)}}}));
|
||||
|
||||
BasicBlock* block = context()->get_instr_block(varInst);
|
||||
BasicBlock* block = context()->get_instr_block(var_inst);
|
||||
block->begin().InsertBefore(std::move(variable));
|
||||
Instruction* inst = &*block->begin();
|
||||
|
||||
// If varInst was initialized, make sure to initialize its replacement.
|
||||
GetOrCreateInitialValue(varInst, index, inst);
|
||||
GetOrCreateInitialValue(var_inst, index, inst);
|
||||
get_def_use_mgr()->AnalyzeInstDefUse(inst);
|
||||
context()->set_instr_block(inst, block);
|
||||
|
||||
// Copy decorations from the member to the new variable.
|
||||
Instruction* typeInst = GetStorageType(varInst);
|
||||
for (auto dec_inst :
|
||||
get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) {
|
||||
uint32_t decoration;
|
||||
if (dec_inst->opcode() != spv::Op::OpMemberDecorate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dec_inst->GetSingleWordInOperand(1) != index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
decoration = dec_inst->GetSingleWordInOperand(2u);
|
||||
switch (spv::Decoration(decoration)) {
|
||||
case spv::Decoration::RelaxedPrecision: {
|
||||
std::unique_ptr<Instruction> new_dec_inst(
|
||||
new Instruction(context(), spv::Op::OpDecorate, 0, 0, {}));
|
||||
new_dec_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {id}));
|
||||
for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) {
|
||||
new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i)));
|
||||
}
|
||||
context()->AddAnnotationInst(std::move(new_dec_inst));
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the DebugInfo debug information.
|
||||
inst->UpdateDebugInfoFrom(varInst);
|
||||
CopyDecorationsToVariable(var_inst, inst, index);
|
||||
inst->UpdateDebugInfoFrom(var_inst);
|
||||
|
||||
replacements->push_back(inst);
|
||||
}
|
||||
@ -529,52 +500,11 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) {
|
||||
auto iter = pointee_to_pointer_.find(id);
|
||||
if (iter != pointee_to_pointer_.end()) return iter->second;
|
||||
|
||||
analysis::Type* pointeeTy;
|
||||
std::unique_ptr<analysis::Pointer> pointerTy;
|
||||
std::tie(pointeeTy, pointerTy) =
|
||||
context()->get_type_mgr()->GetTypeAndPointerType(
|
||||
id, spv::StorageClass::Function);
|
||||
uint32_t ptrId = 0;
|
||||
if (pointeeTy->IsUniqueType()) {
|
||||
// Non-ambiguous type, just ask the type manager for an id.
|
||||
ptrId = context()->get_type_mgr()->GetTypeInstruction(pointerTy.get());
|
||||
pointee_to_pointer_[id] = ptrId;
|
||||
return ptrId;
|
||||
}
|
||||
|
||||
// Ambiguous type. We must perform a linear search to try and find the right
|
||||
// type.
|
||||
for (auto global : context()->types_values()) {
|
||||
if (global.opcode() == spv::Op::OpTypePointer &&
|
||||
spv::StorageClass(global.GetSingleWordInOperand(0u)) ==
|
||||
spv::StorageClass::Function &&
|
||||
global.GetSingleWordInOperand(1u) == id) {
|
||||
if (get_decoration_mgr()->GetDecorationsFor(id, false).empty()) {
|
||||
// Only reuse a decoration-less pointer of the correct type.
|
||||
ptrId = global.result_id();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ptrId != 0) {
|
||||
pointee_to_pointer_[id] = ptrId;
|
||||
return ptrId;
|
||||
}
|
||||
|
||||
ptrId = TakeNextId();
|
||||
context()->AddType(MakeUnique<Instruction>(
|
||||
context(), spv::Op::OpTypePointer, 0, ptrId,
|
||||
std::initializer_list<Operand>{{SPV_OPERAND_TYPE_STORAGE_CLASS,
|
||||
{uint32_t(spv::StorageClass::Function)}},
|
||||
{SPV_OPERAND_TYPE_ID, {id}}}));
|
||||
Instruction* ptr = &*--context()->types_values_end();
|
||||
get_def_use_mgr()->AnalyzeInstDefUse(ptr);
|
||||
pointee_to_pointer_[id] = ptrId;
|
||||
// Register with the type manager if necessary.
|
||||
context()->get_type_mgr()->RegisterType(ptrId, *pointerTy);
|
||||
|
||||
return ptrId;
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
uint32_t ptr_type_id =
|
||||
type_mgr->FindPointerToType(id, spv::StorageClass::Function);
|
||||
pointee_to_pointer_[id] = ptr_type_id;
|
||||
return ptr_type_id;
|
||||
}
|
||||
|
||||
void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source,
|
||||
@ -761,6 +691,8 @@ bool ScalarReplacementPass::CheckTypeAnnotations(
|
||||
case spv::Decoration::AlignmentId:
|
||||
case spv::Decoration::MaxByteOffset:
|
||||
case spv::Decoration::RelaxedPrecision:
|
||||
case spv::Decoration::AliasedPointer:
|
||||
case spv::Decoration::RestrictPointer:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@ -781,6 +713,8 @@ bool ScalarReplacementPass::CheckAnnotations(const Instruction* varInst) const {
|
||||
case spv::Decoration::Alignment:
|
||||
case spv::Decoration::AlignmentId:
|
||||
case spv::Decoration::MaxByteOffset:
|
||||
case spv::Decoration::AliasedPointer:
|
||||
case spv::Decoration::RestrictPointer:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@ -1011,5 +945,69 @@ uint64_t ScalarReplacementPass::GetMaxLegalIndex(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScalarReplacementPass::CopyDecorationsToVariable(Instruction* from,
|
||||
Instruction* to,
|
||||
uint32_t member_index) {
|
||||
CopyPointerDecorationsToVariable(from, to);
|
||||
CopyNecessaryMemberDecorationsToVariable(from, to, member_index);
|
||||
}
|
||||
|
||||
void ScalarReplacementPass::CopyPointerDecorationsToVariable(Instruction* from,
|
||||
Instruction* to) {
|
||||
// The RestrictPointer and AliasedPointer decorations are copied to all
|
||||
// members even if the new variable does not contain a pointer. It does
|
||||
// not hurt to do so.
|
||||
for (auto dec_inst :
|
||||
get_decoration_mgr()->GetDecorationsFor(from->result_id(), false)) {
|
||||
uint32_t decoration;
|
||||
decoration = dec_inst->GetSingleWordInOperand(1u);
|
||||
switch (spv::Decoration(decoration)) {
|
||||
case spv::Decoration::AliasedPointer:
|
||||
case spv::Decoration::RestrictPointer: {
|
||||
std::unique_ptr<Instruction> new_dec_inst(dec_inst->Clone(context()));
|
||||
new_dec_inst->SetInOperand(0, {to->result_id()});
|
||||
context()->AddAnnotationInst(std::move(new_dec_inst));
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScalarReplacementPass::CopyNecessaryMemberDecorationsToVariable(
|
||||
Instruction* from, Instruction* to, uint32_t member_index) {
|
||||
Instruction* type_inst = GetStorageType(from);
|
||||
for (auto dec_inst :
|
||||
get_decoration_mgr()->GetDecorationsFor(type_inst->result_id(), false)) {
|
||||
uint32_t decoration;
|
||||
if (dec_inst->opcode() == spv::Op::OpMemberDecorate) {
|
||||
if (dec_inst->GetSingleWordInOperand(1) != member_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
decoration = dec_inst->GetSingleWordInOperand(2u);
|
||||
switch (spv::Decoration(decoration)) {
|
||||
case spv::Decoration::ArrayStride:
|
||||
case spv::Decoration::Alignment:
|
||||
case spv::Decoration::AlignmentId:
|
||||
case spv::Decoration::MaxByteOffset:
|
||||
case spv::Decoration::MaxByteOffsetId:
|
||||
case spv::Decoration::RelaxedPrecision: {
|
||||
std::unique_ptr<Instruction> new_dec_inst(
|
||||
new Instruction(context(), spv::Op::OpDecorate, 0, 0, {}));
|
||||
new_dec_inst->AddOperand(
|
||||
Operand(SPV_OPERAND_TYPE_ID, {to->result_id()}));
|
||||
for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) {
|
||||
new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i)));
|
||||
}
|
||||
context()->AddAnnotationInst(std::move(new_dec_inst));
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
@ -262,9 +262,26 @@ class ScalarReplacementPass : public MemPass {
|
||||
// that we will be willing to split.
|
||||
bool IsLargerThanSizeLimit(uint64_t length) const;
|
||||
|
||||
// Copies all relevant decorations from `from` to `to`. This includes
|
||||
// decorations applied to the variable, and to the members of the type.
|
||||
// It is assumed that `to` is a variable that is intended to replace the
|
||||
// `member_index`th member of `from`.
|
||||
void CopyDecorationsToVariable(Instruction* from, Instruction* to,
|
||||
uint32_t member_index);
|
||||
|
||||
// Copies pointer related decoration from `from` to `to` if they exist.
|
||||
void CopyPointerDecorationsToVariable(Instruction* from, Instruction* to);
|
||||
|
||||
// Copies decorations that are needed from the `member_index` of `from` to
|
||||
// `to, if there was one.
|
||||
void CopyNecessaryMemberDecorationsToVariable(Instruction* from,
|
||||
Instruction* to,
|
||||
uint32_t member_index);
|
||||
|
||||
// Limit on the number of members in an object that will be replaced.
|
||||
// 0 means there is no limit.
|
||||
uint32_t max_num_elements_;
|
||||
|
||||
// This has to be big enough to fit "scalar-replacement=" followed by a
|
||||
// uint32_t number written in decimal (so 10 digits), and then a
|
||||
// terminating nul.
|
||||
|
@ -178,7 +178,7 @@ void TypeManager::RemoveId(uint32_t id) {
|
||||
if (iter == id_to_type_.end()) return;
|
||||
|
||||
auto& type = iter->second;
|
||||
if (!type->IsUniqueType(true)) {
|
||||
if (!type->IsUniqueType()) {
|
||||
auto tIter = type_to_id_.find(type);
|
||||
if (tIter != type_to_id_.end() && tIter->second == id) {
|
||||
// |type| currently maps to |id|.
|
||||
@ -437,7 +437,7 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id,
|
||||
spv::StorageClass storage_class) {
|
||||
Type* pointeeTy = GetType(type_id);
|
||||
Pointer pointerTy(pointeeTy, storage_class);
|
||||
if (pointeeTy->IsUniqueType(true)) {
|
||||
if (pointeeTy->IsUniqueType()) {
|
||||
// Non-ambiguous type. Get the pointer type through the type manager.
|
||||
return GetTypeInstruction(&pointerTy);
|
||||
}
|
||||
|
3
3rdparty/spirv-tools/source/opt/types.cpp
vendored
3
3rdparty/spirv-tools/source/opt/types.cpp
vendored
@ -84,10 +84,9 @@ bool Type::HasSameDecorations(const Type* that) const {
|
||||
return CompareTwoVectors(decorations_, that->decorations_);
|
||||
}
|
||||
|
||||
bool Type::IsUniqueType(bool allowVariablePointers) const {
|
||||
bool Type::IsUniqueType() const {
|
||||
switch (kind_) {
|
||||
case kPointer:
|
||||
return !allowVariablePointers;
|
||||
case kStruct:
|
||||
case kArray:
|
||||
case kRuntimeArray:
|
||||
|
14
3rdparty/spirv-tools/source/opt/types.h
vendored
14
3rdparty/spirv-tools/source/opt/types.h
vendored
@ -148,12 +148,16 @@ class Type {
|
||||
// Returns a clone of |this| minus any decorations.
|
||||
std::unique_ptr<Type> RemoveDecorations() const;
|
||||
|
||||
// Returns true if this type must be unique.
|
||||
// Returns true if this cannot hash to the same value as another type in the
|
||||
// module. For example, structs are not unique types because the module could
|
||||
// have two types
|
||||
//
|
||||
// If variable pointers are allowed, then pointers are not required to be
|
||||
// unique.
|
||||
// TODO(alanbaker): Update this if variable pointers become a core feature.
|
||||
bool IsUniqueType(bool allowVariablePointers = false) const;
|
||||
// %1 = OpTypeStruct %int
|
||||
// %2 = OpTypeStruct %int
|
||||
//
|
||||
// The only way to distinguish these types is the result id. The type manager
|
||||
// will hash them to the same value.
|
||||
bool IsUniqueType() const;
|
||||
|
||||
bool operator==(const Type& other) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user