mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-18 04:53:06 +01:00
Updated spirv-tools.
This commit is contained in:
@@ -1 +1 @@
|
||||
"v2020.3-dev", "SPIRV-Tools v2020.3-dev 36e37dd5b53636024ccb44310450d4128dae0842"
|
||||
"v2020.3-dev", "SPIRV-Tools v2020.3-dev 0778398f58d93ce8a861aeeb7a6a60324383525e"
|
||||
|
||||
@@ -124,6 +124,7 @@ SpvStorageClass FuzzerPassDonateModules::AdaptStorageClass(
|
||||
case SpvStorageClassUniform:
|
||||
case SpvStorageClassUniformConstant:
|
||||
case SpvStorageClassPushConstant:
|
||||
case SpvStorageClassImage:
|
||||
// We change these to Private
|
||||
return SpvStorageClassPrivate;
|
||||
default:
|
||||
@@ -721,11 +722,12 @@ bool FuzzerPassDonateModules::CanDonateInstruction(
|
||||
// We do not have a mapped result id for this id operand. That either
|
||||
// means that it is a forward reference (which is OK), that we skipped
|
||||
// the instruction that generated it (which is not OK), or that it is
|
||||
// the id of a function that we did not donate (which is not OK). We
|
||||
// check for the latter two cases.
|
||||
// the id of a function or global value that we did not donate (which
|
||||
// is not OK). We check for the latter two cases.
|
||||
if (skipped_instructions.count(*in_id) ||
|
||||
donor_ir_context->get_def_use_mgr()->GetDef(*in_id)->opcode() ==
|
||||
SpvOpFunction) {
|
||||
// A function or global value does not have an associated basic
|
||||
// block.
|
||||
!donor_ir_context->get_instr_block(*in_id)) {
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class FuzzerPassDonateModules : public FuzzerPass {
|
||||
opt::IRContext* donor_ir_context,
|
||||
std::map<uint32_t, uint32_t>* original_id_to_donated_id);
|
||||
|
||||
// TODO comment
|
||||
// Helper method for HandleTypesAndValues, to handle a single type/value.
|
||||
void HandleTypeOrValue(
|
||||
const opt::Instruction& type_or_value,
|
||||
std::map<uint32_t, uint32_t>* original_id_to_donated_id);
|
||||
|
||||
@@ -218,6 +218,12 @@ bool CanInsertOpcodeBeforeInstruction(
|
||||
}
|
||||
|
||||
bool CanMakeSynonymOf(opt::IRContext* ir_context, opt::Instruction* inst) {
|
||||
if (inst->opcode() == SpvOpSampledImage) {
|
||||
// The SPIR-V data rules say that only very specific instructions may
|
||||
// may consume the result id of an OpSampledImage, and this excludes the
|
||||
// instructions that are used for making synonyms.
|
||||
return false;
|
||||
}
|
||||
if (!inst->HasResultId()) {
|
||||
// We can only make a synonym of an instruction that generates an id.
|
||||
return false;
|
||||
|
||||
@@ -198,10 +198,23 @@ bool TransformationOutlineFunction::IsApplicable(
|
||||
for (auto& block : *entry_block->GetParent()) {
|
||||
if (&block == exit_block) {
|
||||
// It is OK (and typically expected) for the exit block of the region to
|
||||
// have successors outside the region. It is also OK for the exit block
|
||||
// to head a structured control flow construct - the block containing the
|
||||
// call to the outlined function will end up heading this construct if
|
||||
// outlining takes place.
|
||||
// have successors outside the region.
|
||||
//
|
||||
// It is also OK for the exit block to head a structured control flow
|
||||
// construct - the block containing the call to the outlined function will
|
||||
// end up heading this construct if outlining takes place. However, we
|
||||
// must ensure that if the exit block heads a loop, the continue target
|
||||
// for this loop is outside the region.
|
||||
if (auto loop_merge = block.GetLoopMergeInst()) {
|
||||
// The exit block heads a loop
|
||||
auto continue_target =
|
||||
ir_context->cfg()->block(loop_merge->GetSingleWordOperand(1));
|
||||
if (region_set.count(continue_target)) {
|
||||
// The continue target for the loop is in the region.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -274,12 +287,20 @@ bool TransformationOutlineFunction::IsApplicable(
|
||||
}
|
||||
|
||||
// For each region output id -- i.e. every id defined inside the region but
|
||||
// used outside the region -- there needs to be a corresponding fresh id that
|
||||
// can hold the value for this id computed in the outlined function.
|
||||
// used outside the region, ...
|
||||
std::map<uint32_t, uint32_t> output_id_to_fresh_id_map =
|
||||
PairSequenceToMap(message_.output_id_to_fresh_id());
|
||||
for (auto id : GetRegionOutputIds(ir_context, region_set, exit_block)) {
|
||||
if (output_id_to_fresh_id_map.count(id) == 0) {
|
||||
if (
|
||||
// ... there needs to be a corresponding fresh id that can hold the
|
||||
// value for this id computed in the outlined function, and ...
|
||||
output_id_to_fresh_id_map.count(id) == 0
|
||||
// ... the output id must not have pointer type (to avoid creating a
|
||||
// struct with pointer members to pass data out of the outlined
|
||||
// function)
|
||||
|| ir_context->get_def_use_mgr()
|
||||
->GetDef(fuzzerutil::GetTypeId(ir_context, id))
|
||||
->opcode() == SpvOpTypePointer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,9 @@ bool TransformationReplaceIdWithSynonym::UseCanBeReplacedWithSynonym(
|
||||
} else if (composite_type_being_accessed->AsArray()) {
|
||||
composite_type_being_accessed =
|
||||
composite_type_being_accessed->AsArray()->element_type();
|
||||
} else if (composite_type_being_accessed->AsRuntimeArray()) {
|
||||
composite_type_being_accessed =
|
||||
composite_type_being_accessed->AsRuntimeArray()->element_type();
|
||||
} else {
|
||||
assert(composite_type_being_accessed->AsStruct());
|
||||
auto constant_index_instruction = ir_context->get_def_use_mgr()->GetDef(
|
||||
|
||||
@@ -76,8 +76,34 @@ bool TransformationSplitBlock::IsApplicable(
|
||||
}
|
||||
// We cannot split before an OpPhi unless the OpPhi has exactly one
|
||||
// associated incoming edge.
|
||||
return !(split_before->opcode() == SpvOpPhi &&
|
||||
split_before->NumInOperands() != 2);
|
||||
if (split_before->opcode() == SpvOpPhi &&
|
||||
split_before->NumInOperands() != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Splitting the block must not separate the definition of an OpSampledImage
|
||||
// from its use: the SPIR-V data rules require them to be in the same block.
|
||||
std::set<uint32_t> sampled_image_result_ids;
|
||||
bool before_split = true;
|
||||
for (auto& instruction : *block_to_split) {
|
||||
if (&instruction == &*split_before) {
|
||||
before_split = false;
|
||||
}
|
||||
if (before_split) {
|
||||
if (instruction.opcode() == SpvOpSampledImage) {
|
||||
sampled_image_result_ids.insert(instruction.result_id());
|
||||
}
|
||||
} else {
|
||||
if (!instruction.WhileEachInId(
|
||||
[&sampled_image_result_ids](uint32_t* id) -> bool {
|
||||
return !sampled_image_result_ids.count(*id);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TransformationSplitBlock::Apply(
|
||||
|
||||
@@ -78,6 +78,8 @@ void FeatureManager::AddCapabilities(Module* module) {
|
||||
|
||||
void FeatureManager::AddExtInstImportIds(Module* module) {
|
||||
extinst_importid_GLSLstd450_ = module->GetExtInstImportId("GLSL.std.450");
|
||||
extinst_importid_OpenCL100DebugInfo_ =
|
||||
module->GetExtInstImportId("OpenCL.DebugInfo.100");
|
||||
}
|
||||
|
||||
bool operator==(const FeatureManager& a, const FeatureManager& b) {
|
||||
@@ -100,6 +102,11 @@ bool operator==(const FeatureManager& a, const FeatureManager& b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.extinst_importid_OpenCL100DebugInfo_ !=
|
||||
b.extinst_importid_OpenCL100DebugInfo_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace opt
|
||||
|
||||
@@ -51,6 +51,10 @@ class FeatureManager {
|
||||
return extinst_importid_GLSLstd450_;
|
||||
}
|
||||
|
||||
uint32_t GetExtInstImportId_OpenCL100DebugInfo() const {
|
||||
return extinst_importid_OpenCL100DebugInfo_;
|
||||
}
|
||||
|
||||
friend bool operator==(const FeatureManager& a, const FeatureManager& b);
|
||||
friend bool operator!=(const FeatureManager& a, const FeatureManager& b) {
|
||||
return !(a == b);
|
||||
@@ -84,6 +88,10 @@ class FeatureManager {
|
||||
|
||||
// Common external instruction import ids, cached for performance.
|
||||
uint32_t extinst_importid_GLSLstd450_ = 0;
|
||||
|
||||
// Common OpenCL100DebugInfo external instruction import ids, cached
|
||||
// for performance.
|
||||
uint32_t extinst_importid_OpenCL100DebugInfo_ = 0;
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
|
||||
13
3rdparty/spirv-tools/source/opt/function.cpp
vendored
13
3rdparty/spirv-tools/source/opt/function.cpp
vendored
@@ -84,9 +84,12 @@ bool Function::WhileEachInst(const std::function<bool(Instruction*)>& f,
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& di : debug_insts_in_header_) {
|
||||
if (!di.WhileEachInst(f, run_on_debug_line_insts)) {
|
||||
return false;
|
||||
if (!debug_insts_in_header_.empty()) {
|
||||
Instruction* di = &debug_insts_in_header_.front();
|
||||
while (di != nullptr) {
|
||||
Instruction* next_instruction = di->NextNode();
|
||||
if (!di->WhileEachInst(f, run_on_debug_line_insts)) return false;
|
||||
di = next_instruction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,9 +121,9 @@ bool Function::WhileEachInst(const std::function<bool(const Instruction*)>& f,
|
||||
}
|
||||
|
||||
for (const auto& di : debug_insts_in_header_) {
|
||||
if (!di.WhileEachInst(f, run_on_debug_line_insts)) {
|
||||
if (!static_cast<const Instruction*>(&di)->WhileEachInst(
|
||||
f, run_on_debug_line_insts))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& bb : blocks_) {
|
||||
|
||||
@@ -802,8 +802,11 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer(
|
||||
opt::Instruction* image_texel_pointer) {
|
||||
// TODO(dneto): Write tests for this code.
|
||||
// TODO(dneto): Use signed-clamp
|
||||
(void)(image_texel_pointer);
|
||||
return SPV_SUCCESS;
|
||||
|
||||
// Do not compile this code until it is ready to be used.
|
||||
#if 0
|
||||
// Example:
|
||||
// %texel_ptr = OpImageTexelPointer %texel_ptr_type %image_ptr %coord
|
||||
// %sample
|
||||
@@ -1035,6 +1038,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer(
|
||||
def_use_mgr->AnalyzeInstUse(image_texel_pointer);
|
||||
|
||||
return SPV_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
opt::Instruction* GraphicsRobustAccessPass::InsertInst(
|
||||
|
||||
41
3rdparty/spirv-tools/source/opt/instruction.cpp
vendored
41
3rdparty/spirv-tools/source/opt/instruction.cpp
vendored
@@ -33,6 +33,8 @@ const uint32_t kVariableStorageClassIndex = 0;
|
||||
const uint32_t kTypeImageSampledIndex = 5;
|
||||
|
||||
// Constants for OpenCL.DebugInfo.100 extension instructions.
|
||||
const uint32_t kExtInstSetIdInIdx = 0;
|
||||
const uint32_t kExtInstInstructionInIdx = 1;
|
||||
const uint32_t kDebugScopeNumWords = 7;
|
||||
const uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6;
|
||||
const uint32_t kDebugNoScopeNumWords = 5;
|
||||
@@ -180,10 +182,27 @@ void Instruction::ReplaceOperands(const OperandList& new_operands) {
|
||||
bool Instruction::IsReadOnlyLoad() const {
|
||||
if (IsLoad()) {
|
||||
Instruction* address_def = GetBaseAddress();
|
||||
if (!address_def || address_def->opcode() != SpvOpVariable) {
|
||||
if (!address_def) {
|
||||
return false;
|
||||
}
|
||||
return address_def->IsReadOnlyVariable();
|
||||
|
||||
if (address_def->opcode() == SpvOpVariable) {
|
||||
if (address_def->IsReadOnlyVariable()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (address_def->opcode() == SpvOpLoad) {
|
||||
const analysis::Type* address_type =
|
||||
context()->get_type_mgr()->GetType(address_def->type_id());
|
||||
if (address_type->AsSampledImage() != nullptr) {
|
||||
const auto* image_type =
|
||||
address_type->AsSampledImage()->image_type()->AsImage();
|
||||
if (image_type->sampled() == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -510,6 +529,21 @@ bool Instruction::IsValidBasePointer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const {
|
||||
if (opcode() != SpvOpExtInst) return OpenCLDebugInfo100InstructionsMax;
|
||||
|
||||
if (!context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo())
|
||||
return OpenCLDebugInfo100InstructionsMax;
|
||||
|
||||
if (GetSingleWordInOperand(kExtInstSetIdInIdx) !=
|
||||
context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) {
|
||||
return OpenCLDebugInfo100InstructionsMax;
|
||||
}
|
||||
|
||||
return OpenCLDebugInfo100Instructions(
|
||||
GetSingleWordInOperand(kExtInstInstructionInIdx));
|
||||
}
|
||||
|
||||
bool Instruction::IsValidBaseImage() const {
|
||||
uint32_t tid = type_id();
|
||||
if (tid == 0) {
|
||||
@@ -714,9 +748,6 @@ bool Instruction::IsScalarizable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t kExtInstSetIdInIdx = 0;
|
||||
const uint32_t kExtInstInstructionInIdx = 1;
|
||||
|
||||
if (opcode() == SpvOpExtInst) {
|
||||
uint32_t instSetId =
|
||||
context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450();
|
||||
|
||||
15
3rdparty/spirv-tools/source/opt/instruction.h
vendored
15
3rdparty/spirv-tools/source/opt/instruction.h
vendored
@@ -22,14 +22,14 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "source/opcode.h"
|
||||
#include "source/operand.h"
|
||||
#include "source/util/ilist_node.h"
|
||||
#include "source/util/small_vector.h"
|
||||
|
||||
#include "OpenCLDebugInfo100.h"
|
||||
#include "source/latest_version_glsl_std_450_header.h"
|
||||
#include "source/latest_version_spirv_header.h"
|
||||
#include "source/opcode.h"
|
||||
#include "source/operand.h"
|
||||
#include "source/opt/reflect.h"
|
||||
#include "source/util/ilist_node.h"
|
||||
#include "source/util/small_vector.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
const uint32_t kNoDebugScope = 0;
|
||||
@@ -496,6 +496,11 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
// rules for physical addressing.
|
||||
bool IsValidBasePointer() const;
|
||||
|
||||
// Returns debug opcode of an OpenCL.100.DebugInfo instruction. If
|
||||
// it is not an OpenCL.100.DebugInfo instruction, just returns
|
||||
// OpenCLDebugInfo100InstructionsMax.
|
||||
OpenCLDebugInfo100Instructions GetOpenCL100DebugOpcode() const;
|
||||
|
||||
// Dump this instruction on stderr. Useful when running interactive
|
||||
// debuggers.
|
||||
void Dump() const;
|
||||
|
||||
65
3rdparty/spirv-tools/source/opt/ir_context.cpp
vendored
65
3rdparty/spirv-tools/source/opt/ir_context.cpp
vendored
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "OpenCLDebugInfo100.h"
|
||||
#include "source/latest_version_glsl_std_450_header.h"
|
||||
#include "source/opt/log.h"
|
||||
#include "source/opt/mem_pass.h"
|
||||
@@ -29,6 +30,10 @@ static const int kSpvDecorateBuiltinInIdx = 2;
|
||||
static const int kEntryPointInterfaceInIdx = 3;
|
||||
static const int kEntryPointFunctionIdInIdx = 1;
|
||||
|
||||
// Constants for OpenCL.DebugInfo.100 extension instructions.
|
||||
static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
|
||||
static const uint32_t kDebugGlobalVariableOperandVariableIndex = 11;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace spvtools {
|
||||
@@ -153,6 +158,8 @@ Instruction* IRContext::KillInst(Instruction* inst) {
|
||||
|
||||
KillNamesAndDecorates(inst);
|
||||
|
||||
KillOperandFromDebugInstructions(inst);
|
||||
|
||||
if (AreAnalysesValid(kAnalysisDefUse)) {
|
||||
get_def_use_mgr()->ClearInst(inst);
|
||||
}
|
||||
@@ -265,7 +272,7 @@ bool IRContext::ReplaceAllUsesWithPredicate(
|
||||
bool IRContext::IsConsistent() {
|
||||
#ifndef SPIRV_CHECK_CONTEXT
|
||||
return true;
|
||||
#endif
|
||||
#else
|
||||
if (AreAnalysesValid(kAnalysisDefUse)) {
|
||||
analysis::DefUseManager new_def_use(module());
|
||||
if (*get_def_use_mgr() != new_def_use) {
|
||||
@@ -317,6 +324,7 @@ bool IRContext::IsConsistent() {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRContext::ForgetUses(Instruction* inst) {
|
||||
@@ -365,6 +373,61 @@ void IRContext::KillNamesAndDecorates(Instruction* inst) {
|
||||
KillNamesAndDecorates(rId);
|
||||
}
|
||||
|
||||
Instruction* IRContext::GetOpenCL100DebugInfoNone() {
|
||||
if (debug_info_none_inst_) return debug_info_none_inst_;
|
||||
assert(get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo() &&
|
||||
"Module does not include debug info extension instruction.");
|
||||
|
||||
// Create a new DebugInfoNone.
|
||||
std::unique_ptr<Instruction> dbg_info_none(new Instruction(
|
||||
this, SpvOpExtInst, get_type_mgr()->GetVoidTypeId(), TakeNextId(),
|
||||
{
|
||||
{SPV_OPERAND_TYPE_RESULT_ID,
|
||||
{get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()}},
|
||||
{SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
|
||||
{static_cast<uint32_t>(OpenCLDebugInfo100DebugInfoNone)}},
|
||||
}));
|
||||
|
||||
// Add to the front of |ext_inst_debuginfo_|.
|
||||
debug_info_none_inst_ = module()->ext_inst_debuginfo_begin()->InsertBefore(
|
||||
std::move(dbg_info_none));
|
||||
return debug_info_none_inst_;
|
||||
}
|
||||
|
||||
void IRContext::KillOperandFromDebugInstructions(Instruction* inst) {
|
||||
const auto opcode = inst->opcode();
|
||||
const uint32_t id = inst->result_id();
|
||||
// Kill id of OpFunction from DebugFunction.
|
||||
if (opcode == SpvOpFunction) {
|
||||
for (auto it = module()->ext_inst_debuginfo_begin();
|
||||
it != module()->ext_inst_debuginfo_end(); ++it) {
|
||||
if (it->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugFunction)
|
||||
continue;
|
||||
auto& operand = it->GetOperand(kDebugFunctionOperandFunctionIndex);
|
||||
if (operand.words[0] == id) {
|
||||
operand.words[0] = GetOpenCL100DebugInfoNone()->result_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Kill id of OpVariable for global variable from DebugGlobalVariable.
|
||||
if (opcode == SpvOpVariable || IsConstantInst(opcode)) {
|
||||
for (auto it = module()->ext_inst_debuginfo_begin();
|
||||
it != module()->ext_inst_debuginfo_end(); ++it) {
|
||||
if (it->GetOpenCL100DebugOpcode() !=
|
||||
OpenCLDebugInfo100DebugGlobalVariable)
|
||||
continue;
|
||||
auto& operand = it->GetOperand(kDebugGlobalVariableOperandVariableIndex);
|
||||
if (operand.words[0] == id) {
|
||||
operand.words[0] = GetOpenCL100DebugInfoNone()->result_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Notice that we do not need anythings to do for local variables.
|
||||
// DebugLocalVariable does not have an OpVariable operand. Instead,
|
||||
// DebugDeclare/DebugValue has an OpVariable operand for a local
|
||||
// variable. The function inlining pass handles it properly.
|
||||
}
|
||||
|
||||
void IRContext::AddCombinatorsForCapability(uint32_t capability) {
|
||||
if (capability == SpvCapabilityShader) {
|
||||
combinator_ops_[0].insert({SpvOpNop,
|
||||
|
||||
16
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
16
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
@@ -102,7 +102,8 @@ class IRContext {
|
||||
id_to_name_(nullptr),
|
||||
max_id_bound_(kDefaultMaxIdBound),
|
||||
preserve_bindings_(false),
|
||||
preserve_spec_constants_(false) {
|
||||
preserve_spec_constants_(false),
|
||||
debug_info_none_inst_(nullptr) {
|
||||
SetContextMessageConsumer(syntax_context_, consumer_);
|
||||
module_->SetContext(this);
|
||||
}
|
||||
@@ -119,7 +120,8 @@ class IRContext {
|
||||
id_to_name_(nullptr),
|
||||
max_id_bound_(kDefaultMaxIdBound),
|
||||
preserve_bindings_(false),
|
||||
preserve_spec_constants_(false) {
|
||||
preserve_spec_constants_(false),
|
||||
debug_info_none_inst_(nullptr) {
|
||||
SetContextMessageConsumer(syntax_context_, consumer_);
|
||||
module_->SetContext(this);
|
||||
InitializeCombinators();
|
||||
@@ -426,6 +428,9 @@ class IRContext {
|
||||
// Kill all name and decorate ops targeting the result id of |inst|.
|
||||
void KillNamesAndDecorates(Instruction* inst);
|
||||
|
||||
// Change operands of debug instruction to DebugInfoNone.
|
||||
void KillOperandFromDebugInstructions(Instruction* inst);
|
||||
|
||||
// Returns the next unique id for use by an instruction.
|
||||
inline uint32_t TakeNextUniqueId() {
|
||||
assert(unique_id_ != std::numeric_limits<uint32_t>::max());
|
||||
@@ -705,6 +710,9 @@ class IRContext {
|
||||
// Add |var_id| to all entry points in module.
|
||||
void AddVarToEntryPoints(uint32_t var_id);
|
||||
|
||||
// Get the existing DebugInfoNone. If it is null, create one and keep it.
|
||||
Instruction* GetOpenCL100DebugInfoNone();
|
||||
|
||||
// The SPIR-V syntax context containing grammar tables for opcodes and
|
||||
// operands.
|
||||
spv_context syntax_context_;
|
||||
@@ -798,6 +806,10 @@ class IRContext {
|
||||
// Whether all specialization constants within |module_|
|
||||
// should be preserved.
|
||||
bool preserve_spec_constants_;
|
||||
|
||||
// DebugInfoNone instruction. We need only a single DebugInfoNone.
|
||||
// To reuse the existing one, we keep it using this member variable.
|
||||
Instruction* debug_info_none_inst_;
|
||||
};
|
||||
|
||||
inline IRContext::Analysis operator|(IRContext::Analysis lhs,
|
||||
|
||||
@@ -498,7 +498,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
|
||||
} else if (pass_name == "legalize-vector-shuffle") {
|
||||
RegisterPass(CreateLegalizeVectorShufflePass());
|
||||
} else if (pass_name == "split-invalid-unreachable") {
|
||||
RegisterPass(CreateLegalizeVectorShufflePass());
|
||||
RegisterPass(CreateSplitInvalidUnreachablePass());
|
||||
} else if (pass_name == "decompose-initialized-variables") {
|
||||
RegisterPass(CreateDecomposeInitializedVariablesPass());
|
||||
} else if (pass_name == "graphics-robust-access") {
|
||||
|
||||
@@ -85,9 +85,14 @@ void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) {
|
||||
if (merge_inst->opcode() == SpvOpLoopMerge) {
|
||||
new_state.cinfo.containing_loop = block->id();
|
||||
new_state.cinfo.containing_switch = 0;
|
||||
new_state.cinfo.in_continue = false;
|
||||
new_state.continue_node =
|
||||
merge_inst->GetSingleWordInOperand(kContinueNodeIndex);
|
||||
if (block->id() == new_state.continue_node) {
|
||||
new_state.cinfo.in_continue = true;
|
||||
bb_to_construct_[block->id()].in_continue = true;
|
||||
} else {
|
||||
new_state.cinfo.in_continue = false;
|
||||
}
|
||||
} else {
|
||||
new_state.cinfo.containing_loop = state.back().cinfo.containing_loop;
|
||||
new_state.cinfo.in_continue = state.back().cinfo.in_continue;
|
||||
|
||||
@@ -194,6 +194,13 @@ class TypeManager {
|
||||
|
||||
uint32_t GetBoolTypeId() { return GetTypeInstruction(GetBoolType()); }
|
||||
|
||||
Type* GetVoidType() {
|
||||
Void void_type;
|
||||
return GetRegisteredType(&void_type);
|
||||
}
|
||||
|
||||
uint32_t GetVoidTypeId() { return GetTypeInstruction(GetVoidType()); }
|
||||
|
||||
private:
|
||||
using TypeToIdMap = std::unordered_map<const Type*, uint32_t, HashTypePointer,
|
||||
CompareTypePointers>;
|
||||
|
||||
@@ -1090,8 +1090,9 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) {
|
||||
return _.diag(SPV_ERROR_INVALID_CFG, inst)
|
||||
<< "OpReturn can only be called from a function with void "
|
||||
<< "return type.";
|
||||
_.current_function().RegisterBlockEnd(std::vector<uint32_t>(), opcode);
|
||||
break;
|
||||
}
|
||||
// Fallthrough.
|
||||
case SpvOpKill:
|
||||
case SpvOpReturnValue:
|
||||
case SpvOpUnreachable:
|
||||
|
||||
Reference in New Issue
Block a user