aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-04-21 08:09:22 +0200
committerBjörn Gustavsson <[email protected]>2015-04-23 13:43:03 +0200
commit7effd4c9efc42d7afcef6390d18617e7e97275e6 (patch)
tree2d38515ae17b16fd1dbd2fde2f98ad5499ff3630 /lib/compiler/src
parent2ff88fe3687c4728e58cf7ac7e008ef7c5be1320 (diff)
downloadotp-7effd4c9efc42d7afcef6390d18617e7e97275e6.tar.gz
otp-7effd4c9efc42d7afcef6390d18617e7e97275e6.tar.bz2
otp-7effd4c9efc42d7afcef6390d18617e7e97275e6.zip
beam_validator: Correct merging of y registers
When merging y registers, only the y registers that are found in both states should be retained.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_validator.erl30
1 files changed, 17 insertions, 13 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index c55919dc73..ed94880d38 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1398,20 +1398,24 @@ merge_regs_1([], [_|_]) -> [];
merge_regs_1([_|_], []) -> [].
merge_y_regs(Rs0, Rs1) ->
- Rs = merge_y_regs_1(gb_trees:to_list(Rs0), gb_trees:to_list(Rs1)),
- gb_trees_from_list(Rs).
+ case {gb_trees:size(Rs0),gb_trees:size(Rs1)} of
+ {Sz0,Sz1} when Sz0 < Sz1 ->
+ merge_y_regs_1(Sz0-1, Rs1, Rs0);
+ {_,Sz1} ->
+ merge_y_regs_1(Sz1-1, Rs0, Rs1)
+ end.
-merge_y_regs_1([Same|Rs1], [Same|Rs2]) ->
- [Same|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R1,_}|Rs1], [{R2,_}|_]=Rs2) when R1 < R2 ->
- [{R1,uninitialized}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R1,_}|_]=Rs1, [{R2,_}|Rs2]) when R1 > R2 ->
- [{R2,uninitialized}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([{R,Type1}|Rs1], [{R,Type2}|Rs2]) ->
- [{R,merge_types(Type1, Type2)}|merge_y_regs_1(Rs1, Rs2)];
-merge_y_regs_1([], []) -> [];
-merge_y_regs_1([], [_|_]=Rs) -> Rs;
-merge_y_regs_1([_|_]=Rs, []) -> Rs.
+merge_y_regs_1(Y, S, Regs0) when Y >= 0 ->
+ Type0 = gb_trees:get(Y, Regs0),
+ case gb_trees:get(Y, S) of
+ Type0 ->
+ merge_y_regs_1(Y-1, S, Regs0);
+ Type1 ->
+ Type = merge_types(Type0, Type1),
+ Regs = gb_trees:update(Y, Type, Regs0),
+ merge_y_regs_1(Y-1, S, Regs)
+ end;
+merge_y_regs_1(_, _, Regs) -> Regs.
%% merge_types(Type1, Type2) -> Type
%% Return the most specific type possible.