summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h14
-rw-r--r--src/emscripten-optimizer/simple_ast.h4
-rw-r--r--src/passes/PrintCallGraph.cpp47
3 files changed, 31 insertions, 34 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 377b6b20b..87fd10649 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -443,9 +443,13 @@ private:
std::map<unsigned, Ref> tempNums;
- Literal checkLiteral(Ref ast) {
+ Literal checkLiteral(Ref ast, bool rawIsInteger = true) {
if (ast[0] == NUM) {
- return Literal((int32_t)ast[1]->getInteger());
+ if (rawIsInteger) {
+ return Literal((int32_t)ast[1]->getInteger());
+ } else {
+ return Literal(ast[1]->getNumber());
+ }
} else if (ast[0] == UNARY_PREFIX) {
if (ast[1] == PLUS && ast[2][0] == NUM) {
return Literal((double)ast[2][1]->getNumber());
@@ -1475,10 +1479,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
}
if (name == Math_fround) {
assert(ast[2]->size() == 1);
- Literal lit = checkLiteral(ast[2][0]);
- if (lit.type == i32) {
- return builder.makeConst(Literal((float)lit.geti32()));
- } else if (lit.type == f64) {
+ Literal lit = checkLiteral(ast[2][0], false /* raw is float */);
+ if (lit.type == f64) {
return builder.makeConst(Literal((float)lit.getf64()));
}
auto ret = allocator.alloc<Unary>();
diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h
index 3f0d363df..20de952c1 100644
--- a/src/emscripten-optimizer/simple_ast.h
+++ b/src/emscripten-optimizer/simple_ast.h
@@ -225,9 +225,9 @@ struct Value {
return boo;
}
- int getInteger() { // convenience function to get a known integer
+ int32_t getInteger() { // convenience function to get a known integer
assert(fmod(getNumber(), 1) == 0);
- int ret = int(getNumber());
+ int32_t ret = getNumber();
assert(double(ret) == getNumber()); // no loss in conversion
return ret;
}
diff --git a/src/passes/PrintCallGraph.cpp b/src/passes/PrintCallGraph.cpp
index 33fcb3457..233ae3a0c 100644
--- a/src/passes/PrintCallGraph.cpp
+++ b/src/passes/PrintCallGraph.cpp
@@ -33,20 +33,25 @@ struct PrintCallGraph : public Pass {
o << "digraph call {\n";
o << " rankdir = LR;\n";
o << " subgraph cluster_key {\n";
- o << " node [shape=box, style=rounded, fontname=courier, fontsize=10];\n";
+ o << " node [shape=box, fontname=courier, fontsize=10];\n";
o << " edge [fontname=courier, fontsize=10];\n";
o << " label = \"Key\";\n";
- o << " \"Import\" [style=\"filled, rounded\", fillcolor=\"turquoise\"];\n";
- o << " \"Export\" [style=\"filled, rounded\", fillcolor=\"gray\"];\n";
+ o << " \"Import\" [style=\"filled\", fillcolor=\"turquoise\"];\n";
+ o << " \"Export\" [style=\"filled\", fillcolor=\"gray\"];\n";
+ o << " \"Indirect Target\" [style=\"filled, rounded\", fillcolor=\"white\"];\n";
o << " \"A\" -> \"B\" [style=\"filled, rounded\", label = \"Direct Call\"];\n";
- o << " \"C\" -> \"D\" [style=\"filled, rounded, dashed\", label = \"Possible Indirect Call\"];\n";
o << " }\n\n";
- o << " node [shape=box,style=rounded, fontname=courier, fontsize=10];\n";
+ o << " node [shape=box, fontname=courier, fontsize=10];\n";
+
+ // All Functions
+ for (auto& func : module->functions) {
+ std::cout << " \"" << func.get()->name << "\" [style=\"filled\", fillcolor=\"white\"];\n";
+ }
// Imports Nodes
for (auto& curr : module->imports) {
if (curr->kind == ExternalKind::Function) {
- o << " \"" << curr->name << "\" [style=\"filled, rounded\", fillcolor=\"turquoise\"];\n";
+ o << " \"" << curr->name << "\" [style=\"filled\", fillcolor=\"turquoise\"];\n";
}
}
@@ -54,7 +59,7 @@ struct PrintCallGraph : public Pass {
for (auto& curr : module->exports) {
if (curr->kind == ExternalKind::Function) {
Function* func = module->getFunction(curr->value);
- o << " \"" << func->name << "\" [style=\"filled, rounded\", fillcolor=\"gray\"];\n";
+ o << " \"" << func->name << "\" [style=\"filled\", fillcolor=\"gray\"];\n";
}
}
@@ -64,16 +69,9 @@ struct PrintCallGraph : public Pass {
std::set<Name> visitedTargets; // Used to avoid printing duplicate edges.
std::vector<Function*> allIndirectTargets;
CallPrinter(Module *module) : module(module) {
- // Gather targets of indirect calls.
- for (auto& segment : module->table.segments) {
- for (auto& curr : segment.data) {
- allIndirectTargets.push_back(module->getFunction(curr));
- }
- }
// Walk function bodies.
for (auto& func : module->functions) {
currFunction = func.get();
- std::cout << " \"" << func->name << "\";\n";
visitedTargets.clear();
walk(func.get()->body);
}
@@ -90,20 +88,17 @@ struct PrintCallGraph : public Pass {
visitedTargets.insert(name);
std::cout << " \"" << currFunction->name << "\" -> \"" << name << "\"; // callImport\n";
}
- void visitCallIndirect(CallIndirect *curr) {
- // Find eligible indirect targets.
- auto* currType = module->getFunctionType(curr->fullType);
- for (auto& target : allIndirectTargets) {
- auto* targetType = module->getFunctionType(target->type);
- if (targetType->structuralComparison(*currType)) continue;
- auto name = target->name;
- if (visitedTargets.count(name) > 0) continue;
- visitedTargets.insert(name);
- std::cout << " \"" << currFunction->name << "\" -> \"" << name << "\" [style=\"dashed\"]; // callIndirect\n";
- }
- }
};
CallPrinter printer(module);
+
+ // Indirect Targets
+ for (auto& segment : module->table.segments) {
+ for (auto& curr : segment.data) {
+ auto* func = module->getFunction(curr);
+ o << " \"" << func->name << "\" [style=\"filled, rounded\"];\n";
+ }
+ }
+
o << "}\n";
}
};