diff options
author | Nathan Froyd <froydnj@gmail.com> | 2018-03-23 12:38:07 -0400 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2018-03-23 09:38:07 -0700 |
commit | 9c2fa9247333233d3454c546677205b4a3c2e96a (patch) | |
tree | 3d6babf3adb4857dd266cf5756dc123112cd0419 /src | |
parent | f7ebc7c0e53241e4604be5321134d48d640f0a40 (diff) | |
download | binaryen-9c2fa9247333233d3454c546677205b4a3c2e96a.tar.gz binaryen-9c2fa9247333233d3454c546677205b4a3c2e96a.tar.bz2 binaryen-9c2fa9247333233d3454c546677205b4a3c2e96a.zip |
remap {get,set}_local indices (#1486)
When lowering i64 values in a function, we create new local variables
for all of the i64 local variables, one local for the low bits, and one
for the high bits. We create a mapping between the old locals and the
new as well. During translation, when we encountered a `get_local` that
didn't have type `i64`, we skipped it, on the supposition that there was
nothing to do. But that's not true; the local it was getting may have
been remapped to a new index in the lowered function, and we need to
account for that change. Similar logic holds for `set_local`.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/I64ToI32Lowering.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index c77ec3963..b051642f6 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -381,14 +381,19 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { } void visitGetLocal(GetLocal* curr) { - if (curr->type != i64) return; - curr->index = indexMap[curr->index]; + const auto mappedIndex = indexMap[curr->index]; + // Need to remap the local into the new naming scheme, regardless of + // the type of the local. + curr->index = mappedIndex; + if (curr->type != i64) { + return; + } curr->type = i32; TempVar highBits = getTemp(); SetLocal *setHighBits = builder->makeSetLocal( highBits, builder->makeGetLocal( - curr->index + 1, + mappedIndex + 1, i32 ) ); @@ -400,7 +405,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { void lowerTee(SetLocal* curr) { TempVar highBits = fetchOutParam(curr->value); TempVar tmp = getTemp(); - curr->index = indexMap[curr->index]; curr->type = i32; SetLocal* setLow = builder->makeSetLocal(tmp, curr); SetLocal* setHigh = builder->makeSetLocal( @@ -414,15 +418,20 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { } void visitSetLocal(SetLocal* curr) { - if (!hasOutParam(curr->value)) return; + const auto mappedIndex = indexMap[curr->index]; + // Need to remap the local into the new naming scheme, regardless of + // the type of the local. Note that lowerTee depends on this happening. + curr->index = mappedIndex; + if (!hasOutParam(curr->value)) { + return; + } if (curr->isTee()) { lowerTee(curr); return; } TempVar highBits = fetchOutParam(curr->value); - curr->index = indexMap[curr->index]; SetLocal* setHigh = builder->makeSetLocal( - curr->index + 1, + mappedIndex + 1, builder->makeGetLocal(highBits, i32) ); Block* result = builder->blockify(curr, setHigh); |