mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Propagate OpLine to all applied instructions in spirv-opt (#3951)
Based on the OpLine spec, an OpLine instruction must be applied to the instructions physically following it up to the first occurrence of the next end of block, the next OpLine instruction, or the next OpNoLine instruction. ``` OpLine %file 0 0 OpNoLine OpLine %file 1 1 OpStore %foo %int_1 %value = OpLoad %int %foo OpLine %file 2 2 ``` For the above code, the current spirv-opt keeps three line instructions `OpLine %file 0 0`, `OpNoLine`, and `OpLine %file 1 1` in `std::vector<Instruction> dbg_line_insts_` of Instruction class for `OpStore %foo %int_1`. It does not put any line instruction to `std::vector<Instruction> dbg_line_insts_` of `%value = OpLoad %int %foo` even though `OpLine %file 1 1` must be applied to `%value = OpLoad %int %foo` based on the spec. This results in the missing line information for `%value = OpLoad %int %foo` while each spirv-opt pass optimizes the code. We have to put `OpLine %file 1 1` to `std::vector<Instruction> dbg_line_insts_` of both `%value = OpLoad %int %foo` and `OpStore %foo %int_1`. This commit conducts the line instruction propagation and skips emitting the eliminated line instructions at the end, which are the same with PropagateLineInfoPass and RedundantLineInfoElimPass. This commit removes PropagateLineInfoPass and RedundantLineInfoElimPass. KhronosGroup/glslang#2440 is a related PR that stop using PropagateLineInfoPass and RedundantLineInfoElimPass from glslang. When the code in this PR applied, the glslang tests will pass.
This commit is contained in:
parent
7403dfafd8
commit
56d0f50357
@ -149,7 +149,6 @@ SPVTOOLS_OPT_SRC_FILES := \
|
||||
source/opt/pass.cpp \
|
||||
source/opt/pass_manager.cpp \
|
||||
source/opt/private_to_local_pass.cpp \
|
||||
source/opt/process_lines_pass.cpp \
|
||||
source/opt/propagator.cpp \
|
||||
source/opt/reduce_load_size.cpp \
|
||||
source/opt/redundancy_elimination.cpp \
|
||||
|
2
BUILD.gn
2
BUILD.gn
@ -654,8 +654,6 @@ static_library("spvtools_opt") {
|
||||
"source/opt/passes.h",
|
||||
"source/opt/private_to_local_pass.cpp",
|
||||
"source/opt/private_to_local_pass.h",
|
||||
"source/opt/process_lines_pass.cpp",
|
||||
"source/opt/process_lines_pass.h",
|
||||
"source/opt/propagator.cpp",
|
||||
"source/opt/propagator.h",
|
||||
"source/opt/reduce_load_size.cpp",
|
||||
|
@ -536,30 +536,6 @@ Optimizer::PassToken CreateDeadInsertElimPass();
|
||||
// eliminated with standard dead code elimination.
|
||||
Optimizer::PassToken CreateAggressiveDCEPass();
|
||||
|
||||
// Create line propagation pass
|
||||
// This pass propagates line information based on the rules for OpLine and
|
||||
// OpNoline and clones an appropriate line instruction into every instruction
|
||||
// which does not already have debug line instructions.
|
||||
//
|
||||
// This pass is intended to maximize preservation of source line information
|
||||
// through passes which delete, move and clone instructions. Ideally it should
|
||||
// be run before any such pass. It is a bookend pass with EliminateDeadLines
|
||||
// which can be used to remove redundant line instructions at the end of a
|
||||
// run of such passes and reduce final output file size.
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass();
|
||||
|
||||
// Create dead line elimination pass
|
||||
// This pass eliminates redundant line instructions based on the rules for
|
||||
// OpLine and OpNoline. Its main purpose is to reduce the size of the file
|
||||
// need to store the SPIR-V without losing line information.
|
||||
//
|
||||
// This is a bookend pass with PropagateLines which attaches line instructions
|
||||
// to every instruction to preserve line information during passes which
|
||||
// delete, move and clone instructions. DeadLineElim should be run after
|
||||
// PropagateLines and all such subsequent passes. Normally it would be one
|
||||
// of the last passes to be run.
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass();
|
||||
|
||||
// Creates a compact ids pass.
|
||||
// The pass remaps result ids to a compact and gapless range starting from %1.
|
||||
Optimizer::PassToken CreateCompactIdsPass();
|
||||
|
@ -89,7 +89,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.h
|
||||
pass_manager.h
|
||||
private_to_local_pass.h
|
||||
process_lines_pass.h
|
||||
propagator.h
|
||||
reduce_load_size.h
|
||||
redundancy_elimination.h
|
||||
@ -196,7 +195,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.cpp
|
||||
pass_manager.cpp
|
||||
private_to_local_pass.cpp
|
||||
process_lines_pass.cpp
|
||||
propagator.cpp
|
||||
reduce_load_size.cpp
|
||||
redundancy_elimination.cpp
|
||||
|
@ -41,6 +41,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
++inst_index_;
|
||||
const auto opcode = static_cast<SpvOp>(inst->opcode);
|
||||
if (IsDebugLineInst(opcode)) {
|
||||
last_line_inst_.reset();
|
||||
dbg_line_info_.push_back(
|
||||
Instruction(module()->context(), *inst, last_dbg_scope_));
|
||||
return true;
|
||||
@ -90,7 +91,16 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
|
||||
std::unique_ptr<Instruction> spv_inst(
|
||||
new Instruction(module()->context(), *inst, std::move(dbg_line_info_)));
|
||||
if (!spv_inst->dbg_line_insts().empty()) {
|
||||
if (spv_inst->dbg_line_insts().back().opcode() != SpvOpNoLine) {
|
||||
last_line_inst_ = std::unique_ptr<Instruction>(
|
||||
spv_inst->dbg_line_insts().back().Clone(module()->context()));
|
||||
}
|
||||
dbg_line_info_.clear();
|
||||
} else if (last_line_inst_ != nullptr) {
|
||||
last_line_inst_->SetDebugScope(last_dbg_scope_);
|
||||
spv_inst->dbg_line_insts().push_back(*last_line_inst_);
|
||||
}
|
||||
|
||||
const char* src = source_.c_str();
|
||||
spv_position_t loc = {inst_index_, 0, 0};
|
||||
@ -141,6 +151,8 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
function_->AddBasicBlock(std::move(block_));
|
||||
block_ = nullptr;
|
||||
last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt);
|
||||
last_line_inst_.reset();
|
||||
dbg_line_info_.clear();
|
||||
} else {
|
||||
if (function_ == nullptr) { // Outside function definition
|
||||
SPIRV_ASSERT(consumer_, block_ == nullptr);
|
||||
|
@ -78,6 +78,8 @@ class IrLoader {
|
||||
std::unique_ptr<BasicBlock> block_;
|
||||
// Line related debug instructions accumulated thus far.
|
||||
std::vector<Instruction> dbg_line_info_;
|
||||
// Line instruction that should be applied to the next instruction.
|
||||
std::unique_ptr<Instruction> last_line_inst_;
|
||||
|
||||
// The last DebugScope information that IrLoader::AddInstruction() handled.
|
||||
DebugScope last_dbg_scope_;
|
||||
|
@ -143,8 +143,38 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
|
||||
|
||||
size_t bound_idx = binary->size() - 2;
|
||||
DebugScope last_scope(kNoDebugScope, kNoInlinedAt);
|
||||
auto write_inst = [binary, skip_nop, &last_scope,
|
||||
this](const Instruction* i) {
|
||||
const Instruction* last_line_inst = nullptr;
|
||||
bool between_merge_and_branch = false;
|
||||
auto write_inst = [binary, skip_nop, &last_scope, &last_line_inst,
|
||||
&between_merge_and_branch, this](const Instruction* i) {
|
||||
// Skip emitting line instructions between merge and branch instructions.
|
||||
auto opcode = i->opcode();
|
||||
if (between_merge_and_branch &&
|
||||
(opcode == SpvOpLine || opcode == SpvOpNoLine)) {
|
||||
return;
|
||||
}
|
||||
between_merge_and_branch = false;
|
||||
if (last_line_inst != nullptr) {
|
||||
// If the current instruction is OpLine and it is the same with
|
||||
// the last line instruction that is still effective (can be applied
|
||||
// to the next instruction), we skip writing the current instruction.
|
||||
if (opcode == SpvOpLine) {
|
||||
uint32_t operand_index = 0;
|
||||
if (last_line_inst->WhileEachInOperand(
|
||||
[&operand_index, i](const uint32_t* word) {
|
||||
assert(i->NumInOperandWords() > operand_index);
|
||||
return *word == i->GetSingleWordInOperand(operand_index++);
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
} else if (opcode != SpvOpNoLine && i->dbg_line_insts().empty()) {
|
||||
// If the current instruction does not have the line information,
|
||||
// the last line information is not effective any more. Emit OpNoLine
|
||||
// to specify it.
|
||||
binary->push_back((1 << 16) | static_cast<uint16_t>(SpvOpNoLine));
|
||||
last_line_inst = nullptr;
|
||||
}
|
||||
}
|
||||
if (!(skip_nop && i->IsNop())) {
|
||||
const auto& scope = i->GetDebugScope();
|
||||
if (scope != last_scope) {
|
||||
@ -157,6 +187,15 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
|
||||
|
||||
i->ToBinaryWithoutAttachedDebugInsts(binary);
|
||||
}
|
||||
// Update the last line instruction.
|
||||
if (IsTerminatorInst(opcode) || opcode == SpvOpNoLine) {
|
||||
last_line_inst = nullptr;
|
||||
} else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
|
||||
between_merge_and_branch = true;
|
||||
last_line_inst = nullptr;
|
||||
} else if (opcode == SpvOpLine) {
|
||||
last_line_inst = i;
|
||||
}
|
||||
};
|
||||
ForEachInst(write_inst, true);
|
||||
|
||||
|
@ -246,6 +246,12 @@ class Module {
|
||||
// If |skip_nop| is true and this is a OpNop, do nothing.
|
||||
void ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const;
|
||||
|
||||
// Pushes the binary segments for this instruction into the back of *|binary|
|
||||
// including all OpLine and OpNoLine even if we can skip emitting some line
|
||||
// instructions. If |skip_nop| is true and this is a OpNop, do nothing.
|
||||
void ToBinaryWithAllOpLines(std::vector<uint32_t>* binary,
|
||||
bool skip_nop) const;
|
||||
|
||||
// Returns 1 more than the maximum Id value mentioned in the module.
|
||||
uint32_t ComputeIdBound() const;
|
||||
|
||||
|
@ -339,10 +339,6 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
|
||||
RegisterPass(CreateDescriptorScalarReplacementPass());
|
||||
} else if (pass_name == "eliminate-dead-code-aggressive") {
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
} else if (pass_name == "propagate-line-info") {
|
||||
RegisterPass(CreatePropagateLineInfoPass());
|
||||
} else if (pass_name == "eliminate-redundant-line-info") {
|
||||
RegisterPass(CreateRedundantLineInfoElimPass());
|
||||
} else if (pass_name == "eliminate-insert-extract") {
|
||||
RegisterPass(CreateInsertExtractElimPass());
|
||||
} else if (pass_name == "eliminate-local-single-block") {
|
||||
@ -757,16 +753,6 @@ Optimizer::PassToken CreateAggressiveDCEPass() {
|
||||
MakeUnique<opt::AggressiveDCEPass>());
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesPropagateLines));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesEliminateDeadLines));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateCompactIdsPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::CompactIdsPass>());
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include "source/opt/merge_return_pass.h"
|
||||
#include "source/opt/null_pass.h"
|
||||
#include "source/opt/private_to_local_pass.h"
|
||||
#include "source/opt/process_lines_pass.h"
|
||||
#include "source/opt/reduce_load_size.h"
|
||||
#include "source/opt/redundancy_elimination.h"
|
||||
#include "source/opt/relax_float_ops_pass.h"
|
||||
|
@ -1,157 +0,0 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// 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/opt/process_lines_pass.h"
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// Input Operand Indices
|
||||
static const int kSpvLineFileInIdx = 0;
|
||||
static const int kSpvLineLineInIdx = 1;
|
||||
static const int kSpvLineColInIdx = 2;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
Pass::Status ProcessLinesPass::Process() {
|
||||
bool modified = ProcessLines();
|
||||
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::ProcessLines() {
|
||||
bool modified = false;
|
||||
uint32_t file_id = 0;
|
||||
uint32_t line = 0;
|
||||
uint32_t col = 0;
|
||||
// Process types, globals, constants
|
||||
for (Instruction& inst : get_module()->types_values())
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Process functions
|
||||
for (Function& function : *get_module()) {
|
||||
modified |= line_process_func_(&function.DefInst(), &file_id, &line, &col);
|
||||
function.ForEachParam(
|
||||
[this, &modified, &file_id, &line, &col](Instruction* param) {
|
||||
modified |= line_process_func_(param, &file_id, &line, &col);
|
||||
});
|
||||
for (BasicBlock& block : function) {
|
||||
modified |=
|
||||
line_process_func_(block.GetLabelInst(), &file_id, &line, &col);
|
||||
for (Instruction& inst : block) {
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Don't process terminal instruction if preceeded by merge
|
||||
if (inst.opcode() == SpvOpSelectionMerge ||
|
||||
inst.opcode() == SpvOpLoopMerge)
|
||||
break;
|
||||
}
|
||||
// Nullify line info after each block.
|
||||
file_id = 0;
|
||||
}
|
||||
modified |= line_process_func_(function.EndInst(), &file_id, &line, &col);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::PropagateLine(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
bool modified = false;
|
||||
// only the last debug instruction needs to be considered
|
||||
auto line_itr = inst->dbg_line_insts().rbegin();
|
||||
// if no line instructions, propagate previous info
|
||||
if (line_itr == inst->dbg_line_insts().rend()) {
|
||||
// if no current line info, add OpNoLine, else OpLine
|
||||
if (*file_id == 0)
|
||||
inst->dbg_line_insts().push_back(Instruction(context(), SpvOpNoLine));
|
||||
else
|
||||
inst->dbg_line_insts().push_back(Instruction(
|
||||
context(), SpvOpLine, 0, 0,
|
||||
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*file_id}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*line}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*col}}}));
|
||||
modified = true;
|
||||
} else {
|
||||
// else pre-existing line instruction, so update source line info
|
||||
if (line_itr->opcode() == SpvOpNoLine) {
|
||||
*file_id = 0;
|
||||
} else {
|
||||
assert(line_itr->opcode() == SpvOpLine && "unexpected debug inst");
|
||||
*file_id = line_itr->GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = line_itr->GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = line_itr->GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::EliminateDeadLines(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
// If no debug line instructions, return without modifying lines
|
||||
if (inst->dbg_line_insts().empty()) return false;
|
||||
// Only the last debug instruction needs to be considered; delete all others
|
||||
bool modified = inst->dbg_line_insts().size() > 1;
|
||||
Instruction last_inst = inst->dbg_line_insts().back();
|
||||
inst->dbg_line_insts().clear();
|
||||
// If last line is OpNoLine
|
||||
if (last_inst.opcode() == SpvOpNoLine) {
|
||||
// If no propagated line info, throw away redundant OpNoLine
|
||||
if (*file_id == 0) {
|
||||
modified = true;
|
||||
// Else replace OpNoLine and propagate no line info
|
||||
} else {
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
*file_id = 0;
|
||||
}
|
||||
} else {
|
||||
// Else last line is OpLine
|
||||
assert(last_inst.opcode() == SpvOpLine && "unexpected debug inst");
|
||||
// If propagated info matches last line, throw away last line
|
||||
if (*file_id == last_inst.GetSingleWordInOperand(kSpvLineFileInIdx) &&
|
||||
*line == last_inst.GetSingleWordInOperand(kSpvLineLineInIdx) &&
|
||||
*col == last_inst.GetSingleWordInOperand(kSpvLineColInIdx)) {
|
||||
modified = true;
|
||||
} else {
|
||||
// Else replace last line and propagate line info
|
||||
*file_id = last_inst.GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = last_inst.GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = last_inst.GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
ProcessLinesPass::ProcessLinesPass(uint32_t func_id) {
|
||||
if (func_id == kLinesPropagateLines) {
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return PropagateLine(inst, file_id, line, col);
|
||||
};
|
||||
} else {
|
||||
assert(func_id == kLinesEliminateDeadLines && "unknown Lines param");
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return EliminateDeadLines(inst, file_id, line, col);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
@ -1,87 +0,0 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// 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_OPT_PROPAGATE_LINES_PASS_H_
|
||||
#define SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
|
||||
#include "source/opt/function.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
namespace {
|
||||
|
||||
// Constructor Parameters
|
||||
static const int kLinesPropagateLines = 0;
|
||||
static const int kLinesEliminateDeadLines = 1;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// See optimizer.hpp for documentation.
|
||||
class ProcessLinesPass : public Pass {
|
||||
using LineProcessFunction =
|
||||
std::function<bool(Instruction*, uint32_t*, uint32_t*, uint32_t*)>;
|
||||
|
||||
public:
|
||||
ProcessLinesPass(uint32_t func_id);
|
||||
~ProcessLinesPass() override = default;
|
||||
|
||||
const char* name() const override { return "propagate-lines"; }
|
||||
|
||||
// See optimizer.hpp for this pass' user documentation.
|
||||
Status Process() override;
|
||||
|
||||
IRContext::Analysis GetPreservedAnalyses() override {
|
||||
return IRContext::kAnalysisDefUse |
|
||||
IRContext::kAnalysisInstrToBlockMapping |
|
||||
IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
|
||||
IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
|
||||
IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants |
|
||||
IRContext::kAnalysisTypes;
|
||||
}
|
||||
|
||||
private:
|
||||
// If |inst| has no debug line instruction, create one with
|
||||
// |file_id, line, col|. If |inst| has debug line instructions, set
|
||||
// |file_id, line, col| from the last. |file_id| equals 0 indicates no line
|
||||
// info is available. Return true if |inst| modified.
|
||||
bool PropagateLine(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// If last debug line instruction of |inst| matches |file_id, line, col|,
|
||||
// delete all debug line instructions of |inst|. If they do not match,
|
||||
// replace all debug line instructions of |inst| with new line instruction
|
||||
// set from |file_id, line, col|. If |inst| has no debug line instructions,
|
||||
// do not modify |inst|. |file_id| equals 0 indicates no line info is
|
||||
// available. Return true if |inst| modified.
|
||||
bool EliminateDeadLines(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// Apply lpfn() to all type, constant, global variable and function
|
||||
// instructions in their physical order.
|
||||
bool ProcessLines();
|
||||
|
||||
// A function that calls either PropagateLine or EliminateDeadLines.
|
||||
// Initialized by the class constructor.
|
||||
LineProcessFunction line_process_func_;
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
@ -78,7 +78,6 @@ add_spvtools_unittest(TARGET opt
|
||||
pass_remove_duplicates_test.cpp
|
||||
pass_utils.cpp
|
||||
private_to_local_test.cpp
|
||||
process_lines_test.cpp
|
||||
propagator_test.cpp
|
||||
reduce_load_size_test.cpp
|
||||
redundancy_elimination_test.cpp
|
||||
|
@ -3377,7 +3377,7 @@ OpBranch %18
|
||||
%18 = OpLabel
|
||||
|
||||
; CHECK: DebugScope [[bb3]]
|
||||
; CHECK-NOT: OpLine {{%\w+}} 3 0
|
||||
; CHECK: OpLine {{%\w+}} 3 0
|
||||
; CHECK: DebugValue [[dbg_foo]] [[value]]
|
||||
; CHECK: OpLine {{%\w+}} 4 0
|
||||
; CHECK: OpStore %gl_FragColor [[value]]
|
||||
|
@ -2103,7 +2103,7 @@ OpDecorate %gl_FragCoord BuiltIn FragCoord
|
||||
%uint_7 = OpConstant %uint 7
|
||||
%uint_8 = OpConstant %uint 8
|
||||
%uint_9 = OpConstant %uint 9
|
||||
%uint_93 = OpConstant %uint 93
|
||||
%uint_109 = OpConstant %uint 109
|
||||
%125 = OpConstantNull %v4float
|
||||
)";
|
||||
|
||||
@ -2180,19 +2180,23 @@ OpLine %5 24 0
|
||||
%54 = OpSampledImage %37 %52 %53
|
||||
%55 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
%56 = OpLoad %v2float %55
|
||||
OpNoLine
|
||||
%62 = OpULessThan %bool %50 %uint_128
|
||||
OpSelectionMerge %63 None
|
||||
OpBranchConditional %62 %64 %65
|
||||
%64 = OpLabel
|
||||
%66 = OpLoad %27 %51
|
||||
%67 = OpSampledImage %37 %66 %53
|
||||
OpLine %5 24 0
|
||||
%68 = OpImageSampleImplicitLod %v4float %67 %56
|
||||
OpNoLine
|
||||
OpBranch %63
|
||||
%65 = OpLabel
|
||||
%124 = OpFunctionCall %void %69 %uint_93 %uint_0 %50 %uint_128
|
||||
%124 = OpFunctionCall %void %69 %uint_109 %uint_0 %50 %uint_128
|
||||
OpBranch %63
|
||||
%63 = OpLabel
|
||||
%126 = OpPhi %v4float %68 %64 %125 %65
|
||||
OpLine %5 24 0
|
||||
%58 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpStore %58 %126
|
||||
OpLine %5 25 0
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "source/opt/build_module.h"
|
||||
#include "source/opt/def_use_manager.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
|
||||
@ -28,6 +29,8 @@ namespace spvtools {
|
||||
namespace opt {
|
||||
namespace {
|
||||
|
||||
constexpr uint32_t kOpLineOperandLineIndex = 1;
|
||||
|
||||
void DoRoundTripCheck(const std::string& text) {
|
||||
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
|
||||
std::unique_ptr<IRContext> context =
|
||||
@ -129,6 +132,110 @@ TEST(IrBuilder, KeepLineDebugInfo) {
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
TEST(IrBuilder, DistributeLineDebugInfo) {
|
||||
const std::string text =
|
||||
// clang-format off
|
||||
"OpCapability Shader\n"
|
||||
"%1 = OpExtInstImport \"GLSL.std.450\"\n"
|
||||
"OpMemoryModel Logical GLSL450\n"
|
||||
"OpEntryPoint Vertex %main \"main\"\n"
|
||||
"OpSource ESSL 310\n"
|
||||
"%file = OpString \"test\"\n"
|
||||
"OpName %main \"main\"\n"
|
||||
"OpName %f_ \"f(\"\n"
|
||||
"OpName %gv1 \"gv1\"\n"
|
||||
"OpName %gv2 \"gv2\"\n"
|
||||
"OpName %lv1 \"lv1\"\n"
|
||||
"OpName %lv2 \"lv2\"\n"
|
||||
"OpName %lv1_0 \"lv1\"\n"
|
||||
"%void = OpTypeVoid\n"
|
||||
"%10 = OpTypeFunction %void\n"
|
||||
"OpLine %file 10 0\n"
|
||||
"%float = OpTypeFloat 32\n"
|
||||
"%12 = OpTypeFunction %float\n"
|
||||
"%_ptr_Private_float = OpTypePointer Private %float\n"
|
||||
"%gv1 = OpVariable %_ptr_Private_float Private\n"
|
||||
"%float_10 = OpConstant %float 10\n"
|
||||
"%gv2 = OpVariable %_ptr_Private_float Private\n"
|
||||
"%float_100 = OpConstant %float 100\n"
|
||||
"%_ptr_Function_float = OpTypePointer Function %float\n"
|
||||
"%main = OpFunction %void None %10\n"
|
||||
"%17 = OpLabel\n"
|
||||
"%lv1_0 = OpVariable %_ptr_Function_float Function\n"
|
||||
"OpStore %gv1 %float_10\n"
|
||||
"OpStore %gv2 %float_100\n"
|
||||
"OpLine %file 1 0\n"
|
||||
"OpNoLine\n"
|
||||
"OpLine %file 2 0\n"
|
||||
"%18 = OpLoad %float %gv1\n"
|
||||
"%19 = OpLoad %float %gv2\n"
|
||||
"%20 = OpFSub %float %18 %19\n"
|
||||
"OpStore %lv1_0 %20\n"
|
||||
"OpReturn\n"
|
||||
"OpFunctionEnd\n"
|
||||
"%f_ = OpFunction %float None %12\n"
|
||||
"%21 = OpLabel\n"
|
||||
"%lv1 = OpVariable %_ptr_Function_float Function\n"
|
||||
"%lv2 = OpVariable %_ptr_Function_float Function\n"
|
||||
"OpLine %file 3 0\n"
|
||||
"OpLine %file 4 0\n"
|
||||
"%22 = OpLoad %float %gv1\n"
|
||||
"%23 = OpLoad %float %gv2\n"
|
||||
"%24 = OpFAdd %float %22 %23\n"
|
||||
"OpStore %lv1 %24\n"
|
||||
"OpLine %file 5 0\n"
|
||||
"OpLine %file 6 0\n"
|
||||
"OpNoLine\n"
|
||||
"%25 = OpLoad %float %gv1\n"
|
||||
"%26 = OpLoad %float %gv2\n"
|
||||
"%27 = OpFMul %float %25 %26\n"
|
||||
"OpBranch %28\n"
|
||||
"%28 = OpLabel\n"
|
||||
"OpStore %lv2 %27\n"
|
||||
"%29 = OpLoad %float %lv1\n"
|
||||
"OpLine %file 7 0\n"
|
||||
"%30 = OpLoad %float %lv2\n"
|
||||
"%31 = OpFDiv %float %28 %29\n"
|
||||
"OpReturnValue %30\n"
|
||||
"OpFunctionEnd\n";
|
||||
// clang-format on
|
||||
|
||||
std::unique_ptr<IRContext> context =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
||||
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
ASSERT_NE(nullptr, context);
|
||||
|
||||
struct LineInstrCheck {
|
||||
uint32_t id;
|
||||
std::vector<uint32_t> line_numbers;
|
||||
};
|
||||
const uint32_t kNoLine = 0;
|
||||
const LineInstrCheck line_checks[] = {
|
||||
{12, {10}}, {18, {1, kNoLine, 2}},
|
||||
{19, {2}}, {20, {2}},
|
||||
{22, {3, 4}}, {23, {4}},
|
||||
{24, {4}}, {25, {5, 6, kNoLine}},
|
||||
{26, {}}, {27, {}},
|
||||
{28, {}}, {29, {}},
|
||||
{30, {7}}, {31, {7}},
|
||||
};
|
||||
|
||||
spvtools::opt::analysis::DefUseManager* def_use_mgr =
|
||||
context->get_def_use_mgr();
|
||||
for (const LineInstrCheck& check : line_checks) {
|
||||
auto& lines = def_use_mgr->GetDef(check.id)->dbg_line_insts();
|
||||
for (uint32_t i = 0; i < check.line_numbers.size(); ++i) {
|
||||
if (check.line_numbers[i] == kNoLine) {
|
||||
EXPECT_EQ(lines[i].opcode(), SpvOpNoLine);
|
||||
continue;
|
||||
}
|
||||
EXPECT_EQ(lines[i].opcode(), SpvOpLine);
|
||||
EXPECT_EQ(lines[i].GetSingleWordOperand(kOpLineOperandLineIndex),
|
||||
check.line_numbers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IrBuilder, ConsumeDebugInfoInst) {
|
||||
// /* HLSL */
|
||||
//
|
||||
|
@ -160,13 +160,10 @@ OpName %gl_FragColor "gl_FragColor"
|
||||
; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: OpStore %s0 [[ex1]]
|
||||
; CHECK: OpLine {{%\w+}} 3 0
|
||||
; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0
|
||||
; CHECK: OpLine {{%\w+}} 3 0
|
||||
; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1
|
||||
; CHECK: OpLine {{%\w+}} 4 0
|
||||
; CHECK: OpStore %gl_FragColor [[ex2]]
|
||||
@ -263,15 +260,12 @@ OpName %gl_FragColor "gl_FragColor"
|
||||
; CHECK: DebugValue [[dbg_s0:%\w+]] [[s0_1_ptr]]
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: [[s0:%\w+]] = OpLoad %S_t %s0
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: [[comp:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[s0]] 1
|
||||
; CHECK: OpLine {{%\w+}} 1 0
|
||||
; CHECK: OpStore %s0 [[comp]]
|
||||
; CHECK: OpLine {{%\w+}} 2 0
|
||||
; CHECK: [[s0_2_ptr:%\w+]] = OpAccessChain %_ptr_Function_v4float %s0 %int_1
|
||||
; CHECK: OpLine {{%\w+}} 3 0
|
||||
; CHECK: [[s0:%\w+]] = OpLoad %S_t %s0
|
||||
; CHECK: OpLine {{%\w+}} 3 0
|
||||
; CHECK: [[s0_2_val:%\w+]] = OpCompositeExtract %v4float [[s0]] 1
|
||||
; CHECK: DebugValue [[dbg_s0]] [[s0_2_val]]
|
||||
; CHECK: OpLine {{%\w+}} 4 0
|
||||
|
@ -1,695 +0,0 @@
|
||||
// Copyright (c) 2017 Valve Corporation
|
||||
// Copyright (c) 2017 LunarG Inc.
|
||||
//
|
||||
// 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 <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test/opt/pass_fixture.h"
|
||||
#include "test/opt/pass_utils.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
namespace {
|
||||
|
||||
using ProcessLinesTest = PassTest<::testing::Test>;
|
||||
|
||||
TEST_F(ProcessLinesTest, SimplePropagation) {
|
||||
// Texture2D g_tColor[128];
|
||||
//
|
||||
// layout(push_constant) cbuffer PerViewConstantBuffer_t
|
||||
// {
|
||||
// uint g_nDataIdx;
|
||||
// uint g_nDataIdx2;
|
||||
// bool g_B;
|
||||
// };
|
||||
//
|
||||
// SamplerState g_sAniso;
|
||||
//
|
||||
// struct PS_INPUT
|
||||
// {
|
||||
// float2 vTextureCoords : TEXCOORD2;
|
||||
// };
|
||||
//
|
||||
// struct PS_OUTPUT
|
||||
// {
|
||||
// float4 vColor : SV_Target0;
|
||||
// };
|
||||
//
|
||||
// PS_OUTPUT MainPs(PS_INPUT i)
|
||||
// {
|
||||
// PS_OUTPUT ps_output;
|
||||
//
|
||||
// uint u;
|
||||
// if (g_B)
|
||||
// u = g_nDataIdx;
|
||||
// else
|
||||
// u = g_nDataIdx2;
|
||||
// ps_output.vColor = g_tColor[u].Sample(g_sAniso, i.vTextureCoords.xy);
|
||||
// return ps_output;
|
||||
// }
|
||||
|
||||
const std::string predefs =
|
||||
R"(OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
|
||||
OpExecutionMode %MainPs OriginUpperLeft
|
||||
%5 = OpString "foo.frag"
|
||||
OpSource HLSL 500
|
||||
OpName %MainPs "MainPs"
|
||||
OpName %PS_INPUT "PS_INPUT"
|
||||
OpMemberName %PS_INPUT 0 "vTextureCoords"
|
||||
OpName %PS_OUTPUT "PS_OUTPUT"
|
||||
OpMemberName %PS_OUTPUT 0 "vColor"
|
||||
OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
|
||||
OpName %i "i"
|
||||
OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
|
||||
OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
|
||||
OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
|
||||
OpMemberName %PerViewConstantBuffer_t 2 "g_B"
|
||||
OpName %_ ""
|
||||
OpName %u "u"
|
||||
OpName %ps_output "ps_output"
|
||||
OpName %g_tColor "g_tColor"
|
||||
OpName %g_sAniso "g_sAniso"
|
||||
OpName %i_0 "i"
|
||||
OpName %i_vTextureCoords "i.vTextureCoords"
|
||||
OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
|
||||
OpName %param "param"
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
|
||||
OpDecorate %PerViewConstantBuffer_t Block
|
||||
OpDecorate %g_tColor DescriptorSet 0
|
||||
OpDecorate %g_sAniso DescriptorSet 0
|
||||
OpDecorate %i_vTextureCoords Location 0
|
||||
OpDecorate %_entryPointOutput_vColor Location 0
|
||||
)";
|
||||
|
||||
const std::string before =
|
||||
R"(%void = OpTypeVoid
|
||||
%19 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
%v4float = OpTypeVector %float 4
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
%uint = OpTypeInt 32 0
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
%int = OpTypeInt 32 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
%bool = OpTypeBool
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
%41 = OpTypeSampler
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
%43 = OpTypeSampledImage %36
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
%MainPs = OpFunction %void None %19
|
||||
%48 = OpLabel
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpStore %50 %49
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpStore %param %51
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
%54 = OpLabel
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
%56 = OpLoad %uint %55
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
%62 = OpLoad %uint %61
|
||||
OpStore %u %62
|
||||
OpBranch %58
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
%64 = OpLoad %uint %63
|
||||
OpStore %u %64
|
||||
OpBranch %58
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
%67 = OpLoad %36 %66
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
%71 = OpLoad %v2float %70
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpReturnValue %74
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const std::string after =
|
||||
R"(OpNoLine
|
||||
%void = OpTypeVoid
|
||||
OpNoLine
|
||||
%19 = OpTypeFunction %void
|
||||
OpNoLine
|
||||
%float = OpTypeFloat 32
|
||||
OpNoLine
|
||||
%v2float = OpTypeVector %float 2
|
||||
OpNoLine
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
OpNoLine
|
||||
%v4float = OpTypeVector %float 4
|
||||
OpNoLine
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
OpNoLine
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%uint = OpTypeInt 32 0
|
||||
OpNoLine
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
OpNoLine
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
OpNoLine
|
||||
%int = OpTypeInt 32 1
|
||||
OpNoLine
|
||||
%int_2 = OpConstant %int 2
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
OpNoLine
|
||||
%bool = OpTypeBool
|
||||
OpNoLine
|
||||
%uint_0 = OpConstant %uint 0
|
||||
OpNoLine
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
OpNoLine
|
||||
%int_0 = OpConstant %int 0
|
||||
OpNoLine
|
||||
%int_1 = OpConstant %int 1
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
OpNoLine
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
OpNoLine
|
||||
%uint_128 = OpConstant %uint 128
|
||||
OpNoLine
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
OpNoLine
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
OpNoLine
|
||||
%41 = OpTypeSampler
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
OpNoLine
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
OpNoLine
|
||||
%43 = OpTypeSampledImage %36
|
||||
OpNoLine
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
OpNoLine
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
OpNoLine
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
OpNoLine
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
OpNoLine
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
OpNoLine
|
||||
%MainPs = OpFunction %void None %19
|
||||
OpNoLine
|
||||
%48 = OpLabel
|
||||
OpNoLine
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpNoLine
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
OpLine %5 23 0
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpLine %5 23 0
|
||||
OpStore %50 %49
|
||||
OpLine %5 23 0
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpLine %5 23 0
|
||||
OpStore %param %51
|
||||
OpLine %5 23 0
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
OpLine %5 23 0
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpLine %5 23 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpLine %5 23 0
|
||||
OpReturn
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
OpNoLine
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
OpNoLine
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%54 = OpLabel
|
||||
OpNoLine
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
OpNoLine
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
OpLine %5 27 0
|
||||
%56 = OpLoad %uint %55
|
||||
OpLine %5 27 0
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpLine %5 27 0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
OpNoLine
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
OpLine %5 28 0
|
||||
%62 = OpLoad %uint %61
|
||||
OpLine %5 28 0
|
||||
OpStore %u %62
|
||||
OpLine %5 28 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
OpLine %5 30 0
|
||||
%64 = OpLoad %uint %63
|
||||
OpLine %5 30 0
|
||||
OpStore %u %64
|
||||
OpLine %5 30 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
OpLine %5 31 0
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
OpLine %5 31 0
|
||||
%67 = OpLoad %36 %66
|
||||
OpLine %5 31 0
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
OpLine %5 31 0
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
OpLine %5 31 0
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
OpLine %5 31 0
|
||||
%71 = OpLoad %v2float %70
|
||||
OpLine %5 31 0
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
OpLine %5 31 0
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpLine %5 31 0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpLine %5 32 0
|
||||
OpReturnValue %74
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<ProcessLinesPass>(predefs + before, predefs + after,
|
||||
false, true, kLinesPropagateLines);
|
||||
}
|
||||
|
||||
TEST_F(ProcessLinesTest, SimpleElimination) {
|
||||
// Previous test with before and after reversed
|
||||
|
||||
const std::string predefs =
|
||||
R"(OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
|
||||
OpExecutionMode %MainPs OriginUpperLeft
|
||||
%5 = OpString "foo.frag"
|
||||
OpSource HLSL 500
|
||||
OpName %MainPs "MainPs"
|
||||
OpName %PS_INPUT "PS_INPUT"
|
||||
OpMemberName %PS_INPUT 0 "vTextureCoords"
|
||||
OpName %PS_OUTPUT "PS_OUTPUT"
|
||||
OpMemberName %PS_OUTPUT 0 "vColor"
|
||||
OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
|
||||
OpName %i "i"
|
||||
OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
|
||||
OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
|
||||
OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
|
||||
OpMemberName %PerViewConstantBuffer_t 2 "g_B"
|
||||
OpName %_ ""
|
||||
OpName %u "u"
|
||||
OpName %ps_output "ps_output"
|
||||
OpName %g_tColor "g_tColor"
|
||||
OpName %g_sAniso "g_sAniso"
|
||||
OpName %i_0 "i"
|
||||
OpName %i_vTextureCoords "i.vTextureCoords"
|
||||
OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
|
||||
OpName %param "param"
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
|
||||
OpDecorate %PerViewConstantBuffer_t Block
|
||||
OpDecorate %g_tColor DescriptorSet 0
|
||||
OpDecorate %g_sAniso DescriptorSet 0
|
||||
OpDecorate %i_vTextureCoords Location 0
|
||||
OpDecorate %_entryPointOutput_vColor Location 0
|
||||
)";
|
||||
|
||||
const std::string before =
|
||||
R"(OpNoLine
|
||||
%void = OpTypeVoid
|
||||
OpNoLine
|
||||
%19 = OpTypeFunction %void
|
||||
OpNoLine
|
||||
%float = OpTypeFloat 32
|
||||
OpNoLine
|
||||
%v2float = OpTypeVector %float 2
|
||||
OpNoLine
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
OpNoLine
|
||||
%v4float = OpTypeVector %float 4
|
||||
OpNoLine
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
OpNoLine
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%uint = OpTypeInt 32 0
|
||||
OpNoLine
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
OpNoLine
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
OpNoLine
|
||||
%int = OpTypeInt 32 1
|
||||
OpNoLine
|
||||
%int_2 = OpConstant %int 2
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
OpNoLine
|
||||
%bool = OpTypeBool
|
||||
OpNoLine
|
||||
%uint_0 = OpConstant %uint 0
|
||||
OpNoLine
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
OpNoLine
|
||||
%int_0 = OpConstant %int 0
|
||||
OpNoLine
|
||||
%int_1 = OpConstant %int 1
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
OpNoLine
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
OpNoLine
|
||||
%uint_128 = OpConstant %uint 128
|
||||
OpNoLine
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
OpNoLine
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
OpNoLine
|
||||
%41 = OpTypeSampler
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
OpNoLine
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
OpNoLine
|
||||
%43 = OpTypeSampledImage %36
|
||||
OpNoLine
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
OpNoLine
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
OpNoLine
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
OpNoLine
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
OpNoLine
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
OpNoLine
|
||||
%MainPs = OpFunction %void None %19
|
||||
OpNoLine
|
||||
%48 = OpLabel
|
||||
OpNoLine
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpNoLine
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
OpLine %5 23 0
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpLine %5 23 0
|
||||
OpStore %50 %49
|
||||
OpLine %5 23 0
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpLine %5 23 0
|
||||
OpStore %param %51
|
||||
OpLine %5 23 0
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
OpLine %5 23 0
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpLine %5 23 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpLine %5 23 0
|
||||
OpReturn
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
OpNoLine
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
OpNoLine
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%54 = OpLabel
|
||||
OpNoLine
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
OpNoLine
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
OpLine %5 27 0
|
||||
%56 = OpLoad %uint %55
|
||||
OpLine %5 27 0
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpLine %5 27 0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
OpNoLine
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
OpLine %5 28 0
|
||||
%62 = OpLoad %uint %61
|
||||
OpLine %5 28 0
|
||||
OpStore %u %62
|
||||
OpLine %5 28 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
OpLine %5 30 0
|
||||
%64 = OpLoad %uint %63
|
||||
OpLine %5 30 0
|
||||
OpStore %u %64
|
||||
OpLine %5 30 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
OpLine %5 31 0
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
OpLine %5 31 0
|
||||
%67 = OpLoad %36 %66
|
||||
OpLine %5 31 0
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
OpLine %5 31 0
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
OpLine %5 31 0
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
OpLine %5 31 0
|
||||
%71 = OpLoad %v2float %70
|
||||
OpLine %5 31 0
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
OpLine %5 31 0
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpLine %5 31 0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpLine %5 32 0
|
||||
OpReturnValue %74
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const std::string after =
|
||||
R"(%void = OpTypeVoid
|
||||
%19 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
%v4float = OpTypeVector %float 4
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
%uint = OpTypeInt 32 0
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
%int = OpTypeInt 32 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
%bool = OpTypeBool
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
%41 = OpTypeSampler
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
%43 = OpTypeSampledImage %36
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
%MainPs = OpFunction %void None %19
|
||||
%48 = OpLabel
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpStore %50 %49
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpStore %param %51
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
%54 = OpLabel
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
%56 = OpLoad %uint %55
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
%62 = OpLoad %uint %61
|
||||
OpStore %u %62
|
||||
OpBranch %58
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
%64 = OpLoad %uint %63
|
||||
OpStore %u %64
|
||||
OpBranch %58
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
%67 = OpLoad %36 %66
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
%71 = OpLoad %v2float %70
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpReturnValue %74
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<ProcessLinesPass>(
|
||||
predefs + before, predefs + after, false, true, kLinesEliminateDeadLines);
|
||||
}
|
||||
|
||||
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||
//
|
||||
// TODO(greg-lunarg): Think about other tests :)
|
||||
|
||||
} // namespace
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
@ -315,8 +315,10 @@ TEST_F(RedundancyEliminationTest, OpenCLDebugInfo100) {
|
||||
; After removing one `OpFAdd %float %26 %26`, two DebugValues are the same.
|
||||
; One must be removed.
|
||||
;
|
||||
; CHECK: [[add:%\w+]] = OpFAdd %float [[value:%\w+]]
|
||||
; CHECK: OpLine {{%\w+}} 0 0
|
||||
; CHECK-NEXT: [[add:%\w+]] = OpFAdd %float [[value:%\w+]]
|
||||
; CHECK-NEXT: DebugValue [[dbg_local_var]] [[add]]
|
||||
; CHECK-NEXT: OpLine {{%\w+}} 1 0
|
||||
; CHECK-NEXT: OpFAdd %float [[add]] [[value]]
|
||||
; CHECK-NEXT: OpReturn
|
||||
%27 = OpFAdd %float %26 %26
|
||||
|
@ -903,7 +903,7 @@ TEST_F(WrapOpKillTest, DebugInfoSimple) {
|
||||
; CHECK-NEXT: {{%\d+}} = OpExtInst %void [[ext:%\d+]] DebugScope
|
||||
; CHECK-NEXT: OpLine [[file:%\d+]] 100 200
|
||||
; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
|
||||
; CHECK-NEXT: {{%\d+}} = OpExtInst %void [[ext]] DebugNoScope
|
||||
; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugNoScope
|
||||
; CHECK-NEXT: OpReturn
|
||||
; CHECK: [[new_kill]] = OpFunction
|
||||
; CHECK-NEXT: OpLabel
|
||||
|
Loading…
Reference in New Issue
Block a user