anchor.diff:      [{perf, [symbols, annotate]}].
   
   all() ->
  -    [{group, perf}].
  +    [{group, perf}, named_labels].
   
   init_per_suite(Config) ->
       case erlang:system_info(emu_flavor) of
  
positive.code: 
  -export([suite/0, groups/0, all/0,
           init_per_suite/1, end_per_suite/1,
           init_per_group/2, end_per_group/2]).
  -export([symbols/1, annotate/1]).
  
  suite() ->
      [{timetrap, {minutes, 4}}].
  
negative.code:             ct:log("Did not find disassembly test for ~ts.~n~ts",
                     [Symbol, Anno])
      end.
  
  get_tmp_asm_files() ->
      {ok, Cwd} = file:get_cwd(),
      filelib:wildcard(filename:join(Cwd, "*.asm")).
  
  named_labels(_Config) ->
      %% Check that pretty printing of named labels is working. We do
      %% that by loading this module in an emulator running with +JDdump
      %% true and then checking that the produced jit_SUITE.asm contains
      %% a label for each exported function. We also check that the
      %% label for the non-exported function get_tmp_asm_files/0, which
      %% is used by this test, is present.
      Exports = proplists:get_value(exports, ?MODULE:module_info()),
      ModName = atom_to_list(?MODULE),
      ModulePath = filename:dirname(code:which(?MODULE)),
      Cmd = "erl +JDdump true -noshell -pa " ++ ModulePath ++ " -eval \""
          ++ ModName ++ ":module_info(),erlang:halt(0).\"",
      os:cmd(Cmd),
      {ok, Cwd} = file:get_cwd(),
      AsmFile = filename:join(Cwd, ModName ++ ".asm"),
      {ok, Data} = file:read_file(AsmFile),
      Expected = sets:from_list([ lists:flatten(io_lib:format("~p/~p", [N,A]))
                                  || {N,A} <- Exports]
                                ++ ["get_tmp_asm_files/0"]),
      StripSeqNo = fun(Lbl) ->
                           %% In the Arm JIT, labels have the form
                           %% @Mod:Name/Arity-SequenceNumber, so strip
                           %% out the Mod part and the sequence number
                           %% as we can't know anything about them.
                           case re:run(Lbl, "^.*\:(.*)-[0-9]*$",
                                       [{capture,all_but_first,list}]) of
                               {match,[R]} -> R;
                               nomatch -> Lbl
                           end
                   end,
      case re:run(Data, "^(.*)\:\n",
                  [global,multiline,{capture,all_but_first,list}]) of
          {match,Labels} ->
              Found = sets:from_list([ StripSeqNo(NA) || [NA] <- Labels]),
              case sets:is_subset(Expected, Found) of
                  true ->
                      ok;
                  false ->
                      ct:fail("Expected ~p, found ~p",
                              [sets:to_list(Expected), sets:to_list(Found)])
              end;
          _ ->
              ct:fail("No labels found in assembly dump")
      end.
  