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

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/opt/merge_return_pass.cpp')
-rw-r--r--source/opt/merge_return_pass.cpp113
1 files changed, 60 insertions, 53 deletions
diff --git a/source/opt/merge_return_pass.cpp b/source/opt/merge_return_pass.cpp
index 7710deae2..c262ea073 100644
--- a/source/opt/merge_return_pass.cpp
+++ b/source/opt/merge_return_pass.cpp
@@ -30,7 +30,7 @@ namespace opt {
Pass::Status MergeReturnPass::Process() {
bool is_shader =
- context()->get_feature_mgr()->HasCapability(SpvCapabilityShader);
+ context()->get_feature_mgr()->HasCapability(spv::Capability::Shader);
bool failed = false;
ProcessFunction pfn = [&failed, is_shader, this](Function* function) {
@@ -74,16 +74,16 @@ Pass::Status MergeReturnPass::Process() {
void MergeReturnPass::GenerateState(BasicBlock* block) {
if (Instruction* mergeInst = block->GetMergeInst()) {
- if (mergeInst->opcode() == SpvOpLoopMerge) {
+ if (mergeInst->opcode() == spv::Op::OpLoopMerge) {
// If new loop, break to this loop merge block
state_.emplace_back(mergeInst, mergeInst);
} else {
auto branchInst = mergeInst->NextNode();
- if (branchInst->opcode() == SpvOpSwitch) {
+ if (branchInst->opcode() == spv::Op::OpSwitch) {
// If switch inside of loop, break to innermost loop merge block.
// Otherwise need to break to this switch merge block.
auto lastMergeInst = state_.back().BreakMergeInst();
- if (lastMergeInst && lastMergeInst->opcode() == SpvOpLoopMerge)
+ if (lastMergeInst && lastMergeInst->opcode() == spv::Op::OpLoopMerge)
state_.emplace_back(lastMergeInst, mergeInst);
else
state_.emplace_back(mergeInst, mergeInst);
@@ -174,7 +174,7 @@ bool MergeReturnPass::ProcessStructured(
void MergeReturnPass::CreateReturnBlock() {
// Create a label for the new return block
std::unique_ptr<Instruction> return_label(
- new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {}));
+ new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {}));
// Create the new basic block
std::unique_ptr<BasicBlock> return_block(
@@ -195,37 +195,41 @@ void MergeReturnPass::CreateReturn(BasicBlock* block) {
// Load and return the final return value
uint32_t loadId = TakeNextId();
block->AddInstruction(MakeUnique<Instruction>(
- context(), SpvOpLoad, function_->type_id(), loadId,
+ context(), spv::Op::OpLoad, function_->type_id(), loadId,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}}));
Instruction* var_inst = block->terminator();
context()->AnalyzeDefUse(var_inst);
context()->set_instr_block(var_inst, block);
context()->get_decoration_mgr()->CloneDecorations(
- return_value_->result_id(), loadId, {SpvDecorationRelaxedPrecision});
+ return_value_->result_id(), loadId,
+ {spv::Decoration::RelaxedPrecision});
block->AddInstruction(MakeUnique<Instruction>(
- context(), SpvOpReturnValue, 0, 0,
+ context(), spv::Op::OpReturnValue, 0, 0,
std::initializer_list<Operand>{{SPV_OPERAND_TYPE_ID, {loadId}}}));
context()->AnalyzeDefUse(block->terminator());
context()->set_instr_block(block->terminator(), block);
} else {
- block->AddInstruction(MakeUnique<Instruction>(context(), SpvOpReturn));
+ block->AddInstruction(
+ MakeUnique<Instruction>(context(), spv::Op::OpReturn));
context()->AnalyzeDefUse(block->terminator());
context()->set_instr_block(block->terminator(), block);
}
}
void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) {
- SpvOp tail_opcode = block->tail()->opcode();
- if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue) {
+ spv::Op tail_opcode = block->tail()->opcode();
+ if (tail_opcode == spv::Op::OpReturn ||
+ tail_opcode == spv::Op::OpReturnValue) {
if (!return_flag_) {
AddReturnFlag();
}
}
- if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue ||
- tail_opcode == SpvOpUnreachable) {
+ if (tail_opcode == spv::Op::OpReturn ||
+ tail_opcode == spv::Op::OpReturnValue ||
+ tail_opcode == spv::Op::OpUnreachable) {
assert(CurrentState().InBreakable() &&
"Should be in the placeholder construct.");
BranchToBlock(block, CurrentState().BreakMergeId());
@@ -234,8 +238,8 @@ void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) {
}
void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) {
- if (block->tail()->opcode() == SpvOpReturn ||
- block->tail()->opcode() == SpvOpReturnValue) {
+ if (block->tail()->opcode() == spv::Op::OpReturn ||
+ block->tail()->opcode() == spv::Op::OpReturnValue) {
RecordReturned(block);
RecordReturnValue(block);
}
@@ -247,7 +251,7 @@ void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) {
UpdatePhiNodes(block, target_block);
Instruction* return_inst = block->terminator();
- return_inst->SetOpcode(SpvOpBranch);
+ return_inst->SetOpcode(spv::Op::OpBranch);
return_inst->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {target}}});
context()->get_def_use_mgr()->AnalyzeInstDefUse(return_inst);
new_edges_[target_block].insert(block->id());
@@ -276,7 +280,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
&inst,
[&users_to_update, &dom_tree, &inst, inst_bb, this](Instruction* user) {
BasicBlock* user_bb = nullptr;
- if (user->opcode() != SpvOpPhi) {
+ if (user->opcode() != spv::Op::OpPhi) {
user_bb = context()->get_instr_block(user);
} else {
// For OpPhi, the use should be considered to be in the predecessor.
@@ -325,15 +329,16 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
// instruction. If not, the Spir-V will be invalid.
Instruction* inst_type = get_def_use_mgr()->GetDef(inst.type_id());
bool regenerateInstruction = false;
- if (inst_type->opcode() == SpvOpTypePointer) {
+ if (inst_type->opcode() == spv::Op::OpTypePointer) {
if (!context()->get_feature_mgr()->HasCapability(
- SpvCapabilityVariablePointers)) {
+ spv::Capability::VariablePointers)) {
regenerateInstruction = true;
}
- uint32_t storage_class = inst_type->GetSingleWordInOperand(0);
- if (storage_class != SpvStorageClassWorkgroup &&
- storage_class != SpvStorageClassStorageBuffer) {
+ auto storage_class =
+ spv::StorageClass(inst_type->GetSingleWordInOperand(0));
+ if (storage_class != spv::StorageClass::Workgroup &&
+ storage_class != spv::StorageClass::StorageBuffer) {
regenerateInstruction = true;
}
}
@@ -343,7 +348,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
uint32_t new_id = TakeNextId();
regen_inst->SetResultId(new_id);
Instruction* insert_pos = &*merge_block->begin();
- while (insert_pos->opcode() == SpvOpPhi) {
+ while (insert_pos->opcode() == spv::Op::OpPhi) {
insert_pos = insert_pos->NextNode();
}
new_phi = insert_pos->InsertBefore(std::move(regen_inst));
@@ -459,7 +464,7 @@ bool MergeReturnPass::BreakFromConstruct(
// Leave the phi instructions behind.
auto iter = block->begin();
- while (iter->opcode() == SpvOpPhi) {
+ while (iter->opcode() == spv::Op::OpPhi) {
++iter;
}
@@ -478,7 +483,7 @@ bool MergeReturnPass::BreakFromConstruct(
// If |block| was a continue target for a loop |old_body| is now the correct
// continue target.
- if (break_merge_inst->opcode() == SpvOpLoopMerge &&
+ if (break_merge_inst->opcode() == spv::Op::OpLoopMerge &&
break_merge_inst->GetSingleWordInOperand(1) == block->id()) {
break_merge_inst->SetInOperand(1, {old_body->id()});
context()->UpdateDefUse(break_merge_inst);
@@ -531,8 +536,8 @@ bool MergeReturnPass::BreakFromConstruct(
}
void MergeReturnPass::RecordReturned(BasicBlock* block) {
- if (block->tail()->opcode() != SpvOpReturn &&
- block->tail()->opcode() != SpvOpReturnValue)
+ if (block->tail()->opcode() != spv::Op::OpReturn &&
+ block->tail()->opcode() != spv::Op::OpReturnValue)
return;
assert(return_flag_ && "Did not generate the return flag variable.");
@@ -550,7 +555,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) {
}
std::unique_ptr<Instruction> return_store(new Instruction(
- context(), SpvOpStore, 0, 0,
+ context(), spv::Op::OpStore, 0, 0,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}},
{SPV_OPERAND_TYPE_ID, {constant_true_->result_id()}}}));
@@ -563,7 +568,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) {
void MergeReturnPass::RecordReturnValue(BasicBlock* block) {
auto terminator = *block->tail();
- if (terminator.opcode() != SpvOpReturnValue) {
+ if (terminator.opcode() != spv::Op::OpReturnValue) {
return;
}
@@ -571,7 +576,7 @@ void MergeReturnPass::RecordReturnValue(BasicBlock* block) {
"Did not generate the variable to hold the return value.");
std::unique_ptr<Instruction> value_store(new Instruction(
- context(), SpvOpStore, 0, 0,
+ context(), spv::Op::OpStore, 0, 0,
std::initializer_list<Operand>{
{SPV_OPERAND_TYPE_ID, {return_value_->result_id()}},
{SPV_OPERAND_TYPE_ID, {terminator.GetSingleWordInOperand(0u)}}}));
@@ -586,17 +591,19 @@ void MergeReturnPass::AddReturnValue() {
if (return_value_) return;
uint32_t return_type_id = function_->type_id();
- if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == SpvOpTypeVoid)
+ if (get_def_use_mgr()->GetDef(return_type_id)->opcode() ==
+ spv::Op::OpTypeVoid)
return;
uint32_t return_ptr_type = context()->get_type_mgr()->FindPointerToType(
- return_type_id, SpvStorageClassFunction);
+ return_type_id, spv::StorageClass::Function);
uint32_t var_id = TakeNextId();
- std::unique_ptr<Instruction> returnValue(new Instruction(
- context(), SpvOpVariable, return_ptr_type, var_id,
- std::initializer_list<Operand>{
- {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}));
+ std::unique_ptr<Instruction> returnValue(
+ new Instruction(context(), spv::Op::OpVariable, return_ptr_type, var_id,
+ std::initializer_list<Operand>{
+ {SPV_OPERAND_TYPE_STORAGE_CLASS,
+ {uint32_t(spv::StorageClass::Function)}}}));
auto insert_iter = function_->begin()->begin();
insert_iter.InsertBefore(std::move(returnValue));
@@ -606,7 +613,7 @@ void MergeReturnPass::AddReturnValue() {
context()->set_instr_block(return_value_, entry_block);
context()->get_decoration_mgr()->CloneDecorations(
- function_->result_id(), var_id, {SpvDecorationRelaxedPrecision});
+ function_->result_id(), var_id, {spv::Decoration::RelaxedPrecision});
}
void MergeReturnPass::AddReturnFlag() {
@@ -625,14 +632,14 @@ void MergeReturnPass::AddReturnFlag() {
const_mgr->GetDefiningInstruction(false_const)->result_id();
uint32_t bool_ptr_id =
- type_mgr->FindPointerToType(bool_id, SpvStorageClassFunction);
+ type_mgr->FindPointerToType(bool_id, spv::StorageClass::Function);
uint32_t var_id = TakeNextId();
std::unique_ptr<Instruction> returnFlag(new Instruction(
- context(), SpvOpVariable, bool_ptr_id, var_id,
- std::initializer_list<Operand>{
- {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
- {SPV_OPERAND_TYPE_ID, {const_false_id}}}));
+ context(), spv::Op::OpVariable, bool_ptr_id, var_id,
+ std::initializer_list<Operand>{{SPV_OPERAND_TYPE_STORAGE_CLASS,
+ {uint32_t(spv::StorageClass::Function)}},
+ {SPV_OPERAND_TYPE_ID, {const_false_id}}}));
auto insert_iter = function_->begin()->begin();
@@ -648,8 +655,8 @@ std::vector<BasicBlock*> MergeReturnPass::CollectReturnBlocks(
std::vector<BasicBlock*> return_blocks;
for (auto& block : *function) {
Instruction& terminator = *block.tail();
- if (terminator.opcode() == SpvOpReturn ||
- terminator.opcode() == SpvOpReturnValue) {
+ if (terminator.opcode() == spv::Op::OpReturn ||
+ terminator.opcode() == spv::Op::OpReturnValue) {
return_blocks.push_back(&block);
}
}
@@ -670,7 +677,7 @@ void MergeReturnPass::MergeReturnBlocks(
// Create new return.
std::vector<Operand> phi_ops;
for (auto block : return_blocks) {
- if (block->tail()->opcode() == SpvOpReturnValue) {
+ if (block->tail()->opcode() == spv::Op::OpReturnValue) {
phi_ops.push_back(
{SPV_OPERAND_TYPE_ID, {block->tail()->GetSingleWordInOperand(0u)}});
phi_ops.push_back({SPV_OPERAND_TYPE_ID, {block->id()}});
@@ -682,12 +689,12 @@ void MergeReturnPass::MergeReturnBlocks(
uint32_t phi_result_id = TakeNextId();
uint32_t phi_type_id = function->type_id();
std::unique_ptr<Instruction> phi_inst(new Instruction(
- context(), SpvOpPhi, phi_type_id, phi_result_id, phi_ops));
+ context(), spv::Op::OpPhi, phi_type_id, phi_result_id, phi_ops));
ret_block_iter->AddInstruction(std::move(phi_inst));
BasicBlock::iterator phiIter = ret_block_iter->tail();
std::unique_ptr<Instruction> return_inst(
- new Instruction(context(), SpvOpReturnValue, 0u, 0u,
+ new Instruction(context(), spv::Op::OpReturnValue, 0u, 0u,
{{SPV_OPERAND_TYPE_ID, {phi_result_id}}}));
ret_block_iter->AddInstruction(std::move(return_inst));
BasicBlock::iterator ret = ret_block_iter->tail();
@@ -697,14 +704,14 @@ void MergeReturnPass::MergeReturnBlocks(
get_def_use_mgr()->AnalyzeInstDef(&*ret);
} else {
std::unique_ptr<Instruction> return_inst(
- new Instruction(context(), SpvOpReturn));
+ new Instruction(context(), spv::Op::OpReturn));
ret_block_iter->AddInstruction(std::move(return_inst));
}
// Replace returns with branches
for (auto block : return_blocks) {
context()->ForgetUses(block->terminator());
- block->tail()->SetOpcode(SpvOpBranch);
+ block->tail()->SetOpcode(spv::Op::OpBranch);
block->tail()->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {return_id}}});
get_def_use_mgr()->AnalyzeInstUse(block->terminator());
get_def_use_mgr()->AnalyzeInstUse(block->GetLabelInst());
@@ -789,7 +796,7 @@ bool MergeReturnPass::AddSingleCaseSwitchAroundFunction() {
BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) {
std::unique_ptr<Instruction> label(
- new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {}));
+ new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {}));
// Create the new basic block
std::unique_ptr<BasicBlock> block(new BasicBlock(std::move(label)));
@@ -824,7 +831,7 @@ bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) {
// block to make sure the OpVariable instructions remain in the entry block.
BasicBlock* start_block = &*function_->begin();
auto split_pos = start_block->begin();
- while (split_pos->opcode() == SpvOpVariable) {
+ while (split_pos->opcode() == spv::Op::OpVariable) {
++split_pos;
}
@@ -865,7 +872,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) {
if (struct_cfg_analysis->IsContinueBlock(bb.id())) {
// |bb| must be an empty block ending with a branch to the header.
Instruction* inst = &*bb.begin();
- if (inst->opcode() != SpvOpBranch) {
+ if (inst->opcode() != spv::Op::OpBranch) {
return true;
}
@@ -875,7 +882,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) {
}
} else if (struct_cfg_analysis->IsMergeBlock(bb.id())) {
// |bb| must be an empty block ending with OpUnreachable.
- if (bb.begin()->opcode() != SpvOpUnreachable) {
+ if (bb.begin()->opcode() != spv::Op::OpUnreachable) {
return true;
}
} else {