summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-08-02 20:53:48 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 09:54:52 -0700
commit72616971b2a35cbc37ea974e47c870556ef8ef4d (patch)
treee9c3daeed8231fb9a4466b21cf9e05d682d11709 /src
parent1cc33903a0b1b9dddd40674d792a59ee0d1bccf7 (diff)
downloadbinaryen-72616971b2a35cbc37ea974e47c870556ef8ef4d.tar.gz
binaryen-72616971b2a35cbc37ea974e47c870556ef8ef4d.tar.bz2
binaryen-72616971b2a35cbc37ea974e47c870556ef8ef4d.zip
call_indirect now has the target at the end
Diffstat (limited to 'src')
-rw-r--r--src/passes/DeadCodeElimination.cpp33
-rw-r--r--src/passes/Print.cpp2
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-s-parser.h14
-rw-r--r--src/wasm-traversal.h6
5 files changed, 30 insertions, 29 deletions
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index aba442e71..866b3cb73 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -234,45 +234,46 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination, V
}
template<typename T>
- void handleCall(T* curr, Expression* initial) {
+ Expression* handleCall(T* curr) {
for (Index i = 0; i < curr->operands.size(); i++) {
if (isDead(curr->operands[i])) {
- if (i > 0 || initial != nullptr) {
+ if (i > 0) {
auto* block = getModule()->allocator.alloc<Block>();
- Index newSize = i + 1 + (initial ? 1 : 0);
+ Index newSize = i + 1;
block->list.resize(newSize);
Index j = 0;
- if (initial) {
- block->list[j] = drop(initial);
- j++;
- }
for (; j < newSize; j++) {
- block->list[j] = drop(curr->operands[j - (initial ? 1 : 0)]);
+ block->list[j] = drop(curr->operands[j]);
}
block->finalize();
- replaceCurrent(block);
+ return replaceCurrent(block);
} else {
- replaceCurrent(curr->operands[i]);
+ return replaceCurrent(curr->operands[i]);
}
- return;
}
}
+ return curr;
}
void visitCall(Call* curr) {
- handleCall(curr, nullptr);
+ handleCall(curr);
}
void visitCallImport(CallImport* curr) {
- handleCall(curr, nullptr);
+ handleCall(curr);
}
void visitCallIndirect(CallIndirect* curr) {
+ if (handleCall(curr) != curr) return;
if (isDead(curr->target)) {
- replaceCurrent(curr->target);
- return;
+ auto* block = getModule()->allocator.alloc<Block>();
+ for (auto* operand : curr->operands) {
+ block->list.push_back(drop(operand));
+ }
+ block->list.push_back(curr->target);
+ block->finalize();
+ replaceCurrent(block);
}
- handleCall(curr, curr->target);
}
void visitSetLocal(SetLocal* curr) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 4f6baa9da..e54468c41 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -230,10 +230,10 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
void visitCallIndirect(CallIndirect *curr) {
printOpening(o, "call_indirect ") << curr->fullType;
incIndent();
- printFullLine(curr->target);
for (auto operand : curr->operands) {
printFullLine(operand);
}
+ printFullLine(curr->target);
decIndent();
}
void visitGetLocal(GetLocal *curr) {
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 9d1b5e522..77cbd8aab 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -676,11 +676,11 @@ public:
}
Flow visitCallIndirect(CallIndirect *curr) {
NOTE_ENTER("CallIndirect");
- Flow target = visit(curr->target);
- if (target.breaking()) return target;
LiteralList arguments;
Flow flow = generateArguments(curr->operands, arguments);
if (flow.breaking()) return flow;
+ Flow target = visit(curr->target);
+ if (target.breaking()) return target;
Index index = target.value.geti32();
return instance.externalInterface->callTable(index, curr->fullType, arguments, instance);
}
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 685f26d82..49fd52ef0 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -895,7 +895,7 @@ private:
if (op == HostOp::HasFeature) {
ret->nameOperand = s[1]->str();
} else {
- parseCallOperands(s, 1, ret);
+ parseCallOperands(s, 1, s.size(), ret);
}
ret->finalize();
return ret;
@@ -1196,7 +1196,7 @@ private:
auto ret = allocator.alloc<Call>();
ret->target = s[1]->str();
ret->type = functionTypes[ret->target];
- parseCallOperands(s, 2, ret);
+ parseCallOperands(s, 2, s.size(), ret);
return ret;
}
@@ -1205,7 +1205,7 @@ private:
ret->target = s[1]->str();
Import* import = wasm.getImport(ret->target);
ret->type = import->type->result;
- parseCallOperands(s, 2, ret);
+ parseCallOperands(s, 2, s.size(), ret);
return ret;
}
@@ -1216,14 +1216,14 @@ private:
if (!fullType) throw ParseException("invalid call_indirect type", s.line, s.col);
ret->fullType = fullType->name;
ret->type = fullType->result;
- ret->target = parseExpression(s[2]);
- parseCallOperands(s, 3, ret);
+ parseCallOperands(s, 2, s.size() - 1, ret);
+ ret->target = parseExpression(s[s.size() - 1]);
return ret;
}
template<class T>
- void parseCallOperands(Element& s, size_t i, T* call) {
- while (i < s.size()) {
+ void parseCallOperands(Element& s, Index i, Index j, T* call) {
+ while (i < j) {
call->operands.push_back(parseExpression(s[i]));
i++;
}
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index d6484abdb..f9d3d8413 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -156,8 +156,8 @@ struct Walker : public VisitorType {
// Note that the visit*() for the result node is not called for you (i.e.,
// just one visit*() method is called by the traversal; if you replace a node,
// and you want to process the output, you must do that explicitly).
- void replaceCurrent(Expression *expression) {
- replace = expression;
+ Expression* replaceCurrent(Expression *expression) {
+ return replace = expression;
}
// Get the current module
@@ -358,10 +358,10 @@ struct PostWalker : public Walker<SubType, VisitorType> {
case Expression::Id::CallIndirectId: {
self->pushTask(SubType::doVisitCallIndirect, currp);
auto& list = curr->cast<CallIndirect>()->operands;
+ self->pushTask(SubType::scan, &curr->cast<CallIndirect>()->target);
for (int i = int(list.size()) - 1; i >= 0; i--) {
self->pushTask(SubType::scan, &list[i]);
}
- self->pushTask(SubType::scan, &curr->cast<CallIndirect>()->target);
break;
}
case Expression::Id::GetLocalId: {