mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2025-01-11 09:00:06 +00:00
BasicBlock: add ctail, GetMergeInst, GetLoopMergeInst
This commit is contained in:
parent
e6279cde7a
commit
cff2cd3343
@ -17,6 +17,54 @@
|
||||
namespace spvtools {
|
||||
namespace ir {
|
||||
|
||||
const Instruction* BasicBlock::GetMergeInst() const {
|
||||
const Instruction* result = nullptr;
|
||||
// If it exists, the merge instruction immediately precedes the
|
||||
// terminator.
|
||||
auto iter = ctail();
|
||||
if (iter != cbegin()) {
|
||||
--iter;
|
||||
const auto opcode = iter->opcode();
|
||||
if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
|
||||
result = &*iter;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Instruction* BasicBlock::GetMergeInst() {
|
||||
Instruction* result = nullptr;
|
||||
// If it exists, the merge instruction immediately precedes the
|
||||
// terminator.
|
||||
auto iter = tail();
|
||||
if (iter != begin()) {
|
||||
--iter;
|
||||
const auto opcode = iter->opcode();
|
||||
if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
|
||||
result = &*iter;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const Instruction* BasicBlock::GetLoopMergeInst() const {
|
||||
if (auto* merge = GetMergeInst()) {
|
||||
if (merge->opcode() == SpvOpLoopMerge) {
|
||||
return merge;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Instruction* BasicBlock::GetLoopMergeInst() {
|
||||
if (auto* merge = GetMergeInst()) {
|
||||
if (merge->opcode() == SpvOpLoopMerge) {
|
||||
return merge;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BasicBlock::ForEachSuccessorLabel(
|
||||
const std::function<void(const uint32_t)>& f) {
|
||||
const auto br = &*insts_.back();
|
||||
|
@ -52,6 +52,15 @@ class BasicBlock {
|
||||
// The label starting this basic block.
|
||||
Instruction* GetLabelInst() { return label_.get(); }
|
||||
|
||||
// Returns the merge instruction in this basic block, if it exists.
|
||||
// Otherwise return null. May be used whenever tail() can be used.
|
||||
const Instruction* GetMergeInst() const;
|
||||
Instruction* GetMergeInst();
|
||||
// Returns the OpLoopMerge instruciton in this basic block, if it exists.
|
||||
// Otherwise return null. May be used whenever tail() can be used.
|
||||
const Instruction* GetLoopMergeInst() const;
|
||||
Instruction* GetLoopMergeInst();
|
||||
|
||||
// Returns the id of the label at the top of this block
|
||||
inline uint32_t id() const { return label_->result_id(); }
|
||||
|
||||
@ -64,10 +73,18 @@ class BasicBlock {
|
||||
return const_iterator(&insts_, insts_.cend());
|
||||
}
|
||||
|
||||
// Returns an iterator pointing to the last instruction. This may only
|
||||
// be used if this block has an instruction other than the OpLabel
|
||||
// that defines it.
|
||||
iterator tail() {
|
||||
assert(!insts_.empty());
|
||||
return iterator(&insts_, std::prev(insts_.end()));
|
||||
}
|
||||
// Returns a const iterator, but othewrise similar to tail().
|
||||
const_iterator ctail() const {
|
||||
assert(!insts_.empty());
|
||||
return const_iterator(&insts_, std::prev(insts_.cend()));
|
||||
}
|
||||
|
||||
// Runs the given function |f| on each instruction in this basic block, and
|
||||
// optionally on the debug line instructions that might precede them.
|
||||
|
Loading…
Reference in New Issue
Block a user