Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/dxil-spirv.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-04-07 18:32:42 +0300
committerGitHub <noreply@github.com>2022-04-07 18:32:42 +0300
commite33d7d5d010948a5cb3b98f50d7c9d0447122609 (patch)
tree6a92c991e2330bb29379d70975b0bb895945ec07
parent2519370a893cd648a313e981cc41e49a13140a64 (diff)
parent28930a3bba902127d5e8be057024b7d5615c3cdf (diff)
Merge pull request #108 from HansKristian-Work/impossible-fallthrough-default
Consider impossible fallthrough scenarios with default blocks as well.
-rw-r--r--cfg_structurizer.cpp11
-rw-r--r--dxil_converter.cpp7
-rw-r--r--ir.hpp2
-rw-r--r--node.cpp2
-rw-r--r--spirv_module.cpp10
5 files changed, 21 insertions, 11 deletions
diff --git a/cfg_structurizer.cpp b/cfg_structurizer.cpp
index dcaa2ad..d181834 100644
--- a/cfg_structurizer.cpp
+++ b/cfg_structurizer.cpp
@@ -86,7 +86,6 @@ void CFGStructurizer::log_cfg_graphviz(const char *path) const
case Terminator::Type::Switch:
for (auto &c : node->ir.terminator.cases)
fprintf(file, "%u -> %u;\n", get_node_id(node), get_node_id(c.node));
- fprintf(file, "%u -> %u;\n", get_node_id(node), get_node_id(node->ir.terminator.default_node));
break;
default:
@@ -141,8 +140,12 @@ void CFGStructurizer::log_cfg(const char *tag) const
case Terminator::Type::Switch:
LOGI(" Switch\n");
for (auto &c : node->ir.terminator.cases)
- LOGI(" Case %u -> %s\n", c.value, c.node->name.c_str());
- LOGI(" Default -> %s\n", node->ir.terminator.default_node->name.c_str());
+ {
+ if (c.is_default)
+ LOGI(" Default -> %s\n", c.node->name.c_str());
+ else
+ LOGI(" Case %u -> %s\n", c.value, c.node->name.c_str());
+ }
break;
case Terminator::Type::Kill:
@@ -2946,8 +2949,6 @@ void CFGStructurizer::retarget_pred_from(CFGNode *new_node, CFGNode *old_succ)
p_term.true_block = new_node;
if (p_term.false_block == old_succ)
p_term.false_block = new_node;
- if (p_term.default_node == old_succ)
- p_term.default_node = new_node;
for (auto &c : p_term.cases)
if (c.node == old_succ)
c.node = new_node;
diff --git a/dxil_converter.cpp b/dxil_converter.cpp
index f36052a..4aa567e 100644
--- a/dxil_converter.cpp
+++ b/dxil_converter.cpp
@@ -5360,7 +5360,12 @@ CFGNode *Converter::Impl::convert_function(llvm::Function *func, CFGNodePool &po
else if (auto *inst = llvm::dyn_cast<llvm::SwitchInst>(instruction))
{
node->ir.terminator.type = Terminator::Type::Switch;
- node->ir.terminator.default_node = bb_map[inst->getDefaultDest()]->node;
+
+ Terminator::Case default_case = {};
+ default_case.is_default = true;
+ default_case.node = bb_map[inst->getDefaultDest()]->node;
+ node->ir.terminator.cases.push_back(default_case);
+
node->ir.terminator.conditional_id = get_id_for_value(inst->getCondition());
for (auto itr = inst->case_begin(); itr != inst->case_end(); ++itr)
{
diff --git a/ir.hpp b/ir.hpp
index c154037..f02b9f3 100644
--- a/ir.hpp
+++ b/ir.hpp
@@ -164,9 +164,9 @@ struct Terminator
CFGNode *node = nullptr;
uint64_t global_order = 0;
uint32_t value = 0;
+ bool is_default = false;
};
Vector<Case> cases;
- CFGNode *default_node = nullptr;
uint32_t return_value = 0;
};
diff --git a/node.cpp b/node.cpp
index c077eeb..8581532 100644
--- a/node.cpp
+++ b/node.cpp
@@ -429,8 +429,6 @@ void CFGNode::retarget_branch(CFGNode *to_prev, CFGNode *to_next)
ir.terminator.true_block = to_next;
if (ir.terminator.false_block == to_prev)
ir.terminator.false_block = to_next;
- if (ir.terminator.default_node == to_prev)
- ir.terminator.default_node = to_next;
for (auto &c : ir.terminator.cases)
if (c.node == to_prev)
c.node = to_next;
diff --git a/spirv_module.cpp b/spirv_module.cpp
index 6b4f8d6..c7d56db 100644
--- a/spirv_module.cpp
+++ b/spirv_module.cpp
@@ -987,10 +987,16 @@ void SPIRVModule::Impl::emit_basic_block(CFGNode *node)
{
auto switch_op = std::make_unique<spv::Instruction>(spv::OpSwitch);
switch_op->addIdOperand(ir.terminator.conditional_id);
- switch_op->addIdOperand(ir.terminator.default_node->id);
- get_spv_block(ir.terminator.default_node)->addPredecessor(bb);
+
+ auto default_itr = std::find_if(ir.terminator.cases.begin(), ir.terminator.cases.end(),
+ [](const Terminator::Case &c) { return c.is_default; });
+ assert(default_itr != ir.terminator.cases.end());
+ switch_op->addIdOperand(default_itr->node->id);
+ get_spv_block(default_itr->node)->addPredecessor(bb);
for (auto &switch_case : ir.terminator.cases)
{
+ if (switch_case.is_default)
+ continue;
switch_op->addImmediateOperand(switch_case.value);
switch_op->addIdOperand(switch_case.node->id);
get_spv_block(switch_case.node)->addPredecessor(bb);