aboutsummaryrefslogtreecommitdiff
path: root/source/opt/def_use_manager.cpp
diff options
context:
space:
mode:
authorAlan Baker <alanbaker@google.com>2018-01-12 15:05:53 -0500
committerDavid Neto <dneto@google.com>2018-01-12 17:05:09 -0500
commit6587d3f8a31b636c0d75b32d5ae65d338581c200 (patch)
treebd0666573488201551e07e2ee1c39c7603fa1e48 /source/opt/def_use_manager.cpp
parent24f9947050d6e69bccc0061473216075980978e8 (diff)
downloadspirv-tools-6587d3f8a31b636c0d75b32d5ae65d338581c200.tar.gz
Adding early exit versions of several ForEach* methods
* Looked through code for instances where code would benefit from early exit * Added a corresponding WhileEach* method and updated the code
Diffstat (limited to 'source/opt/def_use_manager.cpp')
-rw-r--r--source/opt/def_use_manager.cpp45
1 files changed, 39 insertions, 6 deletions
diff --git a/source/opt/def_use_manager.cpp b/source/opt/def_use_manager.cpp
index 3dbc51aa..2b1b00c1 100644
--- a/source/opt/def_use_manager.cpp
+++ b/source/opt/def_use_manager.cpp
@@ -96,16 +96,31 @@ bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter,
return UsersNotEnd(iter, id_to_users_.end(), inst);
}
-void DefUseManager::ForEachUser(
+bool DefUseManager::WhileEachUser(
const ir::Instruction* def,
- const std::function<void(ir::Instruction*)>& f) const {
+ const std::function<bool(ir::Instruction*)>& f) const {
// Ensure that |def| has been registered.
assert(def && def == GetDef(def->result_id()) &&
"Definition is not registered.");
auto end = id_to_users_.end();
for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) {
- f(iter->second);
+ if (!f(iter->second)) return false;
}
+ return true;
+}
+
+bool DefUseManager::WhileEachUser(
+ uint32_t id, const std::function<bool(ir::Instruction*)>& f) const {
+ return WhileEachUser(GetDef(id), f);
+}
+
+void DefUseManager::ForEachUser(
+ const ir::Instruction* def,
+ const std::function<void(ir::Instruction*)>& f) const {
+ WhileEachUser(def, [&f](ir::Instruction* user) {
+ f(user);
+ return true;
+ });
}
void DefUseManager::ForEachUser(
@@ -113,9 +128,9 @@ void DefUseManager::ForEachUser(
ForEachUser(GetDef(id), f);
}
-void DefUseManager::ForEachUse(
+bool DefUseManager::WhileEachUse(
const ir::Instruction* def,
- const std::function<void(ir::Instruction*, uint32_t)>& f) const {
+ const std::function<bool(ir::Instruction*, uint32_t)>& f) const {
// Ensure that |def| has been registered.
assert(def && def == GetDef(def->result_id()) &&
"Definition is not registered.");
@@ -125,10 +140,28 @@ void DefUseManager::ForEachUse(
for (uint32_t idx = 0; idx != user->NumOperands(); ++idx) {
const ir::Operand& op = user->GetOperand(idx);
if (op.type != SPV_OPERAND_TYPE_RESULT_ID && spvIsIdType(op.type)) {
- if (def->result_id() == op.words[0]) f(user, idx);
+ if (def->result_id() == op.words[0]) {
+ if (!f(user, idx)) return false;
+ }
}
}
}
+ return true;
+}
+
+bool DefUseManager::WhileEachUse(
+ uint32_t id,
+ const std::function<bool(ir::Instruction*, uint32_t)>& f) const {
+ return WhileEachUse(GetDef(id), f);
+}
+
+void DefUseManager::ForEachUse(
+ const ir::Instruction* def,
+ const std::function<void(ir::Instruction*, uint32_t)>& f) const {
+ WhileEachUse(def, [&f](ir::Instruction* user, uint32_t index) {
+ f(user, index);
+ return true;
+ });
}
void DefUseManager::ForEachUse(