BasicBlock: add ctail, GetMergeInst, GetLoopMergeInst

This commit is contained in:
David Neto 2017-08-31 11:37:17 -04:00
parent e6279cde7a
commit cff2cd3343
2 changed files with 65 additions and 0 deletions

View File

@ -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();

View File

@ -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.