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