| #include <iostream> | |
| #include <ir/local-graph.h> | |
| #include <wasm-builder.h> | |
| #include <wasm.h> | |
| using namespace wasm; | |
| int main() { | |
| Module wasm; | |
| Builder builder(wasm); | |
| { | |
| Function foo; | |
| foo.type = Type(Signature(Type::none, Type::none), NonNullable, Exact); | |
| foo.vars = {Type::i32}; | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(0, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| builder.makeLocalSet(0, builder.makeConst(Literal(int32_t(0)))), | |
| // two equivalent gets, as both are preceded by the same single set | |
| builder.makeDrop(get1), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = Type(Signature(Type::none, Type::none), NonNullable, Exact); | |
| foo.vars = {Type::i32}; | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(0, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| // two non-equivalent gets, as there is a set in between them | |
| builder.makeDrop(get1), | |
| builder.makeLocalSet(0, builder.makeConst(Literal(int32_t(0)))), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(!graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = Type(Signature({Type::i32}, Type::none), NonNullable, Exact); | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(0, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| // two equivalent gets of the same parameter | |
| builder.makeDrop(get1), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = Type(Signature({Type::i32}, Type::none), NonNullable, Exact); | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(0, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| // two non-equivalent gets of the same parameter, as there is a set | |
| builder.makeDrop(get1), | |
| builder.makeLocalSet(0, builder.makeConst(Literal(int32_t(0)))), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(!graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = | |
| Type(Signature({Type::i32, Type::i32}, Type::none), NonNullable, Exact); | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(1, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| // two non-equivalent gets as they are of different parameters | |
| builder.makeDrop(get1), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(!graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = Type(Signature(Type::none, Type::none), NonNullable, Exact); | |
| foo.vars = {Type::i32, Type::i32}; | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(1, Type::i32); | |
| foo.body = builder.makeBlock({ | |
| // two equivalent gets, even though they have a different index, as both | |
| // use the zero initialized value | |
| builder.makeDrop(get1), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(graph.equivalent(get1, get2)); | |
| } | |
| { | |
| Function foo; | |
| foo.type = Type(Signature(Type::none, Type::none), NonNullable, Exact); | |
| foo.vars = {Type::i32, Type::f64}; | |
| auto* get1 = builder.makeLocalGet(0, Type::i32); | |
| auto* get2 = builder.makeLocalGet(1, Type::f64); | |
| foo.body = builder.makeBlock({ | |
| // two non-equivalent gets as their zero-init value is different | |
| builder.makeDrop(get1), | |
| builder.makeDrop(get2), | |
| }); | |
| LocalGraph graph(&foo); | |
| assert(!graph.equivalent(get1, get2)); | |
| } | |
| std::cout << "Success." << std::endl; | |
| return 0; | |
| } |