anchor.diff:  solve([_|_] = SCC, State) ->
     ?debug("============ Analyzing SCC: ~w ===========\n",
   	 [[debug_lookup_name(F) || F <- SCC]]),
  -  solve_scc(SCC, dict:new(), State, false).
  +  {Parallel, NewState} =
  +    case parallel_split(SCC) of
  +      false -> {false, State};
  +      SplitSCC -> {SplitSCC, minimize_state(State)}
  +    end,
  +  solve_scc(SCC, Parallel, dict:new(), NewState, false).
   
   solve_fun(Fun, FunMap, State) ->
     Cs = state__get_cs(Fun, State),
  
positive.code: state__new_constraint_context(State) ->
    State#state{cs = []}.
  
  state__prop_domain(FunLabel, #state{prop_types = PropTypes}) ->
   case dict:find(FunLabel, PropTypes) of
      error -> error;
      {ok, {_Range_Fun, Dom}} -> {ok, Dom};
      {ok, FunType} -> {ok, t_fun_args(FunType)}
    end.
  
  state__add_prop_constrs(Tree, #state{prop_types = PropTypes} = State) ->
    Label = cerl_trees:get_label(Tree),
    case dict:find(Label, PropTypes) of
      error -> State;
  
negative.code: 	       true -> t_fun(t_fun_args(T), t_unit())
  	     end || T <- NewTypes],
  	  Map3 = enter_type_lists(Funs, UnitTypes, Map2),
  	  solve_scc(SCC, Parallel, Map3, State, true);
  	false ->
  	  case Parallel of
  	    false -> true;
  	    _ -> dispose_state(State)
  	  end,
  	  Map2
        end;
      false ->
        ?debug("SCC ~w did not reach fixpoint\n", [SCC]),
        solve_scc(SCC, Parallel, Map2, State, TryingUnit)
    end.
  
  solve_whole_scc(SCC, Map, State) ->
    SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State) end,
    lists:foldl(SolveFun, Map, SCC).
  
  %%------------------------------------------------------------------------------
  
  -define(worth_it, 42).
  
  parallel_split(SCC) ->
    Length = length(SCC),
    case Length > 2*?worth_it of
      false -> false;
      true ->
        case min(erlang:system_info(logical_processors_available), 8) of
  	1 -> false;
  	CPUs ->
  	  FullShare = Length div CPUs + 1,
  	  Unit = max(FullShare, ?worth_it),
  	  split(SCC, Unit, [])
        end
    end.
  
  minimize_state(#state{
  		  cmap        = {d, CMap},
  		  fun_map     = FunMap,
  		  fun_arities = FunArities,
  		  self_rec    = SelfRec,
  		  prop_types  = {d, PropTypes},
  		  opaques     = Opaques
  		 }) ->
    ETSCMap = ets:new(cmap,[{read_concurrency, true}]),
    ETSPropTypes = ets:new(prop_types,[{read_concurrency, true}]),
    true = ets:insert(ETSCMap, dict:to_list(CMap)),
    true = ets:insert(ETSPropTypes, dict:to_list(PropTypes)),
    #state
      {cmap        = {e, ETSCMap},
       fun_map     = FunMap,
       fun_arities = FunArities,
       self_rec    = SelfRec,
       prop_types  = {e, ETSPropTypes},
       opaques     = Opaques
      }.
  
  dispose_state(#state{cmap = {e, ETSCMap},
  		     prop_types = {e, ETSPropTypes}}) ->
    true = ets:delete(ETSCMap),
    true = ets:delete(ETSPropTypes).
  
  solve_whole_scc_parallel(SplitSCC, Map, State) ->
    Workers = spawn_workers(SplitSCC, Map, State),
    wait_results(Workers, Map, fold_res_fun(State)).
  
  spawn_workers(SplitSCC, Map, State) ->
    Spawner = solve_scc_spawner(self(), Map, State),
    lists:foreach(Spawner, SplitSCC),
    length(SplitSCC).
  
  wait_results(0, Map, _FoldResFun) ->
    Map;
  wait_results(Pending, Map, FoldResFun) ->
    Res = receive_scc_result(),
    NewMap = lists:foldl(FoldResFun, Map, Res),
    wait_results(Pending-1, NewMap, FoldResFun).
  
  solve_scc_spawner(Parent, Map, State) ->
    fun(SCCPart) ->
        spawn_link(fun() -> solve_scc_worker(Parent, SCCPart, Map, State) end)
    end.
  
  split([], _Unit, Acc) ->
    Acc;
  split(List, Unit, Acc) ->
    {Taken, Rest} =
      try
        lists:split(Unit, List)
      catch
        _:_ -> {List, []}
      end,
    split(Rest, Unit, [Taken|Acc]).
  
  solve_scc_worker(Parent, SCCPart, Map, State) ->
    SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State) end,
    FinalMap = lists:foldl(SolveFun, Map, SCCPart),
    Res =
      [{F, t_limit(unsafe_lookup_type(F, FinalMap), ?TYPE_LIMIT)} ||
        F <- SCCPart],
    send_scc_result(Parent, Res).
  
  fold_res_fun(State) ->
    fun({F, Type}, Map) ->
        case state__get_rec_var(F, State) of
  	{ok, R} ->
  	  enter_type(R, Type, enter_type(F, Type, Map));
  	error ->
  	  enter_type(F, Type, Map)
        end
    end.
  
  receive_scc_result() ->
      receive
        {scc_fun, Res} -> Res
      end.
  
  send_scc_result(Parent, Res) ->
    Parent ! {scc_fun, Res}.
  
  %%------------------------------------------------------------------------------
  
  scc_fold_fun(F, FunMap, State) ->
    Deps = get_deps(state__get_cs(F, State)),
  