mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-24 20:40:13 +00:00
Update some language usage. (#3611)
This CL updates various bits of language in line with the guidelines provided by Android (https://source.android.com/setup/contribute/respectful-code)
This commit is contained in:
parent
863b8e3d3d
commit
a1ea15c902
6
CHANGES
6
CHANGES
@ -39,7 +39,7 @@ v2020.4 2020-07-22
|
||||
|
||||
v2020.3 2020-05-27
|
||||
- General
|
||||
- Prevent Effcee install his things when build spirv-tools with testing enabled (#3256)
|
||||
- Prevent Effcee from installing things when building spirv-tools with testing enabled (#3256)
|
||||
- Update acorn version (#3294)
|
||||
- If SPIRV-Headers is in our tree, include it as subproject (#3299)
|
||||
- allow cross compiling for Windows Store, UWP, etc. (#3330)
|
||||
@ -111,7 +111,7 @@ v2020.1 2020-02-03
|
||||
- Optimizer
|
||||
- Change default version for CreatInstBindlessCheckPass to 2 (#3096, #3119)
|
||||
- Better handling of OpLine on merge blocks (#3130)
|
||||
- Use dummy switch instead of dummy loop in MergeReturn pass. (#3151)
|
||||
- Use placeholder switch instead of placeholder loop in MergeReturn pass. (#3151)
|
||||
- Handle TimeAMD in AmdExtensionToKhrPass. (#3168)
|
||||
- Validator
|
||||
- Fix structured exit validation (#3141)
|
||||
@ -438,7 +438,7 @@ v2018.6 2018-11-07
|
||||
- Optimizer
|
||||
- Unrolling loops marked for unrolling in the legalization passes.
|
||||
- Improved the compile time of loop unrolling.
|
||||
- Changee merge-return to create a dummy loop around the function.
|
||||
- Changee merge-return to create a placeholder loop around the function.
|
||||
- Small improvement to merge-blocks to allow it to merge more often.
|
||||
- Enforce an upper bound for the ids, and add option to set it.
|
||||
- #1966: Report error if there are unreachable block before running merge return
|
||||
|
@ -73,7 +73,7 @@ class TransformationOutlineFunction : public Transformation {
|
||||
// - Unless the type required for the new function is already known,
|
||||
// |message_.new_function_type_id| is used as the type id for a new function
|
||||
// type, and the new function uses this type.
|
||||
// - The new function starts with a dummy block with id
|
||||
// - The new function starts with a placeholder block with id
|
||||
// |message_.new_function_first_block|, which jumps straight to a successor
|
||||
// block, to avoid violating rules on what the first block in a function may
|
||||
// look like.
|
||||
|
@ -324,7 +324,7 @@ std::string FriendlyNameMapper::NameForEnumOperand(spv_operand_type_t type,
|
||||
if (SPV_SUCCESS == grammar_.lookupOperand(type, word, &desc)) {
|
||||
return desc->name;
|
||||
} else {
|
||||
// Invalid input. Just give something sane.
|
||||
// Invalid input. Just give something.
|
||||
return std::string("StorageClass") + to_string(word);
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
// Calculates the dominator or postdominator tree for a given function.
|
||||
// 1 - Compute the successors and predecessors for each BasicBlock. We add a
|
||||
// dummy node for the start node or for postdominators the exit. This node will
|
||||
// point to all entry or all exit nodes.
|
||||
// placeholder node for the start node or for postdominators the exit. This node
|
||||
// will point to all entry or all exit nodes.
|
||||
// 2 - Using the CFA::DepthFirstTraversal get a depth first postordered list of
|
||||
// all BasicBlocks. Using the successors (or for postdominator, predecessors)
|
||||
// calculated in step 1 to traverse the tree.
|
||||
@ -107,8 +107,9 @@ class BasicBlockSuccessorHelper {
|
||||
|
||||
public:
|
||||
// For compliance with the dominance tree computation, entry nodes are
|
||||
// connected to a single dummy node.
|
||||
BasicBlockSuccessorHelper(Function& func, const BasicBlock* dummy_start_node,
|
||||
// connected to a single placeholder node.
|
||||
BasicBlockSuccessorHelper(Function& func,
|
||||
const BasicBlock* placeholder_start_node,
|
||||
bool post);
|
||||
|
||||
// CFA::CalculateDominators requires std::vector<BasicBlock*>.
|
||||
@ -139,23 +140,24 @@ class BasicBlockSuccessorHelper {
|
||||
// Build the successors and predecessors map for each basic blocks |f|.
|
||||
// If |invert_graph_| is true, all edges are reversed (successors becomes
|
||||
// predecessors and vice versa).
|
||||
// For convenience, the start of the graph is |dummy_start_node|.
|
||||
// For convenience, the start of the graph is |placeholder_start_node|.
|
||||
// The dominator tree construction requires a unique entry node, which cannot
|
||||
// be guaranteed for the postdominator graph. The |dummy_start_node| BB is
|
||||
// here to gather all entry nodes.
|
||||
void CreateSuccessorMap(Function& f, const BasicBlock* dummy_start_node);
|
||||
// be guaranteed for the postdominator graph. The |placeholder_start_node| BB
|
||||
// is here to gather all entry nodes.
|
||||
void CreateSuccessorMap(Function& f,
|
||||
const BasicBlock* placeholder_start_node);
|
||||
};
|
||||
|
||||
template <typename BBType>
|
||||
BasicBlockSuccessorHelper<BBType>::BasicBlockSuccessorHelper(
|
||||
Function& func, const BasicBlock* dummy_start_node, bool invert)
|
||||
Function& func, const BasicBlock* placeholder_start_node, bool invert)
|
||||
: invert_graph_(invert) {
|
||||
CreateSuccessorMap(func, dummy_start_node);
|
||||
CreateSuccessorMap(func, placeholder_start_node);
|
||||
}
|
||||
|
||||
template <typename BBType>
|
||||
void BasicBlockSuccessorHelper<BBType>::CreateSuccessorMap(
|
||||
Function& f, const BasicBlock* dummy_start_node) {
|
||||
Function& f, const BasicBlock* placeholder_start_node) {
|
||||
std::map<uint32_t, BasicBlock*> id_to_BB_map;
|
||||
auto GetSuccessorBasicBlock = [&f, &id_to_BB_map](uint32_t successor_id) {
|
||||
BasicBlock*& Succ = id_to_BB_map[successor_id];
|
||||
@ -173,11 +175,10 @@ void BasicBlockSuccessorHelper<BBType>::CreateSuccessorMap(
|
||||
if (invert_graph_) {
|
||||
// For the post dominator tree, we see the inverted graph.
|
||||
// successors_ in the inverted graph are the predecessors in the CFG.
|
||||
// The tree construction requires 1 entry point, so we add a dummy node
|
||||
// that is connected to all function exiting basic blocks.
|
||||
// An exiting basic block is a block with an OpKill, OpUnreachable,
|
||||
// OpReturn, OpReturnValue, or OpTerminateInvocation as terminator
|
||||
// instruction.
|
||||
// The tree construction requires 1 entry point, so we add a placeholder
|
||||
// node that is connected to all function exiting basic blocks. An exiting
|
||||
// basic block is a block with an OpKill, OpUnreachable, OpReturn,
|
||||
// OpReturnValue, or OpTerminateInvocation as terminator instruction.
|
||||
for (BasicBlock& bb : f) {
|
||||
if (bb.hasSuccessor()) {
|
||||
BasicBlockListTy& pred_list = predecessors_[&bb];
|
||||
@ -192,14 +193,15 @@ void BasicBlockSuccessorHelper<BBType>::CreateSuccessorMap(
|
||||
pred_list.push_back(succ);
|
||||
});
|
||||
} else {
|
||||
successors_[dummy_start_node].push_back(&bb);
|
||||
predecessors_[&bb].push_back(const_cast<BasicBlock*>(dummy_start_node));
|
||||
successors_[placeholder_start_node].push_back(&bb);
|
||||
predecessors_[&bb].push_back(
|
||||
const_cast<BasicBlock*>(placeholder_start_node));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
successors_[dummy_start_node].push_back(f.entry().get());
|
||||
successors_[placeholder_start_node].push_back(f.entry().get());
|
||||
predecessors_[f.entry().get()].push_back(
|
||||
const_cast<BasicBlock*>(dummy_start_node));
|
||||
const_cast<BasicBlock*>(placeholder_start_node));
|
||||
for (BasicBlock& bb : f) {
|
||||
BasicBlockListTy& succ_list = successors_[&bb];
|
||||
|
||||
@ -288,7 +290,7 @@ DominatorTreeNode* DominatorTree::GetOrInsertNode(BasicBlock* bb) {
|
||||
}
|
||||
|
||||
void DominatorTree::GetDominatorEdges(
|
||||
const Function* f, const BasicBlock* dummy_start_node,
|
||||
const Function* f, const BasicBlock* placeholder_start_node,
|
||||
std::vector<std::pair<BasicBlock*, BasicBlock*>>* edges) {
|
||||
// Each time the depth first traversal calls the postorder callback
|
||||
// std::function we push that node into the postorder vector to create our
|
||||
@ -302,7 +304,7 @@ void DominatorTree::GetDominatorEdges(
|
||||
// BB are derived from F, so we need to const cast it at some point
|
||||
// no modification is made on F.
|
||||
BasicBlockSuccessorHelper<BasicBlock> helper{
|
||||
*const_cast<Function*>(f), dummy_start_node, postdominator_};
|
||||
*const_cast<Function*>(f), placeholder_start_node, postdominator_};
|
||||
|
||||
// The successor function tells DepthFirstTraversal how to move to successive
|
||||
// nodes by providing an interface to get a list of successor nodes from any
|
||||
@ -316,7 +318,7 @@ void DominatorTree::GetDominatorEdges(
|
||||
// If we're building a post dominator tree we traverse the tree in reverse
|
||||
// using the predecessor function in place of the successor function and vice
|
||||
// versa.
|
||||
DepthFirstSearchPostOrder(dummy_start_node, successor_functor,
|
||||
DepthFirstSearchPostOrder(placeholder_start_node, successor_functor,
|
||||
postorder_function);
|
||||
*edges = CFA<BasicBlock>::CalculateDominators(postorder, predecessor_functor);
|
||||
}
|
||||
@ -329,12 +331,12 @@ void DominatorTree::InitializeTree(const CFG& cfg, const Function* f) {
|
||||
return;
|
||||
}
|
||||
|
||||
const BasicBlock* dummy_start_node =
|
||||
const BasicBlock* placeholder_start_node =
|
||||
postdominator_ ? cfg.pseudo_exit_block() : cfg.pseudo_entry_block();
|
||||
|
||||
// Get the immediate dominator for each node.
|
||||
std::vector<std::pair<BasicBlock*, BasicBlock*>> edges;
|
||||
GetDominatorEdges(f, dummy_start_node, &edges);
|
||||
GetDominatorEdges(f, placeholder_start_node, &edges);
|
||||
|
||||
// Transform the vector<pair> into the tree structure which we can use to
|
||||
// efficiently query dominance.
|
||||
@ -380,7 +382,7 @@ void DominatorTree::DumpTreeAsDot(std::ostream& out_stream) const {
|
||||
}
|
||||
|
||||
// Print the arrow from the parent to this node. Entry nodes will not have
|
||||
// parents so draw them as children from the dummy node.
|
||||
// parents so draw them as children from the placeholder node.
|
||||
if (node->parent_) {
|
||||
out_stream << node->parent_->bb_->id() << " -> " << node->bb_->id()
|
||||
<< ";\n";
|
||||
|
@ -601,15 +601,15 @@ class InstructionBuilder {
|
||||
return preserved_analyses_ & analysis;
|
||||
}
|
||||
|
||||
// Updates the def/use manager if the user requested it. If he did not request
|
||||
// an update, this function does nothing.
|
||||
// Updates the def/use manager if the user requested it. If an update was not
|
||||
// requested, this function does nothing.
|
||||
inline void UpdateDefUseMgr(Instruction* insn) {
|
||||
if (IsAnalysisUpdateRequested(IRContext::kAnalysisDefUse))
|
||||
GetContext()->get_def_use_mgr()->AnalyzeInstDefUse(insn);
|
||||
}
|
||||
|
||||
// Updates the instruction to block analysis if the user requested it. If he
|
||||
// did not request an update, this function does nothing.
|
||||
// Updates the instruction to block analysis if the user requested it. If
|
||||
// an update was not requested, this function does nothing.
|
||||
inline void UpdateInstrToBlockMapping(Instruction* insn) {
|
||||
if (IsAnalysisUpdateRequested(IRContext::kAnalysisInstrToBlockMapping) &&
|
||||
parent_)
|
||||
|
@ -511,7 +511,7 @@ void Loop::ComputeLoopStructuredOrder(
|
||||
}
|
||||
|
||||
LoopDescriptor::LoopDescriptor(IRContext* context, const Function* f)
|
||||
: loops_(), dummy_top_loop_(nullptr) {
|
||||
: loops_(), placeholder_top_loop_(nullptr) {
|
||||
PopulateList(context, f);
|
||||
}
|
||||
|
||||
@ -592,7 +592,7 @@ void LoopDescriptor::PopulateList(IRContext* context, const Function* f) {
|
||||
}
|
||||
}
|
||||
for (Loop* loop : loops_) {
|
||||
if (!loop->HasParent()) dummy_top_loop_.nested_loops_.push_back(loop);
|
||||
if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop);
|
||||
}
|
||||
}
|
||||
|
||||
@ -986,7 +986,7 @@ void LoopDescriptor::ClearLoops() {
|
||||
// Adds a new loop nest to the descriptor set.
|
||||
Loop* LoopDescriptor::AddLoopNest(std::unique_ptr<Loop> new_loop) {
|
||||
Loop* loop = new_loop.release();
|
||||
if (!loop->HasParent()) dummy_top_loop_.nested_loops_.push_back(loop);
|
||||
if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop);
|
||||
// Iterate from inner to outer most loop, adding basic block to loop mapping
|
||||
// as we go.
|
||||
for (Loop& current_loop :
|
||||
@ -1000,7 +1000,7 @@ Loop* LoopDescriptor::AddLoopNest(std::unique_ptr<Loop> new_loop) {
|
||||
}
|
||||
|
||||
void LoopDescriptor::RemoveLoop(Loop* loop) {
|
||||
Loop* parent = loop->GetParent() ? loop->GetParent() : &dummy_top_loop_;
|
||||
Loop* parent = loop->GetParent() ? loop->GetParent() : &placeholder_top_loop_;
|
||||
parent->nested_loops_.erase(std::find(parent->nested_loops_.begin(),
|
||||
parent->nested_loops_.end(), loop));
|
||||
std::for_each(
|
||||
|
@ -406,8 +406,8 @@ class Loop {
|
||||
// the iterators.
|
||||
bool loop_is_marked_for_removal_;
|
||||
|
||||
// This is only to allow LoopDescriptor::dummy_top_loop_ to add top level
|
||||
// loops as child.
|
||||
// This is only to allow LoopDescriptor::placeholder_top_loop_ to add top
|
||||
// level loops as child.
|
||||
friend class LoopDescriptor;
|
||||
friend class LoopUtils;
|
||||
};
|
||||
@ -430,14 +430,14 @@ class LoopDescriptor {
|
||||
// Disable copy constructor, to avoid double-free on destruction.
|
||||
LoopDescriptor(const LoopDescriptor&) = delete;
|
||||
// Move constructor.
|
||||
LoopDescriptor(LoopDescriptor&& other) : dummy_top_loop_(nullptr) {
|
||||
LoopDescriptor(LoopDescriptor&& other) : placeholder_top_loop_(nullptr) {
|
||||
// We need to take ownership of the Loop objects in the other
|
||||
// LoopDescriptor, to avoid double-free.
|
||||
loops_ = std::move(other.loops_);
|
||||
other.loops_.clear();
|
||||
basic_block_to_loop_ = std::move(other.basic_block_to_loop_);
|
||||
other.basic_block_to_loop_.clear();
|
||||
dummy_top_loop_ = std::move(other.dummy_top_loop_);
|
||||
placeholder_top_loop_ = std::move(other.placeholder_top_loop_);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@ -470,25 +470,27 @@ class LoopDescriptor {
|
||||
|
||||
// Iterators for post order depth first traversal of the loops.
|
||||
// Inner most loops will be visited first.
|
||||
inline iterator begin() { return iterator::begin(&dummy_top_loop_); }
|
||||
inline iterator end() { return iterator::end(&dummy_top_loop_); }
|
||||
inline iterator begin() { return iterator::begin(&placeholder_top_loop_); }
|
||||
inline iterator end() { return iterator::end(&placeholder_top_loop_); }
|
||||
inline const_iterator begin() const { return cbegin(); }
|
||||
inline const_iterator end() const { return cend(); }
|
||||
inline const_iterator cbegin() const {
|
||||
return const_iterator::begin(&dummy_top_loop_);
|
||||
return const_iterator::begin(&placeholder_top_loop_);
|
||||
}
|
||||
inline const_iterator cend() const {
|
||||
return const_iterator::end(&dummy_top_loop_);
|
||||
return const_iterator::end(&placeholder_top_loop_);
|
||||
}
|
||||
|
||||
// Iterators for pre-order depth first traversal of the loops.
|
||||
// Inner most loops will be visited first.
|
||||
inline pre_iterator pre_begin() { return ++pre_iterator(&dummy_top_loop_); }
|
||||
inline pre_iterator pre_begin() {
|
||||
return ++pre_iterator(&placeholder_top_loop_);
|
||||
}
|
||||
inline pre_iterator pre_end() { return pre_iterator(); }
|
||||
inline const_pre_iterator pre_begin() const { return pre_cbegin(); }
|
||||
inline const_pre_iterator pre_end() const { return pre_cend(); }
|
||||
inline const_pre_iterator pre_cbegin() const {
|
||||
return ++const_pre_iterator(&dummy_top_loop_);
|
||||
return ++const_pre_iterator(&placeholder_top_loop_);
|
||||
}
|
||||
inline const_pre_iterator pre_cend() const { return const_pre_iterator(); }
|
||||
|
||||
@ -524,14 +526,14 @@ class LoopDescriptor {
|
||||
void RemoveLoop(Loop* loop);
|
||||
|
||||
void SetAsTopLoop(Loop* loop) {
|
||||
assert(std::find(dummy_top_loop_.begin(), dummy_top_loop_.end(), loop) ==
|
||||
dummy_top_loop_.end() &&
|
||||
assert(std::find(placeholder_top_loop_.begin(), placeholder_top_loop_.end(),
|
||||
loop) == placeholder_top_loop_.end() &&
|
||||
"already registered");
|
||||
dummy_top_loop_.nested_loops_.push_back(loop);
|
||||
placeholder_top_loop_.nested_loops_.push_back(loop);
|
||||
}
|
||||
|
||||
Loop* GetDummyRootLoop() { return &dummy_top_loop_; }
|
||||
const Loop* GetDummyRootLoop() const { return &dummy_top_loop_; }
|
||||
Loop* GetPlaceholderRootLoop() { return &placeholder_top_loop_; }
|
||||
const Loop* GetPlaceholderRootLoop() const { return &placeholder_top_loop_; }
|
||||
|
||||
private:
|
||||
// TODO(dneto): This should be a vector of unique_ptr. But VisualStudio 2013
|
||||
@ -558,8 +560,8 @@ class LoopDescriptor {
|
||||
// objects.
|
||||
LoopContainerType loops_;
|
||||
|
||||
// Dummy root: this "loop" is only there to help iterators creation.
|
||||
Loop dummy_top_loop_;
|
||||
// Placeholder root: this "loop" is only there to help iterators creation.
|
||||
Loop placeholder_top_loop_;
|
||||
|
||||
std::unordered_map<uint32_t, Loop*> basic_block_to_loop_;
|
||||
|
||||
|
@ -674,21 +674,21 @@ void LoopUnrollerUtilsImpl::CopyBody(Loop* loop, bool eliminate_conditions) {
|
||||
std::vector<Instruction*> inductions;
|
||||
loop->GetInductionVariables(inductions);
|
||||
for (size_t index = 0; index < inductions.size(); ++index) {
|
||||
Instruction* master_copy = inductions[index];
|
||||
Instruction* primary_copy = inductions[index];
|
||||
|
||||
assert(master_copy->result_id() != 0);
|
||||
assert(primary_copy->result_id() != 0);
|
||||
Instruction* induction_clone =
|
||||
state_.ids_to_new_inst[state_.new_inst[master_copy->result_id()]];
|
||||
state_.ids_to_new_inst[state_.new_inst[primary_copy->result_id()]];
|
||||
|
||||
state_.new_phis_.push_back(induction_clone);
|
||||
assert(induction_clone->result_id() != 0);
|
||||
|
||||
if (!state_.previous_phis_.empty()) {
|
||||
state_.new_inst[master_copy->result_id()] = GetPhiDefID(
|
||||
state_.new_inst[primary_copy->result_id()] = GetPhiDefID(
|
||||
state_.previous_phis_[index], state_.previous_latch_block_->id());
|
||||
} else {
|
||||
// Do not replace the first phi block ids.
|
||||
state_.new_inst[master_copy->result_id()] = master_copy->result_id();
|
||||
state_.new_inst[primary_copy->result_id()] = primary_copy->result_id();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,8 +594,8 @@ bool LoopUnswitchPass::ProcessFunction(Function* f) {
|
||||
bool loop_changed = true;
|
||||
while (loop_changed) {
|
||||
loop_changed = false;
|
||||
for (Loop& loop :
|
||||
make_range(++TreeDFIterator<Loop>(loop_descriptor.GetDummyRootLoop()),
|
||||
for (Loop& loop : make_range(
|
||||
++TreeDFIterator<Loop>(loop_descriptor.GetPlaceholderRootLoop()),
|
||||
TreeDFIterator<Loop>())) {
|
||||
if (processed_loop.count(&loop)) continue;
|
||||
processed_loop.insert(&loop);
|
||||
|
@ -111,7 +111,7 @@ bool MergeReturnPass::ProcessStructured(
|
||||
}
|
||||
|
||||
RecordImmediateDominators(function);
|
||||
AddDummySwitchAroundFunction();
|
||||
AddSingleCaseSwitchAroundFunction();
|
||||
|
||||
std::list<BasicBlock*> order;
|
||||
cfg()->ComputeStructuredOrder(function, &*function->begin(), &order);
|
||||
@ -223,7 +223,8 @@ void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) {
|
||||
|
||||
if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue ||
|
||||
tail_opcode == SpvOpUnreachable) {
|
||||
assert(CurrentState().InBreakable() && "Should be in the dummy construct.");
|
||||
assert(CurrentState().InBreakable() &&
|
||||
"Should be in the placeholder construct.");
|
||||
BranchToBlock(block, CurrentState().BreakMergeId());
|
||||
return_blocks_.insert(block->id());
|
||||
}
|
||||
@ -408,7 +409,7 @@ bool MergeReturnPass::PredicateBlocks(
|
||||
if (!predicated->insert(block).second) break;
|
||||
// Skip structured subgraphs.
|
||||
assert(state->InBreakable() &&
|
||||
"Should be in the dummy construct at the very least.");
|
||||
"Should be in the placeholder construct at the very least.");
|
||||
Instruction* break_merge_inst = state->BreakMergeInst();
|
||||
uint32_t merge_block_id = break_merge_inst->GetSingleWordInOperand(0);
|
||||
while (state->BreakMergeId() == merge_block_id) {
|
||||
@ -768,7 +769,7 @@ void MergeReturnPass::InsertAfterElement(BasicBlock* element,
|
||||
list->insert(pos, new_element);
|
||||
}
|
||||
|
||||
void MergeReturnPass::AddDummySwitchAroundFunction() {
|
||||
void MergeReturnPass::AddSingleCaseSwitchAroundFunction() {
|
||||
CreateReturnBlock();
|
||||
CreateReturn(final_return_block_);
|
||||
|
||||
@ -776,7 +777,7 @@ void MergeReturnPass::AddDummySwitchAroundFunction() {
|
||||
cfg()->RegisterBlock(final_return_block_);
|
||||
}
|
||||
|
||||
CreateDummySwitch(final_return_block_);
|
||||
CreateSingleCaseSwitch(final_return_block_);
|
||||
}
|
||||
|
||||
BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) {
|
||||
@ -811,7 +812,7 @@ BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) {
|
||||
return new_block;
|
||||
}
|
||||
|
||||
void MergeReturnPass::CreateDummySwitch(BasicBlock* merge_target) {
|
||||
void MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) {
|
||||
// Insert the switch before any code is run. We have to split the entry
|
||||
// block to make sure the OpVariable instructions remain in the entry block.
|
||||
BasicBlock* start_block = &*function_->begin();
|
||||
|
@ -48,13 +48,13 @@ namespace opt {
|
||||
* is the final return. This block should branch to the new return block (its
|
||||
* direct successor). If the current block is within structured control flow,
|
||||
* the branch destination should be the innermost construct's merge. This
|
||||
* merge will always exist because a dummy switch is added around the
|
||||
* merge will always exist because a single case switch is added around the
|
||||
* entire function. If the merge block produces any live values it will need to
|
||||
* be predicated. While the merge is nested in structured control flow, the
|
||||
* predication path should branch to the merge block of the inner-most loop
|
||||
* (or switch if no loop) it is contained in. Once structured control flow has
|
||||
* been exited, it will be at the merge of the dummy switch, which will simply
|
||||
* return.
|
||||
* been exited, it will be at the merge of the single case switch, which will
|
||||
* simply return.
|
||||
*
|
||||
* In the final return block, the return value should be loaded and returned.
|
||||
* Memory promotion passes should be able to promote the newly introduced
|
||||
@ -73,7 +73,7 @@ namespace opt {
|
||||
* ||
|
||||
* \/
|
||||
*
|
||||
* 0 (dummy switch header)
|
||||
* 0 (single case switch header)
|
||||
* |
|
||||
* 1 (loop header)
|
||||
* / \
|
||||
@ -83,7 +83,7 @@ namespace opt {
|
||||
* / \
|
||||
* | 3 (original code in 3)
|
||||
* \ /
|
||||
* (ret) 4 (dummy switch merge)
|
||||
* (ret) 4 (single case switch merge)
|
||||
*
|
||||
* In the above (simple) example, the return originally in |2| is passed through
|
||||
* the loop merge. That merge is predicated such that the old body of the block
|
||||
@ -277,7 +277,7 @@ class MergeReturnPass : public MemPass {
|
||||
// current function where the switch and case value are both zero and the
|
||||
// default is the merge block. Returns after the switch is executed. Sets
|
||||
// |final_return_block_|.
|
||||
void AddDummySwitchAroundFunction();
|
||||
void AddSingleCaseSwitchAroundFunction();
|
||||
|
||||
// Creates a new basic block that branches to |header_label_id|. Returns the
|
||||
// new basic block. The block will be the second last basic block in the
|
||||
@ -286,7 +286,7 @@ class MergeReturnPass : public MemPass {
|
||||
|
||||
// Creates a one case switch around the executable code of the function with
|
||||
// |merge_target| as the merge node.
|
||||
void CreateDummySwitch(BasicBlock* merge_target);
|
||||
void CreateSingleCaseSwitch(BasicBlock* merge_target);
|
||||
|
||||
// Returns true if |function| has an unreachable block that is not a continue
|
||||
// target that simply branches back to the header, or a merge block containing
|
||||
|
@ -163,7 +163,7 @@ class ComputeRegisterLiveness {
|
||||
|
||||
// Propagates the register liveness information of each loop iterators.
|
||||
void DoLoopLivenessUnification() {
|
||||
for (const Loop* loop : *loop_desc_.GetDummyRootLoop()) {
|
||||
for (const Loop* loop : *loop_desc_.GetPlaceholderRootLoop()) {
|
||||
DoLoopLivenessUnification(*loop);
|
||||
}
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ class StructuredLoopToSelectionReductionOpportunity
|
||||
void ChangeLoopToSelection();
|
||||
|
||||
// Fixes any scenarios where, due to CFG changes, ids have uses not dominated
|
||||
// by their definitions, by changing such uses to uses of OpUndef or of dummy
|
||||
// variables.
|
||||
// by their definitions, by changing such uses to uses of OpUndef or of
|
||||
// placeholder variables.
|
||||
void FixNonDominatedIdUses();
|
||||
|
||||
// Returns true if and only if at least one of the following holds:
|
||||
|
@ -33,7 +33,7 @@ namespace {
|
||||
// Performs compile time check that all SpvImageOperandsXXX cases are handled in
|
||||
// this module. If SpvImageOperandsXXX list changes, this function will fail the
|
||||
// build.
|
||||
// For all other purposes this is a dummy function.
|
||||
// For all other purposes this is a placeholder function.
|
||||
bool CheckAllImageOperandsHandled() {
|
||||
SpvImageOperandsMask enum_val = SpvImageOperandsBiasMask;
|
||||
|
||||
|
@ -1635,7 +1635,7 @@ TEST_F(InlineTest, SingleBlockLoopCallsMultiBlockCalleeHavingSelectionMerge) {
|
||||
// the OpSelectionMerge, so inlining must create a new block to contain
|
||||
// the callee contents.
|
||||
//
|
||||
// Additionally, we have two dummy OpCopyObject instructions to prove that
|
||||
// Additionally, we have two extra OpCopyObject instructions to prove that
|
||||
// the OpLoopMerge is moved to the right location.
|
||||
//
|
||||
// Also ensure that OpPhis within the cloned callee code are valid.
|
||||
|
@ -37,22 +37,22 @@ using Analysis = IRContext::Analysis;
|
||||
using ::testing::Each;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
|
||||
class DummyPassPreservesNothing : public Pass {
|
||||
class NoopPassPreservesNothing : public Pass {
|
||||
public:
|
||||
DummyPassPreservesNothing(Status s) : Pass(), status_to_return_(s) {}
|
||||
NoopPassPreservesNothing(Status s) : Pass(), status_to_return_(s) {}
|
||||
|
||||
const char* name() const override { return "dummy-pass"; }
|
||||
const char* name() const override { return "noop-pass"; }
|
||||
Status Process() override { return status_to_return_; }
|
||||
|
||||
private:
|
||||
Status status_to_return_;
|
||||
};
|
||||
|
||||
class DummyPassPreservesAll : public Pass {
|
||||
class NoopPassPreservesAll : public Pass {
|
||||
public:
|
||||
DummyPassPreservesAll(Status s) : Pass(), status_to_return_(s) {}
|
||||
NoopPassPreservesAll(Status s) : Pass(), status_to_return_(s) {}
|
||||
|
||||
const char* name() const override { return "dummy-pass"; }
|
||||
const char* name() const override { return "noop-pass"; }
|
||||
Status Process() override { return status_to_return_; }
|
||||
|
||||
Analysis GetPreservedAnalyses() override {
|
||||
@ -63,11 +63,11 @@ class DummyPassPreservesAll : public Pass {
|
||||
Status status_to_return_;
|
||||
};
|
||||
|
||||
class DummyPassPreservesFirst : public Pass {
|
||||
class NoopPassPreservesFirst : public Pass {
|
||||
public:
|
||||
DummyPassPreservesFirst(Status s) : Pass(), status_to_return_(s) {}
|
||||
NoopPassPreservesFirst(Status s) : Pass(), status_to_return_(s) {}
|
||||
|
||||
const char* name() const override { return "dummy-pass"; }
|
||||
const char* name() const override { return "noop-pass"; }
|
||||
Status Process() override { return status_to_return_; }
|
||||
|
||||
Analysis GetPreservedAnalyses() override { return IRContext::kAnalysisBegin; }
|
||||
@ -116,7 +116,7 @@ TEST_F(IRContextTest, AllValidAfterPassNoChange) {
|
||||
built_analyses |= i;
|
||||
}
|
||||
|
||||
DummyPassPreservesNothing pass(Pass::Status::SuccessWithoutChange);
|
||||
NoopPassPreservesNothing pass(Pass::Status::SuccessWithoutChange);
|
||||
Pass::Status s = pass.Run(&localContext);
|
||||
EXPECT_EQ(s, Pass::Status::SuccessWithoutChange);
|
||||
EXPECT_TRUE(localContext.AreAnalysesValid(built_analyses));
|
||||
@ -132,7 +132,7 @@ TEST_F(IRContextTest, NoneValidAfterPassWithChange) {
|
||||
localContext.BuildInvalidAnalyses(i);
|
||||
}
|
||||
|
||||
DummyPassPreservesNothing pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesNothing pass(Pass::Status::SuccessWithChange);
|
||||
Pass::Status s = pass.Run(&localContext);
|
||||
EXPECT_EQ(s, Pass::Status::SuccessWithChange);
|
||||
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
|
||||
@ -151,7 +151,7 @@ TEST_F(IRContextTest, AllPreservedAfterPassWithChange) {
|
||||
localContext.BuildInvalidAnalyses(i);
|
||||
}
|
||||
|
||||
DummyPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
Pass::Status s = pass.Run(&localContext);
|
||||
EXPECT_EQ(s, Pass::Status::SuccessWithChange);
|
||||
for (Analysis i = IRContext::kAnalysisBegin; i < IRContext::kAnalysisEnd;
|
||||
@ -170,7 +170,7 @@ TEST_F(IRContextTest, PreserveFirstOnlyAfterPassWithChange) {
|
||||
localContext.BuildInvalidAnalyses(i);
|
||||
}
|
||||
|
||||
DummyPassPreservesFirst pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesFirst pass(Pass::Status::SuccessWithChange);
|
||||
Pass::Status s = pass.Run(&localContext);
|
||||
EXPECT_EQ(s, Pass::Status::SuccessWithChange);
|
||||
EXPECT_TRUE(localContext.AreAnalysesValid(IRContext::kAnalysisBegin));
|
||||
@ -912,7 +912,7 @@ OpFunctionEnd)";
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
||||
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
ctx->BuildInvalidAnalyses(IRContext::kAnalysisDebugInfo);
|
||||
DummyPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
pass.Run(ctx.get());
|
||||
EXPECT_TRUE(ctx->AreAnalysesValid(IRContext::kAnalysisDebugInfo));
|
||||
|
||||
@ -978,7 +978,7 @@ OpFunctionEnd)";
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
||||
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
ctx->BuildInvalidAnalyses(IRContext::kAnalysisDebugInfo);
|
||||
DummyPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
pass.Run(ctx.get());
|
||||
EXPECT_TRUE(ctx->AreAnalysesValid(IRContext::kAnalysisDebugInfo));
|
||||
|
||||
@ -1055,7 +1055,7 @@ OpFunctionEnd)";
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
||||
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
ctx->BuildInvalidAnalyses(IRContext::kAnalysisDebugInfo);
|
||||
DummyPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
NoopPassPreservesAll pass(Pass::Status::SuccessWithChange);
|
||||
pass.Run(ctx.get());
|
||||
EXPECT_TRUE(ctx->AreAnalysesValid(IRContext::kAnalysisDebugInfo));
|
||||
|
||||
|
@ -534,7 +534,7 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowAddPhi) {
|
||||
; CHECK: [[true:%\w+]] = OpConstantTrue
|
||||
; CHECK: OpFunction
|
||||
; CHECK: [[var:%\w+]] = OpVariable [[:%\w+]] Function [[false]]
|
||||
; CHECK: OpSelectionMerge [[dummy_loop_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[single_case_switch_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[merge_lab:%\w+]]
|
||||
; CHECK: OpBranchConditional [[cond:%\w+]] [[if_lab:%\w+]] [[then_lab:%\w+]]
|
||||
; CHECK: [[if_lab]] = OpLabel
|
||||
@ -542,9 +542,9 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowAddPhi) {
|
||||
; CHECK-NEXT: OpBranch
|
||||
; CHECK: [[then_lab]] = OpLabel
|
||||
; CHECK-NEXT: OpStore [[var]] [[true]]
|
||||
; CHECK-NEXT: OpBranch [[dummy_loop_merge]]
|
||||
; CHECK-NEXT: OpBranch [[single_case_switch_merge]]
|
||||
; CHECK: [[merge_lab]] = OpLabel
|
||||
; CHECK: [[dummy_loop_merge]] = OpLabel
|
||||
; CHECK: [[single_case_switch_merge]] = OpLabel
|
||||
; CHECK-NEXT: OpReturn
|
||||
OpCapability Addresses
|
||||
OpCapability Shader
|
||||
@ -631,10 +631,10 @@ TEST_F(MergeReturnPassTest, SplitBlockUsedInPhi) {
|
||||
const std::string before =
|
||||
R"(
|
||||
; CHECK: OpFunction
|
||||
; CHECK: OpSelectionMerge [[dummy_loop_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[single_case_switch_merge:%\w+]]
|
||||
; CHECK: OpLoopMerge [[loop_merge:%\w+]]
|
||||
; CHECK: [[loop_merge]] = OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[dummy_loop_merge]] [[old_code_path:%\w+]]
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[single_case_switch_merge]] [[old_code_path:%\w+]]
|
||||
; CHECK: [[old_code_path:%\w+]] = OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[side_node:%\w+]] [[phi_block:%\w+]]
|
||||
; CHECK: [[phi_block]] = OpLabel
|
||||
@ -828,7 +828,7 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowBothMergeAndHeader) {
|
||||
R"(
|
||||
; CHECK: OpFunction
|
||||
; CHECK: [[ret_flag:%\w+]] = OpVariable %_ptr_Function_bool Function %false
|
||||
; CHECK: OpSelectionMerge [[dummy_loop_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[single_case_switch_merge:%\w+]]
|
||||
; CHECK: OpLoopMerge [[loop1_merge:%\w+]] {{%\w+}}
|
||||
; CHECK-NEXT: OpBranchConditional {{%\w+}} [[if_lab:%\w+]] {{%\w+}}
|
||||
; CHECK: [[if_lab]] = OpLabel
|
||||
@ -837,7 +837,7 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowBothMergeAndHeader) {
|
||||
; CHECK: [[loop1_merge]] = OpLabel
|
||||
; CHECK-NEXT: [[ld:%\w+]] = OpLoad %bool [[ret_flag]]
|
||||
; CHECK-NOT: OpLabel
|
||||
; CHECK: OpBranchConditional [[ld]] [[dummy_loop_merge]] [[empty_block:%\w+]]
|
||||
; CHECK: OpBranchConditional [[ld]] [[single_case_switch_merge]] [[empty_block:%\w+]]
|
||||
; CHECK: [[empty_block]] = OpLabel
|
||||
; CHECK-NEXT: OpBranch [[loop2:%\w+]]
|
||||
; CHECK: [[loop2]] = OpLabel
|
||||
@ -1217,7 +1217,7 @@ TEST_F(MergeReturnPassTest, NestedLoopMerge) {
|
||||
const std::string test =
|
||||
R"(
|
||||
; CHECK: OpFunction
|
||||
; CHECK: OpSelectionMerge [[dummy_loop_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[single_case_switch_merge:%\w+]]
|
||||
; CHECK: OpLoopMerge [[outer_loop_merge:%\w+]]
|
||||
; CHECK: OpLoopMerge [[inner_loop_merge:%\w+]]
|
||||
; CHECK: OpSelectionMerge
|
||||
@ -1230,8 +1230,8 @@ TEST_F(MergeReturnPassTest, NestedLoopMerge) {
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[outer_loop_merge]]
|
||||
; CHECK: [[outer_loop_merge]] = OpLabel
|
||||
; CHECK-NOT: OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[dummy_loop_merge]]
|
||||
; CHECK: [[dummy_loop_merge]] = OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[single_case_switch_merge]]
|
||||
; CHECK: [[single_case_switch_merge]] = OpLabel
|
||||
; CHECK-NOT: OpLabel
|
||||
; CHECK: OpReturn
|
||||
OpCapability SampledBuffer
|
||||
@ -2145,12 +2145,12 @@ TEST_F(MergeReturnPassTest, PhiInSecondMerge) {
|
||||
}
|
||||
|
||||
TEST_F(MergeReturnPassTest, ReturnsInSwitch) {
|
||||
// Cannot branch directly to dummy switch merge block from original switch.
|
||||
// Must branch to merge block of original switch and then do predicated
|
||||
// branch to merge block of dummy switch.
|
||||
// Cannot branch directly to single case switch merge block from original
|
||||
// switch. Must branch to merge block of original switch and then do
|
||||
// predicated branch to merge block of single case switch.
|
||||
const std::string text =
|
||||
R"(
|
||||
; CHECK: OpSelectionMerge [[dummy_merge_bb:%\w+]]
|
||||
; CHECK: OpSelectionMerge [[single_case_switch_merge_bb:%\w+]]
|
||||
; CHECK-NEXT: OpSwitch {{%\w+}} [[def_bb1:%\w+]]
|
||||
; CHECK-NEXT: [[def_bb1]] = OpLabel
|
||||
; CHECK: OpSelectionMerge
|
||||
@ -2158,7 +2158,7 @@ TEST_F(MergeReturnPassTest, ReturnsInSwitch) {
|
||||
; CHECK: OpBranch [[inner_merge_bb]]
|
||||
; CHECK: OpBranch [[inner_merge_bb]]
|
||||
; CHECK-NEXT: [[inner_merge_bb]] = OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[dummy_merge_bb]] {{%\w+}}
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[single_case_switch_merge_bb]] {{%\w+}}
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
|
@ -25,7 +25,7 @@ using opt::Function;
|
||||
using opt::Instruction;
|
||||
using opt::IRContext;
|
||||
|
||||
// A dumb reduction opportunity finder that finds opportunities to remove global
|
||||
// A reduction opportunity finder that finds opportunities to remove global
|
||||
// values regardless of whether they are referenced. This is very likely to make
|
||||
// the resulting module invalid. We use this to test the reducer's behavior in
|
||||
// the scenario where a bad reduction pass leads to an invalid module.
|
||||
@ -55,7 +55,7 @@ class BlindlyRemoveGlobalValuesReductionOpportunityFinder
|
||||
}
|
||||
};
|
||||
|
||||
// A dumb reduction opportunity that exists at the start of every function whose
|
||||
// A reduction opportunity that exists at the start of every function whose
|
||||
// first instruction is an OpVariable instruction. When applied, the OpVariable
|
||||
// instruction is duplicated (with a fresh result id). This allows each
|
||||
// reduction step to increase the number of variables to check if the validator
|
||||
|
@ -324,7 +324,7 @@ OpBranch %end_label
|
||||
%false_label = OpLabel
|
||||
OpBranch %end_label
|
||||
%end_label = OpLabel
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
%result = OpPhi %bool %true %true_label %false %false_label
|
||||
)";
|
||||
|
||||
@ -350,7 +350,7 @@ OpBranch %end_label
|
||||
OpBranch %end_label
|
||||
%end_label = OpLabel
|
||||
%result1 = OpPhi %bool %true %true_label %false %false_label
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
%result2 = OpPhi %bool %true %true_label %false %false_label
|
||||
)";
|
||||
|
||||
@ -377,7 +377,7 @@ OpBranch %end_label
|
||||
%end_label = OpLabel
|
||||
OpLine %string 0 0
|
||||
%result = OpPhi %bool %true %true_label %false %false_label
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
)";
|
||||
|
||||
const std::string extra = R"(OpCapability Shader
|
||||
@ -411,7 +411,7 @@ OpExecutionMode %main OriginUpperLeft
|
||||
%paramfunc_type = OpTypeFunction %void %int %int
|
||||
|
||||
%paramfunc = OpFunction %void None %paramfunc_type
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
%a = OpFunctionParameter %int
|
||||
%b = OpFunctionParameter %int
|
||||
%paramfunc_entry = OpLabel
|
||||
@ -454,7 +454,7 @@ OpExecutionMode %main OriginUpperLeft
|
||||
|
||||
%paramfunc = OpFunction %void None %paramfunc_type
|
||||
%a = OpFunctionParameter %int
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
%b = OpFunctionParameter %int
|
||||
%paramfunc_entry = OpLabel
|
||||
OpReturn
|
||||
@ -498,7 +498,7 @@ OpExecutionMode %main OriginUpperLeft
|
||||
%a = OpFunctionParameter %int
|
||||
%b = OpFunctionParameter %int
|
||||
%paramfunc_entry = OpLabel
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
||||
@ -540,7 +540,7 @@ OpExecutionMode %main OriginUpperLeft
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
||||
%dummy = OpExtInst %void %extinst 123 %int_1
|
||||
%placeholder = OpExtInst %void %extinst 123 %int_1
|
||||
|
||||
%main = OpFunction %void None %func
|
||||
%main_entry = OpLabel
|
||||
|
@ -1063,10 +1063,10 @@ std::string GetUnreachableMergeWithComplexBody(SpvCapability cap,
|
||||
Block merge("merge", SpvOpUnreachable);
|
||||
|
||||
entry.AppendBody(spvIsWebGPUEnv(env)
|
||||
? "%dummy = OpVariable %intptrt Function %two\n"
|
||||
: "%dummy = OpVariable %intptrt Function\n");
|
||||
? "%placeholder = OpVariable %intptrt Function %two\n"
|
||||
: "%placeholder = OpVariable %intptrt Function\n");
|
||||
entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n");
|
||||
merge.AppendBody("OpStore %dummy %one\n");
|
||||
merge.AppendBody("OpStore %placeholder %one\n");
|
||||
|
||||
std::string str = header;
|
||||
if (spvIsWebGPUEnv(env)) {
|
||||
@ -1120,9 +1120,9 @@ std::string GetUnreachableContinueWithComplexBody(SpvCapability cap,
|
||||
target >> branch;
|
||||
|
||||
entry.AppendBody(spvIsWebGPUEnv(env)
|
||||
? "%dummy = OpVariable %intptrt Function %two\n"
|
||||
: "%dummy = OpVariable %intptrt Function\n");
|
||||
target.AppendBody("OpStore %dummy %one\n");
|
||||
? "%placeholder = OpVariable %intptrt Function %two\n"
|
||||
: "%placeholder = OpVariable %intptrt Function\n");
|
||||
target.AppendBody("OpStore %placeholder %one\n");
|
||||
|
||||
std::string str = header;
|
||||
if (spvIsWebGPUEnv(env)) {
|
||||
@ -1279,8 +1279,8 @@ std::string GetUnreachableContinueWithBranchUse(SpvCapability cap,
|
||||
target >> branch;
|
||||
|
||||
entry.AppendBody(spvIsWebGPUEnv(env)
|
||||
? "%dummy = OpVariable %intptrt Function %two\n"
|
||||
: "%dummy = OpVariable %intptrt Function\n");
|
||||
? "%placeholder = OpVariable %intptrt Function %two\n"
|
||||
: "%placeholder = OpVariable %intptrt Function\n");
|
||||
|
||||
std::string str = header;
|
||||
if (spvIsWebGPUEnv(env)) {
|
||||
|
@ -77,7 +77,7 @@ OpFunctionEnd)";
|
||||
std::string CallAndCallee(const std::string& body) {
|
||||
std::ostringstream ss;
|
||||
ss << R"(
|
||||
%dummy = OpFunctionCall %void %foo
|
||||
%placeholder = OpFunctionCall %void %foo
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user