diff options
author | Björn Gustavsson <[email protected]> | 2018-11-01 12:43:34 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-11-01 12:43:34 +0100 |
commit | a1dd7f04877057442a96fe25c4ea983461a4b266 (patch) | |
tree | ab82848c3835e1bfb4630184ed25c206dcc0726d /lib/compiler | |
parent | 46c1dec651df4021bf5e2007d7c34232cd22d51c (diff) | |
parent | 3916346a625ba3be672374395b41eb0dd6f84d4f (diff) | |
download | otp-a1dd7f04877057442a96fe25c4ea983461a4b266.tar.gz otp-a1dd7f04877057442a96fe25c4ea983461a4b266.tar.bz2 otp-a1dd7f04877057442a96fe25c4ea983461a4b266.zip |
Merge branch 'bjorn/compiler/diffable'
* bjorn/compiler/diffable:
scripts/diffable: Correct the number of modules being compiled
scripts/diffable: Use the diffable compiler option
Add a diffable option for the compiler
scripts/diffable: Refactor option parsing
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_listing.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/compile.erl | 35 | ||||
-rw-r--r-- | lib/compiler/test/compile_SUITE.erl | 1 |
3 files changed, 37 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_listing.erl b/lib/compiler/src/beam_listing.erl index 8a0ce5b50a..6121593b11 100644 --- a/lib/compiler/src/beam_listing.erl +++ b/lib/compiler/src/beam_listing.erl @@ -66,7 +66,7 @@ module(Stream, [_|_]=Fs) -> foreach(fun (F) -> io:format(Stream, "~p.\n", [F]) end, Fs). format_asm([{label,L}|Is]) -> - [" {label,",integer_to_list(L),"}.\n"|format_asm(Is)]; + [io_lib:format(" {label,~p}.\n", [L])|format_asm(Is)]; format_asm([I|Is]) -> [io_lib:format(" ~p", [I]),".\n"|format_asm(Is)]; format_asm([]) -> []. diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 27e6e8fe00..65c4f140c9 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -868,7 +868,9 @@ asm_passes() -> %% need to do a few clean-ups to code. {iff,no_postopt,[{pass,beam_clean}]}, + {iff,diffable,?pass(diffable)}, {pass,beam_z}, + {iff,diffable,{listing,"S"}}, {iff,dz,{listing,"z"}}, {iff,dopt,{listing,"optimize"}}, {iff,'S',{listing,"S"}}, @@ -1926,6 +1928,39 @@ restore_expand_module([F|Fs]) -> [F|restore_expand_module(Fs)]; restore_expand_module([]) -> []. +%%% +%%% Transform the BEAM code to make it more friendly for +%%% diffing: using function names instead of labels for +%%% local calls and number labels relative to each function. +%%% + +diffable(Code0, St) -> + {Mod,Exp,Attr,Fs0,NumLabels} = Code0, + EntryLabels0 = [{Entry,{Name,Arity}} || + {function,Name,Arity,Entry,_} <- Fs0], + EntryLabels = maps:from_list(EntryLabels0), + Fs = [diffable_fix_function(F, EntryLabels) || F <- Fs0], + Code = {Mod,Exp,Attr,Fs,NumLabels}, + {ok,Code,St}. + +diffable_fix_function({function,Name,Arity,Entry0,Is0}, LabelMap0) -> + Entry = maps:get(Entry0, LabelMap0), + {Is1,LabelMap} = diffable_label_map(Is0, 1, LabelMap0, []), + Fb = fun(Old) -> error({no_fb,Old}) end, + Is = beam_utils:replace_labels(Is1, [], LabelMap, Fb), + {function,Name,Arity,Entry,Is}. + +diffable_label_map([{label,Old}|Is], New, Map, Acc) -> + case Map of + #{Old:=NewLabel} -> + diffable_label_map(Is, New, Map, [{label,NewLabel}|Acc]); + #{} -> + diffable_label_map(Is, New+1, Map#{Old=>New}, [{label,New}|Acc]) + end; +diffable_label_map([I|Is], New, Map, Acc) -> + diffable_label_map(Is, New, Map, [I|Acc]); +diffable_label_map([], _New, Map, Acc) -> + {Acc,Map}. -spec options() -> 'ok'. diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 5656743c76..8d8bbe9543 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -396,6 +396,7 @@ do_file_listings(DataDir, PrivDir, [File|Files]) -> do_listing(Simple, TargetDir, dclean, ".clean"), do_listing(Simple, TargetDir, dpeep, ".peep"), do_listing(Simple, TargetDir, dopt, ".optimize"), + do_listing(Simple, TargetDir, diffable, ".S"), %% First clean up. Listings = filename:join(PrivDir, listings), |