From b4c6e2bfb11dbdec9e801f36cecd860d5270eed5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 12 Jan 2016 10:17:24 -0800 Subject: update s2wasm for new block and loop format in .s files from llvm #97 --- src/s2wasm.h | 82 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/s2wasm.h b/src/s2wasm.h index 9cb41b8d6..c192effc2 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -437,8 +437,15 @@ private: } // parse body func->body = allocator.alloc(); - std::vector bstack; - bstack.push_back(func->body->dyn_cast()); + std::vector bstack; + auto addToBlock = [&bstack](Expression* curr) { + Expression* last = bstack.back(); + if (last->is()) { + last = last->cast()->body; + } + last->cast()->list.push_back(curr); + }; + bstack.push_back(func->body); std::vector estack; auto push = [&](Expression* curr) { //std::cerr << "push " << curr << '\n'; @@ -491,7 +498,7 @@ private: }; auto setOutput = [&](Expression* curr, Name assign) { if (assign.isNull() || assign.str[1] == 'd') { // discard - bstack.back()->list.push_back(curr); + addToBlock(curr); } else if (assign.str[1] == 'p') { // push push(curr); } else { // set to a local @@ -499,7 +506,7 @@ private: set->name = assign; set->value = curr; set->type = curr->type; - bstack.back()->list.push_back(set); + addToBlock(set); } }; auto makeBinary = [&](BinaryOp op, WasmType type) { @@ -774,10 +781,22 @@ private: default: abort_on("type.?"); } }; + // labels + size_t nextLabel = 0; + auto getNextLabel = [&nextLabel]() { + return cashew::IString(("label$" + std::to_string(nextLabel++)).c_str(), false); + }; + auto getBranchLabel = [&](uint32_t offset) { + assert(offset < bstack.size()); + Expression* target = bstack[bstack.size() - 1 - offset]; + if (target->is()) { + return target->cast()->name; + } else { + return target->cast()->in; + } + }; // fixups std::vector loopBlocks; // we need to clear their names - std::set seenLabels; // if we already used a label, we don't need it in a loop (there is a block above it, with that label) - Name lastLabel; // A loop has an 'in' label which appears before it. There might also be a block in between it and the loop, so we have to remember the last label // main loop while (1) { skipWhitespace(); @@ -792,38 +811,27 @@ private: handleTyped(f64); } else if (match("block")) { auto curr = allocator.alloc(); - curr->name = getStr(); - bstack.back()->list.push_back(curr); + curr->name = getNextLabel(); + addToBlock(curr); bstack.push_back(curr); - seenLabels.insert(curr->name); + } else if (match("end_block")) { + bstack.pop_back(); } else if (match(".LBB")) { - s -= 4; - lastLabel = getStrToColon(); - s++; - skipWhitespace(); - // pop all blocks/loops that reach this target - // pop all targets with this label - while (!bstack.empty()) { - auto curr = bstack.back(); - if (curr->name == lastLabel) { - bstack.pop_back(); - continue; - } - break; - } + s = strchr(s, '\n'); } else if (match("loop")) { auto curr = allocator.alloc(); - bstack.back()->list.push_back(curr); - curr->in = lastLabel; - Name out = getStr(); - if (seenLabels.count(out) == 0) { - curr->out = out; - } + addToBlock(curr); + curr->in = getNextLabel(); + curr->out = getNextLabel(); auto block = allocator.alloc(); - block->name = out; // temporary, fake + block->name = curr->out; // temporary, fake - this way, on bstack we have the right label at the right offset for a br curr->body = block; loopBlocks.push_back(block); bstack.push_back(block); + bstack.push_back(curr); + } else if (match("end_loop")) { + bstack.pop_back(); + bstack.pop_back(); } else if (match("br")) { auto curr = allocator.alloc(); if (*s == '_') { @@ -831,8 +839,8 @@ private: curr->condition = getInput(); skipComma(); } - curr->name = getStr(); - bstack.back()->list.push_back(curr); + curr->name = getBranchLabel(getInt()); + addToBlock(curr); } else if (match("call")) { makeCall(none); } else if (match("copy_local")) { @@ -853,18 +861,18 @@ private: if (*s == '$') { curr->value = getInput(); } - bstack.back()->list.push_back(curr); + addToBlock(curr); } else if (match("tableswitch")) { auto curr = allocator.alloc(); curr->value = getInput(); skipComma(); - curr->default_ = getCommaSeparated(); + curr->default_ = getBranchLabel(getInt()); while (skipComma()) { - curr->targets.push_back(getCommaSeparated()); + curr->targets.push_back(getBranchLabel(getInt())); } - bstack.back()->list.push_back(curr); + addToBlock(curr); } else if (match("unreachable")) { - bstack.back()->list.push_back(allocator.alloc()); + addToBlock(allocator.alloc()); } else if (match("memory_size")) { makeHost(MemorySize); } else if (match("grow_memory")) { -- cgit v1.2.3