summaryrefslogtreecommitdiff
path: root/src/ir/module-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/module-utils.h')
-rw-r--r--src/ir/module-utils.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 703ae3e53..93d110120 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -341,6 +341,7 @@ template<typename T> struct CallGraphPropertyAnalysis {
struct FunctionInfo {
std::set<Function*> callsTo;
std::set<Function*> calledBy;
+ bool hasIndirectCall = false;
};
typedef std::map<Function*, T> Map;
@@ -362,6 +363,10 @@ template<typename T> struct CallGraphPropertyAnalysis {
info.callsTo.insert(module->getFunction(curr->target));
}
+ void visitCallIndirect(CallIndirect* curr) {
+ info.hasIndirectCall = true;
+ }
+
private:
Module* module;
T& info;
@@ -382,14 +387,20 @@ template<typename T> struct CallGraphPropertyAnalysis {
}
}
+ enum IndirectCalls { IgnoreIndirectCalls, IndirectCallsHaveProperty };
+
// Propagate a property from a function to those that call it.
void propagateBack(std::function<bool(const T&)> hasProperty,
std::function<bool(const T&)> canHaveProperty,
- std::function<void(T&)> addProperty) {
+ std::function<void(T&)> addProperty,
+ IndirectCalls indirectCalls) {
// The work queue contains items we just learned can change the state.
UniqueDeferredQueue<Function*> work;
for (auto& func : wasm.functions) {
- if (hasProperty(map[func.get()])) {
+ if (hasProperty(map[func.get()]) ||
+ (indirectCalls == IndirectCallsHaveProperty &&
+ map[func.get()].hasIndirectCall)) {
+ addProperty(map[func.get()]);
work.push(func.get());
}
}