%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2020,2025 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% File: optimization_options.m
% Main author: zs
%
% THIS MODULE IS AUTOMATICALLY GENERATED BY tools/make_optimization_options.
% DO NOT EDIT.
%
% This module manages optimization options. It defines a type, the opt_tuple,
% that allows quick access to them, sets their default values, and implements
% the turning on of optimizations when a given optimization level is selected.
%

:- module libs.optimization_options.
:- interface.

:- import_module libs.options.

:- import_module bool.
:- import_module getopt.
:- import_module list.

%---------------------------------------------------------------------------%

:- type maybe_allow_inlining
    --->    allow_inlining
    ;       do_not_allow_inlining.
:- type maybe_inline_simple
    --->    inline_simple
    ;       do_not_inline_simple.
:- type maybe_inline_builtins
    --->    inline_builtins
    ;       do_not_inline_builtins.
:- type maybe_inline_single_use
    --->    inline_single_use
    ;       do_not_inline_single_use.
:- type maybe_enable_const_struct_poly
    --->    enable_const_struct_poly
    ;       do_not_enable_const_struct_poly.
:- type maybe_enable_const_struct_user
    --->    enable_const_struct_user
    ;       do_not_enable_const_struct_user.
:- type maybe_opt_common_structs
    --->    opt_common_structs
    ;       do_not_opt_common_structs.
:- type maybe_prop_constraints
    --->    prop_constraints
    ;       do_not_prop_constraints.
:- type maybe_prop_local_constraints
    --->    prop_local_constraints
    ;       do_not_prop_local_constraints.
:- type maybe_opt_dup_calls
    --->    opt_dup_calls
    ;       do_not_opt_dup_calls.
:- type maybe_prop_constants
    --->    prop_constants
    ;       do_not_prop_constants.
:- type maybe_elim_excess_assigns
    --->    elim_excess_assigns
    ;       do_not_elim_excess_assigns.
:- type maybe_merge_code_after_switch
    --->    merge_code_after_switch
    ;       do_not_merge_code_after_switch.
:- type maybe_opt_format_calls
    --->    opt_format_calls
    ;       do_not_opt_format_calls.
:- type maybe_split_switch_arms
    --->    split_switch_arms
    ;       do_not_split_switch_arms.
:- type maybe_opt_loop_invariants
    --->    opt_loop_invariants
    ;       do_not_opt_loop_invariants.
:- type maybe_opt_saved_vars_const
    --->    opt_saved_vars_const
    ;       do_not_opt_saved_vars_const.
:- type maybe_opt_svcell
    --->    opt_svcell
    ;       do_not_opt_svcell.
:- type maybe_opt_svcell_loop
    --->    opt_svcell_loop
    ;       do_not_opt_svcell_loop.
:- type maybe_opt_svcell_full_path
    --->    opt_svcell_full_path
    ;       do_not_opt_svcell_full_path.
:- type maybe_opt_svcell_on_stack
    --->    opt_svcell_on_stack
    ;       do_not_opt_svcell_on_stack.
:- type maybe_opt_svcell_candidate_headvars
    --->    opt_svcell_candidate_headvars
    ;       do_not_opt_svcell_candidate_headvars.
:- type maybe_opt_svcell_all_candidates
    --->    opt_svcell_all_candidates
    ;       do_not_opt_svcell_all_candidates.
:- type maybe_delay_constructs
    --->    delay_constructs
    ;       do_not_delay_constructs.
:- type maybe_opt_follow_code
    --->    opt_follow_code
    ;       do_not_opt_follow_code.
:- type maybe_opt_unused_args
    --->    opt_unused_args
    ;       do_not_opt_unused_args.
:- type maybe_opt_unused_args_intermod
    --->    opt_unused_args_intermod
    ;       do_not_opt_unused_args_intermod.
:- type maybe_opt_higher_order
    --->    opt_higher_order
    ;       do_not_opt_higher_order.
:- type maybe_opt_unneeded_code
    --->    opt_unneeded_code
    ;       do_not_opt_unneeded_code.
:- type maybe_spec_types
    --->    spec_types
    ;       do_not_spec_types.
:- type maybe_spec_types_user_guided
    --->    spec_types_user_guided
    ;       do_not_spec_types_user_guided.
:- type maybe_introduce_accumulators
    --->    introduce_accumulators
    ;       do_not_introduce_accumulators.
:- type maybe_opt_lcmc_accumulator
    --->    opt_lcmc_accumulator
    ;       do_not_opt_lcmc_accumulator.
:- type maybe_opt_lcmc_null
    --->    opt_lcmc_null
    ;       do_not_opt_lcmc_null.
:- type maybe_opt_lcmc
    --->    opt_lcmc
    ;       do_not_opt_lcmc.
:- type maybe_opt_dead_procs
    --->    opt_dead_procs
    ;       do_not_opt_dead_procs.
:- type maybe_deforest
    --->    deforest
    ;       do_not_deforest.
:- type maybe_untuple
    --->    untuple
    ;       do_not_untuple.
:- type maybe_tuple
    --->    tuple
    ;       do_not_tuple.
:- type maybe_inline_par_builtins
    --->    inline_par_builtins
    ;       do_not_inline_par_builtins.
:- type maybe_spec_in_all_dep_par_conjs
    --->    spec_in_all_dep_par_conjs
    ;       do_not_spec_in_all_dep_par_conjs.
:- type maybe_allow_some_paths_only_waits
    --->    allow_some_paths_only_waits
    ;       do_not_allow_some_paths_only_waits.
:- type maybe_analyse_regions
    --->    analyse_regions
    ;       do_not_analyse_regions.
:- type maybe_use_smart_indexing
    --->    use_smart_indexing
    ;       do_not_use_smart_indexing.
:- type maybe_use_smart_indexing_atomic
    --->    use_smart_indexing_atomic
    ;       do_not_use_smart_indexing_atomic.
:- type maybe_use_smart_indexing_string
    --->    use_smart_indexing_string
    ;       do_not_use_smart_indexing_string.
:- type maybe_use_smart_indexing_tag
    --->    use_smart_indexing_tag
    ;       do_not_use_smart_indexing_tag.
:- type maybe_use_smart_indexing_float
    --->    use_smart_indexing_float
    ;       do_not_use_smart_indexing_float.
:- type maybe_put_base_first_single_rec
    --->    put_base_first_single_rec
    ;       do_not_put_base_first_single_rec.
:- type maybe_put_base_first_multi_rec
    --->    put_base_first_multi_rec
    ;       do_not_put_base_first_multi_rec.
:- type maybe_use_static_ground_cells
    --->    use_static_ground_cells
    ;       do_not_use_static_ground_cells.
:- type maybe_use_static_ground_floats
    --->    use_static_ground_floats
    ;       do_not_use_static_ground_floats.
:- type maybe_use_static_ground_int64s
    --->    use_static_ground_int64s
    ;       do_not_use_static_ground_int64s.
:- type maybe_use_static_code_addresses
    --->    use_static_code_addresses
    ;       do_not_use_static_code_addresses.
:- type maybe_use_atomic_cells
    --->    use_atomic_cells
    ;       do_not_use_atomic_cells.
:- type maybe_opt_middle_rec_llds
    --->    opt_middle_rec_llds
    ;       do_not_opt_middle_rec_llds.
:- type maybe_opt_simple_neg_llds
    --->    opt_simple_neg_llds
    ;       do_not_opt_simple_neg_llds.
:- type maybe_allow_hijacks
    --->    allow_hijacks
    ;       do_not_allow_hijacks.
:- type maybe_opt_mlds_tailcalls
    --->    opt_mlds_tailcalls
    ;       do_not_opt_mlds_tailcalls.
:- type maybe_opt_mlds_inits
    --->    opt_mlds_inits
    ;       do_not_opt_mlds_inits.
:- type maybe_elim_unused_mlds_assigns
    --->    elim_unused_mlds_assigns
    ;       do_not_elim_unused_mlds_assigns.
:- type maybe_elim_local_vars_mlds
    --->    elim_local_vars_mlds
    ;       do_not_elim_local_vars_mlds.
:- type maybe_gen_trail_ops_inline_mlds
    --->    gen_trail_ops_inline_mlds
    ;       do_not_gen_trail_ops_inline_mlds.
:- type maybe_use_llds_common_data
    --->    use_llds_common_data
    ;       do_not_use_llds_common_data.
:- type maybe_use_llds_common_layout_data
    --->    use_llds_common_layout_data
    ;       do_not_use_llds_common_layout_data.
:- type maybe_optimize_llds
    --->    optimize_llds
    ;       do_not_optimize_llds.
:- type maybe_optimize_mlds
    --->    optimize_mlds
    ;       do_not_optimize_mlds.
:- type maybe_peep_llds
    --->    peep_llds
    ;       do_not_peep_llds.
:- type maybe_peep_llds_mkword
    --->    peep_llds_mkword
    ;       do_not_peep_llds_mkword.
:- type maybe_peep_mlds
    --->    peep_mlds
    ;       do_not_peep_mlds.
:- type maybe_opt_jumps
    --->    opt_jumps
    ;       do_not_opt_jumps.
:- type maybe_opt_fulljumps
    --->    opt_fulljumps
    ;       do_not_opt_fulljumps.
:- type maybe_pessimize_llds_tailcalls
    --->    pessimize_llds_tailcalls
    ;       do_not_pessimize_llds_tailcalls.
:- type maybe_opt_checked_nondet_tailcalls
    --->    opt_checked_nondet_tailcalls
    ;       do_not_opt_checked_nondet_tailcalls.
:- type maybe_use_local_vars_llds
    --->    use_local_vars_llds
    ;       do_not_use_local_vars_llds.
:- type maybe_standardize_labels
    --->    standardize_labels
    ;       do_not_standardize_labels.
:- type maybe_opt_labels
    --->    opt_labels
    ;       do_not_opt_labels.
:- type maybe_opt_dup_instrs_llds
    --->    opt_dup_instrs_llds
    ;       do_not_opt_dup_instrs_llds.
:- type maybe_opt_dup_procs_llds
    --->    opt_dup_procs_llds
    ;       do_not_opt_dup_procs_llds.
:- type maybe_opt_frames
    --->    opt_frames
    ;       do_not_opt_frames.
:- type maybe_opt_delay_slot
    --->    opt_delay_slot
    ;       do_not_opt_delay_slot.
:- type maybe_opt_llds_reassign
    --->    opt_llds_reassign
    ;       do_not_opt_llds_reassign.
:- type maybe_use_macro_for_redo_fail
    --->    use_macro_for_redo_fail
    ;       do_not_use_macro_for_redo_fail.
:- type maybe_emit_c_loops
    --->    emit_c_loops
    ;       do_not_emit_c_loops.
:- type maybe_use_just_one_c_func
    --->    use_just_one_c_func
    ;       do_not_use_just_one_c_func.
:- type maybe_use_local_thread_engine_base
    --->    use_local_thread_engine_base
    ;       do_not_use_local_thread_engine_base.
:- type maybe_inline_alloc
    --->    inline_alloc
    ;       do_not_inline_alloc.
:- type maybe_opt_c
    --->    opt_c
    ;       do_not_opt_c.

%---------------------%

:- type optimization_option
    --->    oo_allow_inlining(bool)
    ;       oo_inline_simple(bool)
    ;       oo_inline_builtins(bool)
    ;       oo_inline_single_use(bool)
    ;       oo_enable_const_struct_poly(bool)
    ;       oo_enable_const_struct_user(bool)
    ;       oo_opt_common_structs(bool)
    ;       oo_prop_constraints(bool)
    ;       oo_prop_local_constraints(bool)
    ;       oo_opt_dup_calls(bool)
    ;       oo_prop_constants(bool)
    ;       oo_elim_excess_assigns(bool)
    ;       oo_merge_code_after_switch(bool)
    ;       oo_opt_format_calls(bool)
    ;       oo_split_switch_arms(bool)
    ;       oo_opt_loop_invariants(bool)
    ;       oo_opt_saved_vars_const(bool)
    ;       oo_opt_svcell(bool)
    ;       oo_opt_svcell_loop(bool)
    ;       oo_opt_svcell_full_path(bool)
    ;       oo_opt_svcell_on_stack(bool)
    ;       oo_opt_svcell_candidate_headvars(bool)
    ;       oo_opt_svcell_all_candidates(bool)
    ;       oo_delay_constructs(bool)
    ;       oo_opt_follow_code(bool)
    ;       oo_opt_unused_args(bool)
    ;       oo_opt_unused_args_intermod(bool)
    ;       oo_opt_higher_order(bool)
    ;       oo_opt_unneeded_code(bool)
    ;       oo_spec_types(bool)
    ;       oo_spec_types_user_guided(bool)
    ;       oo_introduce_accumulators(bool)
    ;       oo_opt_lcmc_accumulator(bool)
    ;       oo_opt_lcmc_null(bool)
    ;       oo_opt_lcmc(bool)
    ;       oo_opt_dead_procs(bool)
    ;       oo_deforest(bool)
    ;       oo_untuple(bool)
    ;       oo_tuple(bool)
    ;       oo_inline_par_builtins(bool)
    ;       oo_spec_in_all_dep_par_conjs(bool)
    ;       oo_allow_some_paths_only_waits(bool)
    ;       oo_analyse_regions(bool)
    ;       oo_use_smart_indexing(bool)
    ;       oo_use_smart_indexing_atomic(bool)
    ;       oo_use_smart_indexing_string(bool)
    ;       oo_use_smart_indexing_tag(bool)
    ;       oo_use_smart_indexing_float(bool)
    ;       oo_put_base_first_single_rec(bool)
    ;       oo_put_base_first_multi_rec(bool)
    ;       oo_use_static_ground_cells(bool)
    ;       oo_use_static_ground_floats(bool)
    ;       oo_use_static_ground_int64s(bool)
    ;       oo_use_static_code_addresses(bool)
    ;       oo_use_atomic_cells(bool)
    ;       oo_opt_middle_rec_llds(bool)
    ;       oo_opt_simple_neg_llds(bool)
    ;       oo_allow_hijacks(bool)
    ;       oo_opt_mlds_tailcalls(bool)
    ;       oo_opt_mlds_inits(bool)
    ;       oo_elim_unused_mlds_assigns(bool)
    ;       oo_elim_local_vars_mlds(bool)
    ;       oo_gen_trail_ops_inline_mlds(bool)
    ;       oo_use_llds_common_data(bool)
    ;       oo_use_llds_common_layout_data(bool)
    ;       oo_optimize_llds(bool)
    ;       oo_optimize_mlds(bool)
    ;       oo_peep_llds(bool)
    ;       oo_peep_llds_mkword(bool)
    ;       oo_peep_mlds(bool)
    ;       oo_opt_jumps(bool)
    ;       oo_opt_fulljumps(bool)
    ;       oo_pessimize_llds_tailcalls(bool)
    ;       oo_opt_checked_nondet_tailcalls(bool)
    ;       oo_use_local_vars_llds(bool)
    ;       oo_standardize_labels(bool)
    ;       oo_opt_labels(bool)
    ;       oo_opt_dup_instrs_llds(bool)
    ;       oo_opt_dup_procs_llds(bool)
    ;       oo_opt_frames(bool)
    ;       oo_opt_delay_slot(bool)
    ;       oo_opt_llds_reassign(bool)
    ;       oo_use_macro_for_redo_fail(bool)
    ;       oo_emit_c_loops(bool)
    ;       oo_use_just_one_c_func(bool)
    ;       oo_use_local_thread_engine_base(bool)
    ;       oo_inline_alloc(bool)
    ;       oo_opt_c(bool)
    ;       oo_inline_call_cost(int)
    ;       oo_inline_compound_threshold(int)
    ;       oo_inline_simple_threshold(int)
    ;       oo_inline_vars_threshold(int)
    ;       oo_intermod_inline_simple_threshold(int)
    ;       oo_from_ground_term_threshold(int)
    ;       oo_opt_svcell_cv_store_cost(int)
    ;       oo_opt_svcell_cv_load_cost(int)
    ;       oo_opt_svcell_fv_store_cost(int)
    ;       oo_opt_svcell_fv_load_cost(int)
    ;       oo_opt_svcell_op_ratio(int)
    ;       oo_opt_svcell_node_ratio(int)
    ;       oo_opt_svcell_all_path_node_ratio(int)
    ;       oo_higher_order_size_limit(int)
    ;       oo_higher_order_arg_limit(int)
    ;       oo_opt_unneeded_code_copy_limit(int)
    ;       oo_deforestation_depth_limit(int)
    ;       oo_deforestation_cost_factor(int)
    ;       oo_deforestation_vars_threshold(int)
    ;       oo_deforestation_size_threshold(int)
    ;       oo_tuple_costs_ratio(int)
    ;       oo_tuple_min_args(int)
    ;       oo_dense_switch_req_density(int)
    ;       oo_lookup_switch_req_density(int)
    ;       oo_dense_switch_size(int)
    ;       oo_lookup_switch_size(int)
    ;       oo_string_trie_switch_size(int)
    ;       oo_string_hash_switch_size(int)
    ;       oo_string_binary_switch_size(int)
    ;       oo_tag_switch_size(int)
    ;       oo_try_switch_size(int)
    ;       oo_binary_switch_size(int)
    ;       oo_llds_local_var_access_threshold(int)
    ;       oo_opt_repeat(int)
    ;       oo_llds_layout_compression_limit(int)
    ;       oo_procs_per_c_function(int)
    ;       oo_tuple_trace_counts_file(string)
    ;       oo_opt_level(int)
    ;       oo_opt_for_space.

%---------------------%

:- type opt_tuple
    --->    opt_tuple(
                ot_allow_inlining             :: maybe_allow_inlining,
                ot_inline_simple              :: maybe_inline_simple,
                ot_inline_builtins            :: maybe_inline_builtins,
                ot_inline_single_use          :: maybe_inline_single_use,
                ot_enable_const_struct_poly   :: maybe_enable_const_struct_poly,
                ot_enable_const_struct_user   :: maybe_enable_const_struct_user,
                ot_opt_common_structs         :: maybe_opt_common_structs,
                ot_prop_constraints           :: maybe_prop_constraints,
                ot_prop_local_constraints     :: maybe_prop_local_constraints,
                ot_opt_dup_calls              :: maybe_opt_dup_calls,
                ot_prop_constants             :: maybe_prop_constants,
                ot_elim_excess_assigns        :: maybe_elim_excess_assigns,
                ot_merge_code_after_switch    :: maybe_merge_code_after_switch,
                ot_opt_format_calls           :: maybe_opt_format_calls,
                ot_split_switch_arms          :: maybe_split_switch_arms,
                ot_opt_loop_invariants        :: maybe_opt_loop_invariants,
                ot_opt_saved_vars_const       :: maybe_opt_saved_vars_const,
                ot_opt_svcell                 :: maybe_opt_svcell,
                ot_opt_svcell_loop            :: maybe_opt_svcell_loop,
                ot_opt_svcell_full_path       :: maybe_opt_svcell_full_path,
                ot_opt_svcell_on_stack        :: maybe_opt_svcell_on_stack,
                ot_opt_svcell_candidate_headvars :: maybe_opt_svcell_candidate_headvars,
                ot_opt_svcell_all_candidates  :: maybe_opt_svcell_all_candidates,
                ot_delay_constructs           :: maybe_delay_constructs,
                ot_opt_follow_code            :: maybe_opt_follow_code,
                ot_opt_unused_args            :: maybe_opt_unused_args,
                ot_opt_unused_args_intermod   :: maybe_opt_unused_args_intermod,
                ot_opt_higher_order           :: maybe_opt_higher_order,
                ot_opt_unneeded_code          :: maybe_opt_unneeded_code,
                ot_spec_types                 :: maybe_spec_types,
                ot_spec_types_user_guided     :: maybe_spec_types_user_guided,
                ot_introduce_accumulators     :: maybe_introduce_accumulators,
                ot_opt_lcmc_accumulator       :: maybe_opt_lcmc_accumulator,
                ot_opt_lcmc_null              :: maybe_opt_lcmc_null,
                ot_opt_lcmc                   :: maybe_opt_lcmc,
                ot_opt_dead_procs             :: maybe_opt_dead_procs,
                ot_deforest                   :: maybe_deforest,
                ot_untuple                    :: maybe_untuple,
                ot_tuple                      :: maybe_tuple,
                ot_inline_par_builtins        :: maybe_inline_par_builtins,
                ot_spec_in_all_dep_par_conjs  :: maybe_spec_in_all_dep_par_conjs,
                ot_allow_some_paths_only_waits :: maybe_allow_some_paths_only_waits,
                ot_analyse_regions            :: maybe_analyse_regions,
                ot_use_smart_indexing         :: maybe_use_smart_indexing,
                ot_use_smart_indexing_atomic  :: maybe_use_smart_indexing_atomic,
                ot_use_smart_indexing_string  :: maybe_use_smart_indexing_string,
                ot_use_smart_indexing_tag     :: maybe_use_smart_indexing_tag,
                ot_use_smart_indexing_float   :: maybe_use_smart_indexing_float,
                ot_put_base_first_single_rec  :: maybe_put_base_first_single_rec,
                ot_put_base_first_multi_rec   :: maybe_put_base_first_multi_rec,
                ot_use_static_ground_cells    :: maybe_use_static_ground_cells,
                ot_use_static_ground_floats   :: maybe_use_static_ground_floats,
                ot_use_static_ground_int64s   :: maybe_use_static_ground_int64s,
                ot_use_static_code_addresses  :: maybe_use_static_code_addresses,
                ot_use_atomic_cells           :: maybe_use_atomic_cells,
                ot_opt_middle_rec_llds        :: maybe_opt_middle_rec_llds,
                ot_opt_simple_neg_llds        :: maybe_opt_simple_neg_llds,
                ot_allow_hijacks              :: maybe_allow_hijacks,
                ot_opt_mlds_tailcalls         :: maybe_opt_mlds_tailcalls,
                ot_opt_mlds_inits             :: maybe_opt_mlds_inits,
                ot_elim_unused_mlds_assigns   :: maybe_elim_unused_mlds_assigns,
                ot_elim_local_vars_mlds       :: maybe_elim_local_vars_mlds,
                ot_gen_trail_ops_inline_mlds  :: maybe_gen_trail_ops_inline_mlds,
                ot_use_llds_common_data       :: maybe_use_llds_common_data,
                ot_use_llds_common_layout_data :: maybe_use_llds_common_layout_data,
                ot_optimize_llds              :: maybe_optimize_llds,
                ot_optimize_mlds              :: maybe_optimize_mlds,
                ot_peep_llds                  :: maybe_peep_llds,
                ot_peep_llds_mkword           :: maybe_peep_llds_mkword,
                ot_peep_mlds                  :: maybe_peep_mlds,
                ot_opt_jumps                  :: maybe_opt_jumps,
                ot_opt_fulljumps              :: maybe_opt_fulljumps,
                ot_pessimize_llds_tailcalls   :: maybe_pessimize_llds_tailcalls,
                ot_opt_checked_nondet_tailcalls :: maybe_opt_checked_nondet_tailcalls,
                ot_use_local_vars_llds        :: maybe_use_local_vars_llds,
                ot_standardize_labels         :: maybe_standardize_labels,
                ot_opt_labels                 :: maybe_opt_labels,
                ot_opt_dup_instrs_llds        :: maybe_opt_dup_instrs_llds,
                ot_opt_dup_procs_llds         :: maybe_opt_dup_procs_llds,
                ot_opt_frames                 :: maybe_opt_frames,
                ot_opt_delay_slot             :: maybe_opt_delay_slot,
                ot_opt_llds_reassign          :: maybe_opt_llds_reassign,
                ot_use_macro_for_redo_fail    :: maybe_use_macro_for_redo_fail,
                ot_emit_c_loops               :: maybe_emit_c_loops,
                ot_use_just_one_c_func        :: maybe_use_just_one_c_func,
                ot_use_local_thread_engine_base :: maybe_use_local_thread_engine_base,
                ot_inline_alloc               :: maybe_inline_alloc,
                ot_opt_c                      :: maybe_opt_c,
                ot_inline_call_cost           :: int,
                ot_inline_compound_threshold  :: int,
                ot_inline_simple_threshold    :: int,
                ot_inline_vars_threshold      :: int,
                ot_intermod_inline_simple_threshold :: int,
                ot_from_ground_term_threshold :: int,
                ot_opt_svcell_cv_store_cost   :: int,
                ot_opt_svcell_cv_load_cost    :: int,
                ot_opt_svcell_fv_store_cost   :: int,
                ot_opt_svcell_fv_load_cost    :: int,
                ot_opt_svcell_op_ratio        :: int,
                ot_opt_svcell_node_ratio      :: int,
                ot_opt_svcell_all_path_node_ratio :: int,
                ot_higher_order_size_limit    :: int,
                ot_higher_order_arg_limit     :: int,
                ot_opt_unneeded_code_copy_limit :: int,
                ot_deforestation_depth_limit  :: int,
                ot_deforestation_cost_factor  :: int,
                ot_deforestation_vars_threshold :: int,
                ot_deforestation_size_threshold :: int,
                ot_tuple_costs_ratio          :: int,
                ot_tuple_min_args             :: int,
                ot_dense_switch_req_density   :: int,
                ot_lookup_switch_req_density  :: int,
                ot_dense_switch_size          :: int,
                ot_lookup_switch_size         :: int,
                ot_string_trie_switch_size    :: int,
                ot_string_hash_switch_size    :: int,
                ot_string_binary_switch_size  :: int,
                ot_tag_switch_size            :: int,
                ot_try_switch_size            :: int,
                ot_binary_switch_size         :: int,
                ot_llds_local_var_access_threshold :: int,
                ot_opt_repeat                 :: int,
                ot_llds_layout_compression_limit :: int,
                ot_procs_per_c_function       :: int,
                ot_tuple_trace_counts_file    :: string
            ).

:- pred bool_option_initial_n_y(list(option)::out, list(option)::out) is det.

:- pred process_optimization_options(option_table::in,
    list(optimization_option)::in, opt_tuple::out) is det.

:- type documented_optimization_option
    --->    doc_oo(
                optimization_option,
                option,
                option_data_bool_int
            ).

:- type option_data_bool_int =< option_data
    --->    bool(bool)
    ;       int(int).

:- pred opts_enabled_at_level(int::in, list(string)::out,
    list(documented_optimization_option)::out) is semidet.

%---------------------------------------------------------------------------%

:- implementation.

:- import_module int.
:- import_module map.
:- import_module string.

%---------------------%

bool_option_initial_n_y(No, Yes) :-
    No = [
        optopt_inline_simple,
        optopt_inline_single_use,
        optopt_opt_common_structs,
        optopt_prop_constraints,
        optopt_prop_local_constraints,
        optopt_opt_dup_calls,
        optopt_prop_constants,
        optopt_elim_excess_assigns,
        optopt_merge_code_after_switch,
        optopt_opt_loop_invariants,
        optopt_opt_saved_vars_const,
        optopt_opt_svcell,
        optopt_opt_svcell_all_candidates,
        optopt_delay_constructs,
        optopt_opt_follow_code,
        optopt_opt_unused_args,
        optopt_opt_unused_args_intermod,
        optopt_opt_higher_order,
        optopt_opt_unneeded_code,
        optopt_spec_types,
        optopt_spec_types_user_guided,
        optopt_introduce_accumulators,
        optopt_opt_lcmc_accumulator,
        optopt_opt_lcmc_null,
        optopt_opt_lcmc,
        optopt_opt_dead_procs,
        optopt_deforest,
        optopt_untuple,
        optopt_tuple,
        optopt_inline_par_builtins,
        optopt_spec_in_all_dep_par_conjs,
        optopt_analyse_regions,
        optopt_use_smart_indexing,
        optopt_use_smart_indexing_atomic,
        optopt_use_smart_indexing_string,
        optopt_use_smart_indexing_tag,
        optopt_use_smart_indexing_float,
        optopt_put_base_first_single_rec,
        optopt_use_static_ground_cells,
        optopt_use_static_ground_floats,
        optopt_use_static_ground_int64s,
        optopt_use_static_code_addresses,
        optopt_use_atomic_cells,
        optopt_opt_middle_rec_llds,
        optopt_opt_simple_neg_llds,
        optopt_opt_mlds_tailcalls,
        optopt_opt_mlds_inits,
        optopt_elim_local_vars_mlds,
        optopt_use_llds_common_data,
        optopt_optimize_llds,
        optopt_optimize_mlds,
        optopt_peep_llds,
        optopt_peep_llds_mkword,
        optopt_peep_mlds,
        optopt_opt_jumps,
        optopt_opt_fulljumps,
        optopt_pessimize_llds_tailcalls,
        optopt_opt_checked_nondet_tailcalls,
        optopt_use_local_vars_llds,
        optopt_standardize_labels,
        optopt_opt_labels,
        optopt_opt_dup_instrs_llds,
        optopt_opt_dup_procs_llds,
        optopt_opt_frames,
        optopt_opt_delay_slot,
        optopt_opt_llds_reassign,
        optopt_use_macro_for_redo_fail,
        optopt_emit_c_loops,
        optopt_use_just_one_c_func,
        optopt_inline_alloc,
        optopt_c_optimize
    ],
    Yes = [
        optopt_allow_inlining,
        optopt_inline_builtins,
        optopt_enable_const_struct_poly,
        optopt_enable_const_struct_user,
        optopt_opt_format_calls,
        optopt_split_switch_arms,
        optopt_opt_svcell_loop,
        optopt_opt_svcell_full_path,
        optopt_opt_svcell_on_stack,
        optopt_opt_svcell_candidate_headvars,
        optopt_allow_some_paths_only_waits,
        optopt_put_base_first_multi_rec,
        optopt_allow_hijacks,
        optopt_elim_unused_mlds_assigns,
        optopt_gen_trail_ops_inline_mlds,
        optopt_use_llds_common_layout_data,
        optopt_use_local_thread_engine_base
    ].

%---------------------%

process_optimization_options(OptionTable, OptOptions, !:OptTuple) :-
    !:OptTuple = init_opt_tuple,
    list.foldl2(
        update_opt_tuple(not_from_opt_level, OptionTable),
        OptOptions, !OptTuple, not_seen_opt_level, MaybeSeenOptLevel),
    (
        MaybeSeenOptLevel = not_seen_opt_level,
        get_default_opt_level(OptionTable, DefaultOptLevel),
        set_opts_upto_level(OptionTable, 0, DefaultOptLevel,
            !OptTuple, MaybeSeenOptLevel, _)
    ;
        MaybeSeenOptLevel = seen_opt_level
    ).

%---------------------%

:- func init_opt_tuple = opt_tuple.

init_opt_tuple =
    opt_tuple(
        allow_inlining,
        do_not_inline_simple,
        inline_builtins,
        do_not_inline_single_use,
        enable_const_struct_poly,
        enable_const_struct_user,
        do_not_opt_common_structs,
        do_not_prop_constraints,
        do_not_prop_local_constraints,
        do_not_opt_dup_calls,
        do_not_prop_constants,
        do_not_elim_excess_assigns,
        do_not_merge_code_after_switch,
        opt_format_calls,
        split_switch_arms,
        do_not_opt_loop_invariants,
        do_not_opt_saved_vars_const,
        do_not_opt_svcell,
        opt_svcell_loop,
        opt_svcell_full_path,
        opt_svcell_on_stack,
        opt_svcell_candidate_headvars,
        do_not_opt_svcell_all_candidates,
        do_not_delay_constructs,
        do_not_opt_follow_code,
        do_not_opt_unused_args,
        do_not_opt_unused_args_intermod,
        do_not_opt_higher_order,
        do_not_opt_unneeded_code,
        do_not_spec_types,
        do_not_spec_types_user_guided,
        do_not_introduce_accumulators,
        do_not_opt_lcmc_accumulator,
        do_not_opt_lcmc_null,
        do_not_opt_lcmc,
        do_not_opt_dead_procs,
        do_not_deforest,
        do_not_untuple,
        do_not_tuple,
        do_not_inline_par_builtins,
        do_not_spec_in_all_dep_par_conjs,
        allow_some_paths_only_waits,
        do_not_analyse_regions,
        do_not_use_smart_indexing,
        do_not_use_smart_indexing_atomic,
        do_not_use_smart_indexing_string,
        do_not_use_smart_indexing_tag,
        do_not_use_smart_indexing_float,
        do_not_put_base_first_single_rec,
        put_base_first_multi_rec,
        do_not_use_static_ground_cells,
        do_not_use_static_ground_floats,
        do_not_use_static_ground_int64s,
        do_not_use_static_code_addresses,
        do_not_use_atomic_cells,
        do_not_opt_middle_rec_llds,
        do_not_opt_simple_neg_llds,
        allow_hijacks,
        do_not_opt_mlds_tailcalls,
        do_not_opt_mlds_inits,
        elim_unused_mlds_assigns,
        do_not_elim_local_vars_mlds,
        gen_trail_ops_inline_mlds,
        do_not_use_llds_common_data,
        use_llds_common_layout_data,
        do_not_optimize_llds,
        do_not_optimize_mlds,
        do_not_peep_llds,
        do_not_peep_llds_mkword,
        do_not_peep_mlds,
        do_not_opt_jumps,
        do_not_opt_fulljumps,
        do_not_pessimize_llds_tailcalls,
        do_not_opt_checked_nondet_tailcalls,
        do_not_use_local_vars_llds,
        do_not_standardize_labels,
        do_not_opt_labels,
        do_not_opt_dup_instrs_llds,
        do_not_opt_dup_procs_llds,
        do_not_opt_frames,
        do_not_opt_delay_slot,
        do_not_opt_llds_reassign,
        do_not_use_macro_for_redo_fail,
        do_not_emit_c_loops,
        do_not_use_just_one_c_func,
        use_local_thread_engine_base,
        do_not_inline_alloc,
        do_not_opt_c,
        0,
        0,
        5,
        100,
        5,
        5,
        3,
        1,
        1,
        1,
        100,
        100,
        100,
        20,
        10,
        10,
        4,
        1000,
        200,
        15,
        100,
        4,
        25,
        25,
        4,
        4,
        16,
        8,
        4,
        3,
        3,
        4,
        2,
        0,
        4000,
        1,
        ""
    ).

%---------------------%

:- type maybe_seen_opt_level
    --->    not_seen_opt_level
    ;       seen_opt_level.

:- type maybe_from_opt_level
    --->    not_from_opt_level
    ;       from_opt_level.

:- pred update_opt_tuple(maybe_from_opt_level::in, option_table::in,
    optimization_option::in, opt_tuple::in, opt_tuple::out,
    maybe_seen_opt_level::in, maybe_seen_opt_level::out) is det.

update_opt_tuple(FromOptLevel, OptionTable, OptOption, !OptTuple,
        !MaybeSeenOptLevel) :-
    require_complete_switch [OptOption]
    (
        OptOption = oo_allow_inlining(Bool),
        update_opt_tuple_bool_allow_inlining(Bool, !OptTuple)
    ;
        OptOption = oo_inline_simple(Bool),
        update_opt_tuple_bool_inline_simple(Bool, !OptTuple)
    ;
        OptOption = oo_inline_builtins(Bool),
        update_opt_tuple_bool_inline_builtins(Bool, !OptTuple)
    ;
        OptOption = oo_inline_single_use(Bool),
        update_opt_tuple_bool_inline_single_use(Bool, !OptTuple)
    ;
        OptOption = oo_enable_const_struct_poly(Bool),
        update_opt_tuple_bool_enable_const_struct_poly(Bool, !OptTuple)
    ;
        OptOption = oo_enable_const_struct_user(Bool),
        update_opt_tuple_bool_enable_const_struct_user(Bool, !OptTuple)
    ;
        OptOption = oo_opt_common_structs(Bool),
        update_opt_tuple_bool_opt_common_structs(Bool, !OptTuple)
    ;
        OptOption = oo_prop_constraints(Bool),
        update_opt_tuple_bool_prop_constraints(Bool, !OptTuple)
    ;
        OptOption = oo_prop_local_constraints(Bool),
        update_opt_tuple_bool_prop_local_constraints(Bool, !OptTuple)
    ;
        OptOption = oo_opt_dup_calls(Bool),
        update_opt_tuple_bool_opt_dup_calls(Bool, !OptTuple)
    ;
        OptOption = oo_prop_constants(Bool),
        update_opt_tuple_bool_prop_constants(Bool, !OptTuple)
    ;
        OptOption = oo_elim_excess_assigns(Bool),
        update_opt_tuple_bool_elim_excess_assigns(Bool, !OptTuple)
    ;
        OptOption = oo_merge_code_after_switch(Bool),
        update_opt_tuple_bool_merge_code_after_switch(Bool, !OptTuple)
    ;
        OptOption = oo_opt_format_calls(Bool),
        update_opt_tuple_bool_opt_format_calls(Bool, !OptTuple)
    ;
        OptOption = oo_split_switch_arms(Bool),
        update_opt_tuple_bool_split_switch_arms(Bool, !OptTuple)
    ;
        OptOption = oo_opt_loop_invariants(Bool),
        update_opt_tuple_bool_opt_loop_invariants(Bool, !OptTuple)
    ;
        OptOption = oo_opt_saved_vars_const(Bool),
        update_opt_tuple_bool_opt_saved_vars_const(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell(Bool),
        update_opt_tuple_bool_opt_svcell(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell_loop(Bool),
        update_opt_tuple_bool_opt_svcell_loop(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell_full_path(Bool),
        update_opt_tuple_bool_opt_svcell_full_path(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell_on_stack(Bool),
        update_opt_tuple_bool_opt_svcell_on_stack(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell_candidate_headvars(Bool),
        update_opt_tuple_bool_opt_svcell_candidate_headvars(Bool, !OptTuple)
    ;
        OptOption = oo_opt_svcell_all_candidates(Bool),
        update_opt_tuple_bool_opt_svcell_all_candidates(Bool, !OptTuple)
    ;
        OptOption = oo_delay_constructs(Bool),
        update_opt_tuple_bool_delay_constructs(Bool, !OptTuple)
    ;
        OptOption = oo_opt_follow_code(Bool),
        update_opt_tuple_bool_opt_follow_code(Bool, !OptTuple)
    ;
        OptOption = oo_opt_unused_args(Bool),
        update_opt_tuple_bool_opt_unused_args(Bool, !OptTuple)
    ;
        OptOption = oo_opt_unused_args_intermod(Bool),
        update_opt_tuple_bool_opt_unused_args_intermod(Bool, !OptTuple)
    ;
        OptOption = oo_opt_higher_order(Bool),
        update_opt_tuple_bool_opt_higher_order(Bool, !OptTuple)
    ;
        OptOption = oo_opt_unneeded_code(Bool),
        update_opt_tuple_bool_opt_unneeded_code(Bool, !OptTuple)
    ;
        OptOption = oo_spec_types(Bool),
        update_opt_tuple_bool_spec_types(Bool, !OptTuple)
    ;
        OptOption = oo_spec_types_user_guided(Bool),
        update_opt_tuple_bool_spec_types_user_guided(Bool, !OptTuple)
    ;
        OptOption = oo_introduce_accumulators(Bool),
        update_opt_tuple_bool_introduce_accumulators(Bool, !OptTuple)
    ;
        OptOption = oo_opt_lcmc_accumulator(Bool),
        update_opt_tuple_bool_opt_lcmc_accumulator(Bool, !OptTuple)
    ;
        OptOption = oo_opt_lcmc_null(Bool),
        update_opt_tuple_bool_opt_lcmc_null(Bool, !OptTuple)
    ;
        OptOption = oo_opt_lcmc(Bool),
        update_opt_tuple_bool_opt_lcmc(Bool, !OptTuple)
    ;
        OptOption = oo_opt_dead_procs(Bool),
        update_opt_tuple_bool_opt_dead_procs(Bool, !OptTuple)
    ;
        OptOption = oo_deforest(Bool),
        update_opt_tuple_bool_deforest(Bool, !OptTuple)
    ;
        OptOption = oo_untuple(Bool),
        update_opt_tuple_bool_untuple(Bool, !OptTuple)
    ;
        OptOption = oo_tuple(Bool),
        update_opt_tuple_bool_tuple(Bool, !OptTuple)
    ;
        OptOption = oo_inline_par_builtins(Bool),
        update_opt_tuple_bool_inline_par_builtins(Bool, !OptTuple)
    ;
        OptOption = oo_spec_in_all_dep_par_conjs(Bool),
        update_opt_tuple_bool_spec_in_all_dep_par_conjs(Bool, !OptTuple)
    ;
        OptOption = oo_allow_some_paths_only_waits(Bool),
        update_opt_tuple_bool_allow_some_paths_only_waits(Bool, !OptTuple)
    ;
        OptOption = oo_analyse_regions(Bool),
        update_opt_tuple_bool_analyse_regions(Bool, !OptTuple)
    ;
        OptOption = oo_use_smart_indexing(Bool),
        update_opt_tuple_bool_use_smart_indexing(Bool, !OptTuple)
    ;
        OptOption = oo_use_smart_indexing_atomic(Bool),
        update_opt_tuple_bool_use_smart_indexing_atomic(Bool, !OptTuple)
    ;
        OptOption = oo_use_smart_indexing_string(Bool),
        update_opt_tuple_bool_use_smart_indexing_string(Bool, !OptTuple)
    ;
        OptOption = oo_use_smart_indexing_tag(Bool),
        update_opt_tuple_bool_use_smart_indexing_tag(Bool, !OptTuple)
    ;
        OptOption = oo_use_smart_indexing_float(Bool),
        update_opt_tuple_bool_use_smart_indexing_float(Bool, !OptTuple)
    ;
        OptOption = oo_put_base_first_single_rec(Bool),
        update_opt_tuple_bool_put_base_first_single_rec(Bool, !OptTuple)
    ;
        OptOption = oo_put_base_first_multi_rec(Bool),
        update_opt_tuple_bool_put_base_first_multi_rec(Bool, !OptTuple)
    ;
        OptOption = oo_use_static_ground_cells(Bool),
        update_opt_tuple_bool_use_static_ground_cells(Bool, !OptTuple)
    ;
        OptOption = oo_use_static_ground_floats(Bool),
        update_opt_tuple_bool_use_static_ground_floats(Bool, !OptTuple)
    ;
        OptOption = oo_use_static_ground_int64s(Bool),
        update_opt_tuple_bool_use_static_ground_int64s(Bool, !OptTuple)
    ;
        OptOption = oo_use_static_code_addresses(Bool),
        update_opt_tuple_bool_use_static_code_addresses(Bool, !OptTuple)
    ;
        OptOption = oo_use_atomic_cells(Bool),
        update_opt_tuple_bool_use_atomic_cells(Bool, !OptTuple)
    ;
        OptOption = oo_opt_middle_rec_llds(Bool),
        update_opt_tuple_bool_opt_middle_rec_llds(Bool, !OptTuple)
    ;
        OptOption = oo_opt_simple_neg_llds(Bool),
        update_opt_tuple_bool_opt_simple_neg_llds(Bool, !OptTuple)
    ;
        OptOption = oo_allow_hijacks(Bool),
        update_opt_tuple_bool_allow_hijacks(Bool, !OptTuple)
    ;
        OptOption = oo_opt_mlds_tailcalls(Bool),
        update_opt_tuple_bool_opt_mlds_tailcalls(Bool, !OptTuple)
    ;
        OptOption = oo_opt_mlds_inits(Bool),
        update_opt_tuple_bool_opt_mlds_inits(Bool, !OptTuple)
    ;
        OptOption = oo_elim_unused_mlds_assigns(Bool),
        update_opt_tuple_bool_elim_unused_mlds_assigns(Bool, !OptTuple)
    ;
        OptOption = oo_elim_local_vars_mlds(Bool),
        update_opt_tuple_bool_elim_local_vars_mlds(Bool, !OptTuple)
    ;
        OptOption = oo_gen_trail_ops_inline_mlds(Bool),
        update_opt_tuple_bool_gen_trail_ops_inline_mlds(Bool, !OptTuple)
    ;
        OptOption = oo_use_llds_common_data(Bool),
        update_opt_tuple_bool_use_llds_common_data(Bool, !OptTuple)
    ;
        OptOption = oo_use_llds_common_layout_data(Bool),
        update_opt_tuple_bool_use_llds_common_layout_data(Bool, !OptTuple)
    ;
        OptOption = oo_optimize_llds(Bool),
        update_opt_tuple_bool_optimize_llds(Bool, !OptTuple)
    ;
        OptOption = oo_optimize_mlds(Bool),
        update_opt_tuple_bool_optimize_mlds(Bool, !OptTuple)
    ;
        OptOption = oo_peep_llds(Bool),
        update_opt_tuple_bool_peep_llds(Bool, !OptTuple)
    ;
        OptOption = oo_peep_llds_mkword(Bool),
        update_opt_tuple_bool_peep_llds_mkword(Bool, !OptTuple)
    ;
        OptOption = oo_peep_mlds(Bool),
        update_opt_tuple_bool_peep_mlds(Bool, !OptTuple)
    ;
        OptOption = oo_opt_jumps(Bool),
        update_opt_tuple_bool_opt_jumps(Bool, !OptTuple)
    ;
        OptOption = oo_opt_fulljumps(Bool),
        update_opt_tuple_bool_opt_fulljumps(Bool, !OptTuple)
    ;
        OptOption = oo_pessimize_llds_tailcalls(Bool),
        update_opt_tuple_bool_pessimize_llds_tailcalls(Bool, !OptTuple)
    ;
        OptOption = oo_opt_checked_nondet_tailcalls(Bool),
        update_opt_tuple_bool_opt_checked_nondet_tailcalls(Bool, !OptTuple)
    ;
        OptOption = oo_use_local_vars_llds(Bool),
        update_opt_tuple_bool_use_local_vars_llds(Bool, !OptTuple)
    ;
        OptOption = oo_standardize_labels(Bool),
        update_opt_tuple_bool_standardize_labels(Bool, !OptTuple)
    ;
        OptOption = oo_opt_labels(Bool),
        update_opt_tuple_bool_opt_labels(Bool, !OptTuple)
    ;
        OptOption = oo_opt_dup_instrs_llds(Bool),
        update_opt_tuple_bool_opt_dup_instrs_llds(Bool, !OptTuple)
    ;
        OptOption = oo_opt_dup_procs_llds(Bool),
        update_opt_tuple_bool_opt_dup_procs_llds(Bool, !OptTuple)
    ;
        OptOption = oo_opt_frames(Bool),
        update_opt_tuple_bool_opt_frames(Bool, !OptTuple)
    ;
        OptOption = oo_opt_delay_slot(Bool),
        update_opt_tuple_bool_opt_delay_slot(OptionTable, Bool, !OptTuple)
    ;
        OptOption = oo_opt_llds_reassign(Bool),
        update_opt_tuple_bool_opt_llds_reassign(Bool, !OptTuple)
    ;
        OptOption = oo_use_macro_for_redo_fail(Bool),
        update_opt_tuple_bool_use_macro_for_redo_fail(Bool, !OptTuple)
    ;
        OptOption = oo_emit_c_loops(Bool),
        update_opt_tuple_bool_emit_c_loops(Bool, !OptTuple)
    ;
        OptOption = oo_use_just_one_c_func(Bool),
        update_opt_tuple_bool_use_just_one_c_func(Bool, !OptTuple)
    ;
        OptOption = oo_use_local_thread_engine_base(Bool),
        update_opt_tuple_bool_use_local_thread_engine_base(Bool, !OptTuple)
    ;
        OptOption = oo_inline_alloc(Bool),
        update_opt_tuple_bool_inline_alloc(Bool, !OptTuple)
    ;
        OptOption = oo_opt_c(Bool),
        update_opt_tuple_bool_opt_c(Bool, !OptTuple)
    ;
        OptOption = oo_inline_call_cost(N),
        update_opt_tuple_int_inline_call_cost(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_inline_compound_threshold(N),
        update_opt_tuple_int_inline_compound_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_inline_simple_threshold(N),
        update_opt_tuple_int_inline_simple_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_inline_vars_threshold(N),
        update_opt_tuple_int_inline_vars_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_intermod_inline_simple_threshold(N),
        update_opt_tuple_int_intermod_inline_simple_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_from_ground_term_threshold(N),
        update_opt_tuple_int_from_ground_term_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_cv_store_cost(N),
        update_opt_tuple_int_opt_svcell_cv_store_cost(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_cv_load_cost(N),
        update_opt_tuple_int_opt_svcell_cv_load_cost(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_fv_store_cost(N),
        update_opt_tuple_int_opt_svcell_fv_store_cost(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_fv_load_cost(N),
        update_opt_tuple_int_opt_svcell_fv_load_cost(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_op_ratio(N),
        update_opt_tuple_int_opt_svcell_op_ratio(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_node_ratio(N),
        update_opt_tuple_int_opt_svcell_node_ratio(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_svcell_all_path_node_ratio(N),
        update_opt_tuple_int_opt_svcell_all_path_node_ratio(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_higher_order_size_limit(N),
        update_opt_tuple_int_higher_order_size_limit(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_higher_order_arg_limit(N),
        update_opt_tuple_int_higher_order_arg_limit(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_unneeded_code_copy_limit(N),
        update_opt_tuple_int_opt_unneeded_code_copy_limit(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_deforestation_depth_limit(N),
        update_opt_tuple_int_deforestation_depth_limit(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_deforestation_cost_factor(N),
        update_opt_tuple_int_deforestation_cost_factor(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_deforestation_vars_threshold(N),
        update_opt_tuple_int_deforestation_vars_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_deforestation_size_threshold(N),
        update_opt_tuple_int_deforestation_size_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_tuple_costs_ratio(N),
        update_opt_tuple_int_tuple_costs_ratio(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_tuple_min_args(N),
        update_opt_tuple_int_tuple_min_args(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_dense_switch_req_density(N),
        update_opt_tuple_int_dense_switch_req_density(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_lookup_switch_req_density(N),
        update_opt_tuple_int_lookup_switch_req_density(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_dense_switch_size(N),
        update_opt_tuple_int_dense_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_lookup_switch_size(N),
        update_opt_tuple_int_lookup_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_string_trie_switch_size(N),
        update_opt_tuple_int_string_trie_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_string_hash_switch_size(N),
        update_opt_tuple_int_string_hash_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_string_binary_switch_size(N),
        update_opt_tuple_int_string_binary_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_tag_switch_size(N),
        update_opt_tuple_int_tag_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_try_switch_size(N),
        update_opt_tuple_int_try_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_binary_switch_size(N),
        update_opt_tuple_int_binary_switch_size(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_llds_local_var_access_threshold(N),
        update_opt_tuple_int_llds_local_var_access_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_repeat(N),
        update_opt_tuple_int_opt_repeat(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_llds_layout_compression_limit(N),
        update_opt_tuple_int_llds_layout_compression_limit(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_procs_per_c_function(N),
        update_opt_tuple_int_procs_per_c_function(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_tuple_trace_counts_file(Str),
        !OptTuple ^ ot_tuple_trace_counts_file := Str
    ;
        OptOption = oo_opt_level(OptLevel),
        set_opts_upto_level(OptionTable, 0, OptLevel, !OptTuple, !.MaybeSeenOptLevel, _),
        !:MaybeSeenOptLevel = seen_opt_level
    ;
        OptOption = oo_opt_for_space,
        set_opts_for_space(!OptTuple)
    ).

:- pred update_opt_tuple_bool_allow_inlining(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_allow_inlining(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_allow_inlining,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_allow_inlining,
            !OptTuple ^ ot_allow_inlining := allow_inlining
        ;
            OldValue = allow_inlining
        )
    else
        (
            OldValue = do_not_allow_inlining
        ;
            OldValue = allow_inlining,
            !OptTuple ^ ot_allow_inlining := do_not_allow_inlining
        )
    ).

:- pred update_opt_tuple_bool_inline_simple(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_simple(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_simple,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_simple,
            !OptTuple ^ ot_inline_simple := inline_simple
        ;
            OldValue = inline_simple
        )
    else
        (
            OldValue = do_not_inline_simple
        ;
            OldValue = inline_simple,
            !OptTuple ^ ot_inline_simple := do_not_inline_simple
        )
    ).

:- pred update_opt_tuple_bool_inline_builtins(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_builtins(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_builtins,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_builtins,
            !OptTuple ^ ot_inline_builtins := inline_builtins
        ;
            OldValue = inline_builtins
        )
    else
        (
            OldValue = do_not_inline_builtins
        ;
            OldValue = inline_builtins,
            !OptTuple ^ ot_inline_builtins := do_not_inline_builtins
        )
    ).

:- pred update_opt_tuple_bool_inline_single_use(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_single_use(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_single_use,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_single_use,
            !OptTuple ^ ot_inline_single_use := inline_single_use
        ;
            OldValue = inline_single_use
        )
    else
        (
            OldValue = do_not_inline_single_use
        ;
            OldValue = inline_single_use,
            !OptTuple ^ ot_inline_single_use := do_not_inline_single_use
        )
    ).

:- pred update_opt_tuple_bool_enable_const_struct_poly(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_enable_const_struct_poly(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_enable_const_struct_poly,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_enable_const_struct_poly,
            !OptTuple ^ ot_enable_const_struct_poly := enable_const_struct_poly
        ;
            OldValue = enable_const_struct_poly
        )
    else
        (
            OldValue = do_not_enable_const_struct_poly
        ;
            OldValue = enable_const_struct_poly,
            !OptTuple ^ ot_enable_const_struct_poly := do_not_enable_const_struct_poly
        )
    ).

:- pred update_opt_tuple_bool_enable_const_struct_user(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_enable_const_struct_user(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_enable_const_struct_user,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_enable_const_struct_user,
            !OptTuple ^ ot_enable_const_struct_user := enable_const_struct_user
        ;
            OldValue = enable_const_struct_user
        )
    else
        (
            OldValue = do_not_enable_const_struct_user
        ;
            OldValue = enable_const_struct_user,
            !OptTuple ^ ot_enable_const_struct_user := do_not_enable_const_struct_user
        )
    ).

:- pred update_opt_tuple_bool_opt_common_structs(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_common_structs(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_common_structs,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_common_structs,
            !OptTuple ^ ot_opt_common_structs := opt_common_structs
        ;
            OldValue = opt_common_structs
        )
    else
        (
            OldValue = do_not_opt_common_structs
        ;
            OldValue = opt_common_structs,
            !OptTuple ^ ot_opt_common_structs := do_not_opt_common_structs
        )
    ).

:- pred update_opt_tuple_bool_prop_constraints(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_prop_constraints(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_prop_constraints,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_prop_constraints,
            !OptTuple ^ ot_prop_constraints := prop_constraints
        ;
            OldValue = prop_constraints
        )
    else
        (
            OldValue = do_not_prop_constraints
        ;
            OldValue = prop_constraints,
            !OptTuple ^ ot_prop_constraints := do_not_prop_constraints
        )
    ).

:- pred update_opt_tuple_bool_prop_local_constraints(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_prop_local_constraints(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_prop_local_constraints,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_prop_local_constraints,
            !OptTuple ^ ot_prop_local_constraints := prop_local_constraints
        ;
            OldValue = prop_local_constraints
        )
    else
        (
            OldValue = do_not_prop_local_constraints
        ;
            OldValue = prop_local_constraints,
            !OptTuple ^ ot_prop_local_constraints := do_not_prop_local_constraints
        )
    ).

:- pred update_opt_tuple_bool_opt_dup_calls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_dup_calls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_dup_calls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_dup_calls,
            !OptTuple ^ ot_opt_dup_calls := opt_dup_calls
        ;
            OldValue = opt_dup_calls
        )
    else
        (
            OldValue = do_not_opt_dup_calls
        ;
            OldValue = opt_dup_calls,
            !OptTuple ^ ot_opt_dup_calls := do_not_opt_dup_calls
        )
    ).

:- pred update_opt_tuple_bool_prop_constants(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_prop_constants(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_prop_constants,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_prop_constants,
            !OptTuple ^ ot_prop_constants := prop_constants
        ;
            OldValue = prop_constants
        )
    else
        (
            OldValue = do_not_prop_constants
        ;
            OldValue = prop_constants,
            !OptTuple ^ ot_prop_constants := do_not_prop_constants
        )
    ).

:- pred update_opt_tuple_bool_elim_excess_assigns(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_elim_excess_assigns(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_elim_excess_assigns,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_elim_excess_assigns,
            !OptTuple ^ ot_elim_excess_assigns := elim_excess_assigns
        ;
            OldValue = elim_excess_assigns
        )
    else
        (
            OldValue = do_not_elim_excess_assigns
        ;
            OldValue = elim_excess_assigns,
            !OptTuple ^ ot_elim_excess_assigns := do_not_elim_excess_assigns
        )
    ).

:- pred update_opt_tuple_bool_merge_code_after_switch(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_merge_code_after_switch(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_merge_code_after_switch,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_merge_code_after_switch,
            !OptTuple ^ ot_merge_code_after_switch := merge_code_after_switch
        ;
            OldValue = merge_code_after_switch
        )
    else
        (
            OldValue = do_not_merge_code_after_switch
        ;
            OldValue = merge_code_after_switch,
            !OptTuple ^ ot_merge_code_after_switch := do_not_merge_code_after_switch
        )
    ).

:- pred update_opt_tuple_bool_opt_format_calls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_format_calls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_format_calls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_format_calls,
            !OptTuple ^ ot_opt_format_calls := opt_format_calls
        ;
            OldValue = opt_format_calls
        )
    else
        (
            OldValue = do_not_opt_format_calls
        ;
            OldValue = opt_format_calls,
            !OptTuple ^ ot_opt_format_calls := do_not_opt_format_calls
        )
    ).

:- pred update_opt_tuple_bool_split_switch_arms(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_split_switch_arms(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_split_switch_arms,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_split_switch_arms,
            !OptTuple ^ ot_split_switch_arms := split_switch_arms
        ;
            OldValue = split_switch_arms
        )
    else
        (
            OldValue = do_not_split_switch_arms
        ;
            OldValue = split_switch_arms,
            !OptTuple ^ ot_split_switch_arms := do_not_split_switch_arms
        )
    ).

:- pred update_opt_tuple_bool_opt_loop_invariants(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_loop_invariants(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_loop_invariants,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_loop_invariants,
            !OptTuple ^ ot_opt_loop_invariants := opt_loop_invariants
        ;
            OldValue = opt_loop_invariants
        )
    else
        (
            OldValue = do_not_opt_loop_invariants
        ;
            OldValue = opt_loop_invariants,
            !OptTuple ^ ot_opt_loop_invariants := do_not_opt_loop_invariants
        )
    ).

:- pred update_opt_tuple_bool_opt_saved_vars_const(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_saved_vars_const(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_saved_vars_const,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_saved_vars_const,
            !OptTuple ^ ot_opt_saved_vars_const := opt_saved_vars_const
        ;
            OldValue = opt_saved_vars_const
        )
    else
        (
            OldValue = do_not_opt_saved_vars_const
        ;
            OldValue = opt_saved_vars_const,
            !OptTuple ^ ot_opt_saved_vars_const := do_not_opt_saved_vars_const
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell,
            !OptTuple ^ ot_opt_svcell := opt_svcell
        ;
            OldValue = opt_svcell
        )
    else
        (
            OldValue = do_not_opt_svcell
        ;
            OldValue = opt_svcell,
            !OptTuple ^ ot_opt_svcell := do_not_opt_svcell
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell_loop(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell_loop(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell_loop,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell_loop,
            !OptTuple ^ ot_opt_svcell_loop := opt_svcell_loop
        ;
            OldValue = opt_svcell_loop
        )
    else
        (
            OldValue = do_not_opt_svcell_loop
        ;
            OldValue = opt_svcell_loop,
            !OptTuple ^ ot_opt_svcell_loop := do_not_opt_svcell_loop
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell_full_path(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell_full_path(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell_full_path,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell_full_path,
            !OptTuple ^ ot_opt_svcell_full_path := opt_svcell_full_path
        ;
            OldValue = opt_svcell_full_path
        )
    else
        (
            OldValue = do_not_opt_svcell_full_path
        ;
            OldValue = opt_svcell_full_path,
            !OptTuple ^ ot_opt_svcell_full_path := do_not_opt_svcell_full_path
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell_on_stack(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell_on_stack(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell_on_stack,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell_on_stack,
            !OptTuple ^ ot_opt_svcell_on_stack := opt_svcell_on_stack
        ;
            OldValue = opt_svcell_on_stack
        )
    else
        (
            OldValue = do_not_opt_svcell_on_stack
        ;
            OldValue = opt_svcell_on_stack,
            !OptTuple ^ ot_opt_svcell_on_stack := do_not_opt_svcell_on_stack
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell_candidate_headvars(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell_candidate_headvars(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell_candidate_headvars,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell_candidate_headvars,
            !OptTuple ^ ot_opt_svcell_candidate_headvars := opt_svcell_candidate_headvars
        ;
            OldValue = opt_svcell_candidate_headvars
        )
    else
        (
            OldValue = do_not_opt_svcell_candidate_headvars
        ;
            OldValue = opt_svcell_candidate_headvars,
            !OptTuple ^ ot_opt_svcell_candidate_headvars := do_not_opt_svcell_candidate_headvars
        )
    ).

:- pred update_opt_tuple_bool_opt_svcell_all_candidates(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_svcell_all_candidates(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_svcell_all_candidates,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_svcell_all_candidates,
            !OptTuple ^ ot_opt_svcell_all_candidates := opt_svcell_all_candidates
        ;
            OldValue = opt_svcell_all_candidates
        )
    else
        (
            OldValue = do_not_opt_svcell_all_candidates
        ;
            OldValue = opt_svcell_all_candidates,
            !OptTuple ^ ot_opt_svcell_all_candidates := do_not_opt_svcell_all_candidates
        )
    ).

:- pred update_opt_tuple_bool_delay_constructs(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_delay_constructs(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_delay_constructs,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_delay_constructs,
            !OptTuple ^ ot_delay_constructs := delay_constructs
        ;
            OldValue = delay_constructs
        )
    else
        (
            OldValue = do_not_delay_constructs
        ;
            OldValue = delay_constructs,
            !OptTuple ^ ot_delay_constructs := do_not_delay_constructs
        )
    ).

:- pred update_opt_tuple_bool_opt_follow_code(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_follow_code(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_follow_code,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_follow_code,
            !OptTuple ^ ot_opt_follow_code := opt_follow_code
        ;
            OldValue = opt_follow_code
        )
    else
        (
            OldValue = do_not_opt_follow_code
        ;
            OldValue = opt_follow_code,
            !OptTuple ^ ot_opt_follow_code := do_not_opt_follow_code
        )
    ).

:- pred update_opt_tuple_bool_opt_unused_args(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_unused_args(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_unused_args,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_unused_args,
            !OptTuple ^ ot_opt_unused_args := opt_unused_args
        ;
            OldValue = opt_unused_args
        )
    else
        (
            OldValue = do_not_opt_unused_args
        ;
            OldValue = opt_unused_args,
            !OptTuple ^ ot_opt_unused_args := do_not_opt_unused_args
        )
    ).

:- pred update_opt_tuple_bool_opt_unused_args_intermod(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_unused_args_intermod(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_unused_args_intermod,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_unused_args_intermod,
            !OptTuple ^ ot_opt_unused_args_intermod := opt_unused_args_intermod
        ;
            OldValue = opt_unused_args_intermod
        )
    else
        (
            OldValue = do_not_opt_unused_args_intermod
        ;
            OldValue = opt_unused_args_intermod,
            !OptTuple ^ ot_opt_unused_args_intermod := do_not_opt_unused_args_intermod
        )
    ).

:- pred update_opt_tuple_bool_opt_higher_order(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_higher_order(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_higher_order,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_higher_order,
            !OptTuple ^ ot_opt_higher_order := opt_higher_order
        ;
            OldValue = opt_higher_order
        )
    else
        (
            OldValue = do_not_opt_higher_order
        ;
            OldValue = opt_higher_order,
            !OptTuple ^ ot_opt_higher_order := do_not_opt_higher_order
        )
    ).

:- pred update_opt_tuple_bool_opt_unneeded_code(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_unneeded_code(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_unneeded_code,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_unneeded_code,
            !OptTuple ^ ot_opt_unneeded_code := opt_unneeded_code
        ;
            OldValue = opt_unneeded_code
        )
    else
        (
            OldValue = do_not_opt_unneeded_code
        ;
            OldValue = opt_unneeded_code,
            !OptTuple ^ ot_opt_unneeded_code := do_not_opt_unneeded_code
        )
    ).

:- pred update_opt_tuple_bool_spec_types(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_spec_types(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_spec_types,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_spec_types,
            !OptTuple ^ ot_spec_types := spec_types
        ;
            OldValue = spec_types
        )
    else
        (
            OldValue = do_not_spec_types
        ;
            OldValue = spec_types,
            !OptTuple ^ ot_spec_types := do_not_spec_types
        )
    ).

:- pred update_opt_tuple_bool_spec_types_user_guided(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_spec_types_user_guided(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_spec_types_user_guided,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_spec_types_user_guided,
            !OptTuple ^ ot_spec_types_user_guided := spec_types_user_guided
        ;
            OldValue = spec_types_user_guided
        )
    else
        (
            OldValue = do_not_spec_types_user_guided
        ;
            OldValue = spec_types_user_guided,
            !OptTuple ^ ot_spec_types_user_guided := do_not_spec_types_user_guided
        )
    ).

:- pred update_opt_tuple_bool_introduce_accumulators(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_introduce_accumulators(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_introduce_accumulators,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_introduce_accumulators,
            !OptTuple ^ ot_introduce_accumulators := introduce_accumulators
        ;
            OldValue = introduce_accumulators
        )
    else
        (
            OldValue = do_not_introduce_accumulators
        ;
            OldValue = introduce_accumulators,
            !OptTuple ^ ot_introduce_accumulators := do_not_introduce_accumulators
        )
    ).

:- pred update_opt_tuple_bool_opt_lcmc_accumulator(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_lcmc_accumulator(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_lcmc_accumulator,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_lcmc_accumulator,
            !OptTuple ^ ot_opt_lcmc_accumulator := opt_lcmc_accumulator
        ;
            OldValue = opt_lcmc_accumulator
        )
    else
        (
            OldValue = do_not_opt_lcmc_accumulator
        ;
            OldValue = opt_lcmc_accumulator,
            !OptTuple ^ ot_opt_lcmc_accumulator := do_not_opt_lcmc_accumulator
        )
    ).

:- pred update_opt_tuple_bool_opt_lcmc_null(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_lcmc_null(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_lcmc_null,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_lcmc_null,
            !OptTuple ^ ot_opt_lcmc_null := opt_lcmc_null
        ;
            OldValue = opt_lcmc_null
        )
    else
        (
            OldValue = do_not_opt_lcmc_null
        ;
            OldValue = opt_lcmc_null,
            !OptTuple ^ ot_opt_lcmc_null := do_not_opt_lcmc_null
        )
    ).

:- pred update_opt_tuple_bool_opt_lcmc(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_lcmc(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_lcmc,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_lcmc,
            !OptTuple ^ ot_opt_lcmc := opt_lcmc
        ;
            OldValue = opt_lcmc
        )
    else
        (
            OldValue = do_not_opt_lcmc
        ;
            OldValue = opt_lcmc,
            !OptTuple ^ ot_opt_lcmc := do_not_opt_lcmc
        )
    ).

:- pred update_opt_tuple_bool_opt_dead_procs(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_dead_procs(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_dead_procs,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_dead_procs,
            !OptTuple ^ ot_opt_dead_procs := opt_dead_procs
        ;
            OldValue = opt_dead_procs
        )
    else
        (
            OldValue = do_not_opt_dead_procs
        ;
            OldValue = opt_dead_procs,
            !OptTuple ^ ot_opt_dead_procs := do_not_opt_dead_procs
        )
    ).

:- pred update_opt_tuple_bool_deforest(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_deforest(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_deforest,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_deforest,
            !OptTuple ^ ot_deforest := deforest
        ;
            OldValue = deforest
        )
    else
        (
            OldValue = do_not_deforest
        ;
            OldValue = deforest,
            !OptTuple ^ ot_deforest := do_not_deforest
        )
    ).

:- pred update_opt_tuple_bool_untuple(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_untuple(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_untuple,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_untuple,
            !OptTuple ^ ot_untuple := untuple
        ;
            OldValue = untuple
        )
    else
        (
            OldValue = do_not_untuple
        ;
            OldValue = untuple,
            !OptTuple ^ ot_untuple := do_not_untuple
        )
    ).

:- pred update_opt_tuple_bool_tuple(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_tuple(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_tuple,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_tuple,
            !OptTuple ^ ot_tuple := tuple
        ;
            OldValue = tuple
        )
    else
        (
            OldValue = do_not_tuple
        ;
            OldValue = tuple,
            !OptTuple ^ ot_tuple := do_not_tuple
        )
    ).

:- pred update_opt_tuple_bool_inline_par_builtins(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_par_builtins(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_par_builtins,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_par_builtins,
            !OptTuple ^ ot_inline_par_builtins := inline_par_builtins
        ;
            OldValue = inline_par_builtins
        )
    else
        (
            OldValue = do_not_inline_par_builtins
        ;
            OldValue = inline_par_builtins,
            !OptTuple ^ ot_inline_par_builtins := do_not_inline_par_builtins
        )
    ).

:- pred update_opt_tuple_bool_spec_in_all_dep_par_conjs(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_spec_in_all_dep_par_conjs(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_spec_in_all_dep_par_conjs,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_spec_in_all_dep_par_conjs,
            !OptTuple ^ ot_spec_in_all_dep_par_conjs := spec_in_all_dep_par_conjs
        ;
            OldValue = spec_in_all_dep_par_conjs
        )
    else
        (
            OldValue = do_not_spec_in_all_dep_par_conjs
        ;
            OldValue = spec_in_all_dep_par_conjs,
            !OptTuple ^ ot_spec_in_all_dep_par_conjs := do_not_spec_in_all_dep_par_conjs
        )
    ).

:- pred update_opt_tuple_bool_allow_some_paths_only_waits(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_allow_some_paths_only_waits(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_allow_some_paths_only_waits,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_allow_some_paths_only_waits,
            !OptTuple ^ ot_allow_some_paths_only_waits := allow_some_paths_only_waits
        ;
            OldValue = allow_some_paths_only_waits
        )
    else
        (
            OldValue = do_not_allow_some_paths_only_waits
        ;
            OldValue = allow_some_paths_only_waits,
            !OptTuple ^ ot_allow_some_paths_only_waits := do_not_allow_some_paths_only_waits
        )
    ).

:- pred update_opt_tuple_bool_analyse_regions(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_analyse_regions(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_analyse_regions,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_analyse_regions,
            !OptTuple ^ ot_analyse_regions := analyse_regions
        ;
            OldValue = analyse_regions
        )
    else
        (
            OldValue = do_not_analyse_regions
        ;
            OldValue = analyse_regions,
            !OptTuple ^ ot_analyse_regions := do_not_analyse_regions
        )
    ).

:- pred update_opt_tuple_bool_use_smart_indexing(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_smart_indexing(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_smart_indexing,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_smart_indexing,
            !OptTuple ^ ot_use_smart_indexing := use_smart_indexing
        ;
            OldValue = use_smart_indexing
        )
    else
        (
            OldValue = do_not_use_smart_indexing
        ;
            OldValue = use_smart_indexing,
            !OptTuple ^ ot_use_smart_indexing := do_not_use_smart_indexing
        )
    ).

:- pred update_opt_tuple_bool_use_smart_indexing_atomic(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_smart_indexing_atomic(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_smart_indexing_atomic,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_smart_indexing_atomic,
            !OptTuple ^ ot_use_smart_indexing_atomic := use_smart_indexing_atomic
        ;
            OldValue = use_smart_indexing_atomic
        )
    else
        (
            OldValue = do_not_use_smart_indexing_atomic
        ;
            OldValue = use_smart_indexing_atomic,
            !OptTuple ^ ot_use_smart_indexing_atomic := do_not_use_smart_indexing_atomic
        )
    ).

:- pred update_opt_tuple_bool_use_smart_indexing_string(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_smart_indexing_string(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_smart_indexing_string,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_smart_indexing_string,
            !OptTuple ^ ot_use_smart_indexing_string := use_smart_indexing_string
        ;
            OldValue = use_smart_indexing_string
        )
    else
        (
            OldValue = do_not_use_smart_indexing_string
        ;
            OldValue = use_smart_indexing_string,
            !OptTuple ^ ot_use_smart_indexing_string := do_not_use_smart_indexing_string
        )
    ).

:- pred update_opt_tuple_bool_use_smart_indexing_tag(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_smart_indexing_tag(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_smart_indexing_tag,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_smart_indexing_tag,
            !OptTuple ^ ot_use_smart_indexing_tag := use_smart_indexing_tag
        ;
            OldValue = use_smart_indexing_tag
        )
    else
        (
            OldValue = do_not_use_smart_indexing_tag
        ;
            OldValue = use_smart_indexing_tag,
            !OptTuple ^ ot_use_smart_indexing_tag := do_not_use_smart_indexing_tag
        )
    ).

:- pred update_opt_tuple_bool_use_smart_indexing_float(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_smart_indexing_float(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_smart_indexing_float,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_smart_indexing_float,
            !OptTuple ^ ot_use_smart_indexing_float := use_smart_indexing_float
        ;
            OldValue = use_smart_indexing_float
        )
    else
        (
            OldValue = do_not_use_smart_indexing_float
        ;
            OldValue = use_smart_indexing_float,
            !OptTuple ^ ot_use_smart_indexing_float := do_not_use_smart_indexing_float
        )
    ).

:- pred update_opt_tuple_bool_put_base_first_single_rec(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_put_base_first_single_rec(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_put_base_first_single_rec,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_put_base_first_single_rec,
            !OptTuple ^ ot_put_base_first_single_rec := put_base_first_single_rec
        ;
            OldValue = put_base_first_single_rec
        )
    else
        (
            OldValue = do_not_put_base_first_single_rec
        ;
            OldValue = put_base_first_single_rec,
            !OptTuple ^ ot_put_base_first_single_rec := do_not_put_base_first_single_rec
        )
    ).

:- pred update_opt_tuple_bool_put_base_first_multi_rec(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_put_base_first_multi_rec(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_put_base_first_multi_rec,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_put_base_first_multi_rec,
            !OptTuple ^ ot_put_base_first_multi_rec := put_base_first_multi_rec
        ;
            OldValue = put_base_first_multi_rec
        )
    else
        (
            OldValue = do_not_put_base_first_multi_rec
        ;
            OldValue = put_base_first_multi_rec,
            !OptTuple ^ ot_put_base_first_multi_rec := do_not_put_base_first_multi_rec
        )
    ).

:- pred update_opt_tuple_bool_use_static_ground_cells(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_static_ground_cells(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_static_ground_cells,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_static_ground_cells,
            !OptTuple ^ ot_use_static_ground_cells := use_static_ground_cells
        ;
            OldValue = use_static_ground_cells
        )
    else
        (
            OldValue = do_not_use_static_ground_cells
        ;
            OldValue = use_static_ground_cells,
            !OptTuple ^ ot_use_static_ground_cells := do_not_use_static_ground_cells
        )
    ).

:- pred update_opt_tuple_bool_use_static_ground_floats(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_static_ground_floats(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_static_ground_floats,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_static_ground_floats,
            !OptTuple ^ ot_use_static_ground_floats := use_static_ground_floats
        ;
            OldValue = use_static_ground_floats
        )
    else
        (
            OldValue = do_not_use_static_ground_floats
        ;
            OldValue = use_static_ground_floats,
            !OptTuple ^ ot_use_static_ground_floats := do_not_use_static_ground_floats
        )
    ).

:- pred update_opt_tuple_bool_use_static_ground_int64s(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_static_ground_int64s(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_static_ground_int64s,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_static_ground_int64s,
            !OptTuple ^ ot_use_static_ground_int64s := use_static_ground_int64s
        ;
            OldValue = use_static_ground_int64s
        )
    else
        (
            OldValue = do_not_use_static_ground_int64s
        ;
            OldValue = use_static_ground_int64s,
            !OptTuple ^ ot_use_static_ground_int64s := do_not_use_static_ground_int64s
        )
    ).

:- pred update_opt_tuple_bool_use_static_code_addresses(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_static_code_addresses(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_static_code_addresses,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_static_code_addresses,
            !OptTuple ^ ot_use_static_code_addresses := use_static_code_addresses
        ;
            OldValue = use_static_code_addresses
        )
    else
        (
            OldValue = do_not_use_static_code_addresses
        ;
            OldValue = use_static_code_addresses,
            !OptTuple ^ ot_use_static_code_addresses := do_not_use_static_code_addresses
        )
    ).

:- pred update_opt_tuple_bool_use_atomic_cells(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_atomic_cells(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_atomic_cells,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_atomic_cells,
            !OptTuple ^ ot_use_atomic_cells := use_atomic_cells
        ;
            OldValue = use_atomic_cells
        )
    else
        (
            OldValue = do_not_use_atomic_cells
        ;
            OldValue = use_atomic_cells,
            !OptTuple ^ ot_use_atomic_cells := do_not_use_atomic_cells
        )
    ).

:- pred update_opt_tuple_bool_opt_middle_rec_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_middle_rec_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_middle_rec_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_middle_rec_llds,
            !OptTuple ^ ot_opt_middle_rec_llds := opt_middle_rec_llds
        ;
            OldValue = opt_middle_rec_llds
        )
    else
        (
            OldValue = do_not_opt_middle_rec_llds
        ;
            OldValue = opt_middle_rec_llds,
            !OptTuple ^ ot_opt_middle_rec_llds := do_not_opt_middle_rec_llds
        )
    ).

:- pred update_opt_tuple_bool_opt_simple_neg_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_simple_neg_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_simple_neg_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_simple_neg_llds,
            !OptTuple ^ ot_opt_simple_neg_llds := opt_simple_neg_llds
        ;
            OldValue = opt_simple_neg_llds
        )
    else
        (
            OldValue = do_not_opt_simple_neg_llds
        ;
            OldValue = opt_simple_neg_llds,
            !OptTuple ^ ot_opt_simple_neg_llds := do_not_opt_simple_neg_llds
        )
    ).

:- pred update_opt_tuple_bool_allow_hijacks(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_allow_hijacks(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_allow_hijacks,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_allow_hijacks,
            !OptTuple ^ ot_allow_hijacks := allow_hijacks
        ;
            OldValue = allow_hijacks
        )
    else
        (
            OldValue = do_not_allow_hijacks
        ;
            OldValue = allow_hijacks,
            !OptTuple ^ ot_allow_hijacks := do_not_allow_hijacks
        )
    ).

:- pred update_opt_tuple_bool_opt_mlds_tailcalls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_mlds_tailcalls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_mlds_tailcalls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_mlds_tailcalls,
            !OptTuple ^ ot_opt_mlds_tailcalls := opt_mlds_tailcalls
        ;
            OldValue = opt_mlds_tailcalls
        )
    else
        (
            OldValue = do_not_opt_mlds_tailcalls
        ;
            OldValue = opt_mlds_tailcalls,
            !OptTuple ^ ot_opt_mlds_tailcalls := do_not_opt_mlds_tailcalls
        )
    ).

:- pred update_opt_tuple_bool_opt_mlds_inits(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_mlds_inits(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_mlds_inits,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_mlds_inits,
            !OptTuple ^ ot_opt_mlds_inits := opt_mlds_inits
        ;
            OldValue = opt_mlds_inits
        )
    else
        (
            OldValue = do_not_opt_mlds_inits
        ;
            OldValue = opt_mlds_inits,
            !OptTuple ^ ot_opt_mlds_inits := do_not_opt_mlds_inits
        )
    ).

:- pred update_opt_tuple_bool_elim_unused_mlds_assigns(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_elim_unused_mlds_assigns(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_elim_unused_mlds_assigns,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_elim_unused_mlds_assigns,
            !OptTuple ^ ot_elim_unused_mlds_assigns := elim_unused_mlds_assigns
        ;
            OldValue = elim_unused_mlds_assigns
        )
    else
        (
            OldValue = do_not_elim_unused_mlds_assigns
        ;
            OldValue = elim_unused_mlds_assigns,
            !OptTuple ^ ot_elim_unused_mlds_assigns := do_not_elim_unused_mlds_assigns
        )
    ).

:- pred update_opt_tuple_bool_elim_local_vars_mlds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_elim_local_vars_mlds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_elim_local_vars_mlds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_elim_local_vars_mlds,
            !OptTuple ^ ot_elim_local_vars_mlds := elim_local_vars_mlds
        ;
            OldValue = elim_local_vars_mlds
        )
    else
        (
            OldValue = do_not_elim_local_vars_mlds
        ;
            OldValue = elim_local_vars_mlds,
            !OptTuple ^ ot_elim_local_vars_mlds := do_not_elim_local_vars_mlds
        )
    ).

:- pred update_opt_tuple_bool_gen_trail_ops_inline_mlds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_gen_trail_ops_inline_mlds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_gen_trail_ops_inline_mlds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_gen_trail_ops_inline_mlds,
            !OptTuple ^ ot_gen_trail_ops_inline_mlds := gen_trail_ops_inline_mlds
        ;
            OldValue = gen_trail_ops_inline_mlds
        )
    else
        (
            OldValue = do_not_gen_trail_ops_inline_mlds
        ;
            OldValue = gen_trail_ops_inline_mlds,
            !OptTuple ^ ot_gen_trail_ops_inline_mlds := do_not_gen_trail_ops_inline_mlds
        )
    ).

:- pred update_opt_tuple_bool_use_llds_common_data(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_llds_common_data(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_llds_common_data,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_llds_common_data,
            !OptTuple ^ ot_use_llds_common_data := use_llds_common_data
        ;
            OldValue = use_llds_common_data
        )
    else
        (
            OldValue = do_not_use_llds_common_data
        ;
            OldValue = use_llds_common_data,
            !OptTuple ^ ot_use_llds_common_data := do_not_use_llds_common_data
        )
    ).

:- pred update_opt_tuple_bool_use_llds_common_layout_data(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_llds_common_layout_data(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_llds_common_layout_data,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_llds_common_layout_data,
            !OptTuple ^ ot_use_llds_common_layout_data := use_llds_common_layout_data
        ;
            OldValue = use_llds_common_layout_data
        )
    else
        (
            OldValue = do_not_use_llds_common_layout_data
        ;
            OldValue = use_llds_common_layout_data,
            !OptTuple ^ ot_use_llds_common_layout_data := do_not_use_llds_common_layout_data
        )
    ).

:- pred update_opt_tuple_bool_optimize_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_optimize_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_optimize_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_optimize_llds,
            !OptTuple ^ ot_optimize_llds := optimize_llds
        ;
            OldValue = optimize_llds
        )
    else
        (
            OldValue = do_not_optimize_llds
        ;
            OldValue = optimize_llds,
            !OptTuple ^ ot_optimize_llds := do_not_optimize_llds
        )
    ).

:- pred update_opt_tuple_bool_optimize_mlds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_optimize_mlds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_optimize_mlds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_optimize_mlds,
            !OptTuple ^ ot_optimize_mlds := optimize_mlds
        ;
            OldValue = optimize_mlds
        )
    else
        (
            OldValue = do_not_optimize_mlds
        ;
            OldValue = optimize_mlds,
            !OptTuple ^ ot_optimize_mlds := do_not_optimize_mlds
        )
    ).

:- pred update_opt_tuple_bool_peep_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_peep_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_peep_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_peep_llds,
            !OptTuple ^ ot_peep_llds := peep_llds
        ;
            OldValue = peep_llds
        )
    else
        (
            OldValue = do_not_peep_llds
        ;
            OldValue = peep_llds,
            !OptTuple ^ ot_peep_llds := do_not_peep_llds
        )
    ).

:- pred update_opt_tuple_bool_peep_llds_mkword(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_peep_llds_mkword(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_peep_llds_mkword,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_peep_llds_mkword,
            !OptTuple ^ ot_peep_llds_mkword := peep_llds_mkword
        ;
            OldValue = peep_llds_mkword
        )
    else
        (
            OldValue = do_not_peep_llds_mkword
        ;
            OldValue = peep_llds_mkword,
            !OptTuple ^ ot_peep_llds_mkword := do_not_peep_llds_mkword
        )
    ).

:- pred update_opt_tuple_bool_peep_mlds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_peep_mlds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_peep_mlds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_peep_mlds,
            !OptTuple ^ ot_peep_mlds := peep_mlds
        ;
            OldValue = peep_mlds
        )
    else
        (
            OldValue = do_not_peep_mlds
        ;
            OldValue = peep_mlds,
            !OptTuple ^ ot_peep_mlds := do_not_peep_mlds
        )
    ).

:- pred update_opt_tuple_bool_opt_jumps(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_jumps(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_jumps,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_jumps,
            !OptTuple ^ ot_opt_jumps := opt_jumps
        ;
            OldValue = opt_jumps
        )
    else
        (
            OldValue = do_not_opt_jumps
        ;
            OldValue = opt_jumps,
            !OptTuple ^ ot_opt_jumps := do_not_opt_jumps
        )
    ).

:- pred update_opt_tuple_bool_opt_fulljumps(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_fulljumps(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_fulljumps,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_fulljumps,
            !OptTuple ^ ot_opt_fulljumps := opt_fulljumps
        ;
            OldValue = opt_fulljumps
        )
    else
        (
            OldValue = do_not_opt_fulljumps
        ;
            OldValue = opt_fulljumps,
            !OptTuple ^ ot_opt_fulljumps := do_not_opt_fulljumps
        )
    ).

:- pred update_opt_tuple_bool_pessimize_llds_tailcalls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_pessimize_llds_tailcalls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_pessimize_llds_tailcalls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_pessimize_llds_tailcalls,
            !OptTuple ^ ot_pessimize_llds_tailcalls := pessimize_llds_tailcalls
        ;
            OldValue = pessimize_llds_tailcalls
        )
    else
        (
            OldValue = do_not_pessimize_llds_tailcalls
        ;
            OldValue = pessimize_llds_tailcalls,
            !OptTuple ^ ot_pessimize_llds_tailcalls := do_not_pessimize_llds_tailcalls
        )
    ).

:- pred update_opt_tuple_bool_opt_checked_nondet_tailcalls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_checked_nondet_tailcalls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_checked_nondet_tailcalls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_checked_nondet_tailcalls,
            !OptTuple ^ ot_opt_checked_nondet_tailcalls := opt_checked_nondet_tailcalls
        ;
            OldValue = opt_checked_nondet_tailcalls
        )
    else
        (
            OldValue = do_not_opt_checked_nondet_tailcalls
        ;
            OldValue = opt_checked_nondet_tailcalls,
            !OptTuple ^ ot_opt_checked_nondet_tailcalls := do_not_opt_checked_nondet_tailcalls
        )
    ).

:- pred update_opt_tuple_bool_use_local_vars_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_local_vars_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_local_vars_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_local_vars_llds,
            !OptTuple ^ ot_use_local_vars_llds := use_local_vars_llds
        ;
            OldValue = use_local_vars_llds
        )
    else
        (
            OldValue = do_not_use_local_vars_llds
        ;
            OldValue = use_local_vars_llds,
            !OptTuple ^ ot_use_local_vars_llds := do_not_use_local_vars_llds
        )
    ).

:- pred update_opt_tuple_bool_standardize_labels(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_standardize_labels(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_standardize_labels,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_standardize_labels,
            !OptTuple ^ ot_standardize_labels := standardize_labels
        ;
            OldValue = standardize_labels
        )
    else
        (
            OldValue = do_not_standardize_labels
        ;
            OldValue = standardize_labels,
            !OptTuple ^ ot_standardize_labels := do_not_standardize_labels
        )
    ).

:- pred update_opt_tuple_bool_opt_labels(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_labels(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_labels,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_labels,
            !OptTuple ^ ot_opt_labels := opt_labels
        ;
            OldValue = opt_labels
        )
    else
        (
            OldValue = do_not_opt_labels
        ;
            OldValue = opt_labels,
            !OptTuple ^ ot_opt_labels := do_not_opt_labels
        )
    ).

:- pred update_opt_tuple_bool_opt_dup_instrs_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_dup_instrs_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_dup_instrs_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_dup_instrs_llds,
            !OptTuple ^ ot_opt_dup_instrs_llds := opt_dup_instrs_llds
        ;
            OldValue = opt_dup_instrs_llds
        )
    else
        (
            OldValue = do_not_opt_dup_instrs_llds
        ;
            OldValue = opt_dup_instrs_llds,
            !OptTuple ^ ot_opt_dup_instrs_llds := do_not_opt_dup_instrs_llds
        )
    ).

:- pred update_opt_tuple_bool_opt_dup_procs_llds(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_dup_procs_llds(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_dup_procs_llds,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_dup_procs_llds,
            !OptTuple ^ ot_opt_dup_procs_llds := opt_dup_procs_llds
        ;
            OldValue = opt_dup_procs_llds
        )
    else
        (
            OldValue = do_not_opt_dup_procs_llds
        ;
            OldValue = opt_dup_procs_llds,
            !OptTuple ^ ot_opt_dup_procs_llds := do_not_opt_dup_procs_llds
        )
    ).

:- pred update_opt_tuple_bool_opt_frames(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_frames(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_frames,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_frames,
            !OptTuple ^ ot_opt_frames := opt_frames
        ;
            OldValue = opt_frames
        )
    else
        (
            OldValue = do_not_opt_frames
        ;
            OldValue = opt_frames,
            !OptTuple ^ ot_opt_frames := do_not_opt_frames
        )
    ).

:- pred update_opt_tuple_bool_opt_delay_slot(option_table::in, bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_delay_slot(OptionTable, Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_delay_slot,
    ( if
        getopt.lookup_bool_option(OptionTable, have_delay_slot, yes),
        Bool = yes
    then
        (
            OldValue = do_not_opt_delay_slot,
            !OptTuple ^ ot_opt_delay_slot := opt_delay_slot
        ;
            OldValue = opt_delay_slot
        )
    else
        (
            OldValue = do_not_opt_delay_slot
        ;
            OldValue = opt_delay_slot,
            !OptTuple ^ ot_opt_delay_slot := do_not_opt_delay_slot
        )
    ).

:- pred update_opt_tuple_bool_opt_llds_reassign(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_llds_reassign(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_llds_reassign,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_llds_reassign,
            !OptTuple ^ ot_opt_llds_reassign := opt_llds_reassign
        ;
            OldValue = opt_llds_reassign
        )
    else
        (
            OldValue = do_not_opt_llds_reassign
        ;
            OldValue = opt_llds_reassign,
            !OptTuple ^ ot_opt_llds_reassign := do_not_opt_llds_reassign
        )
    ).

:- pred update_opt_tuple_bool_use_macro_for_redo_fail(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_macro_for_redo_fail(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_macro_for_redo_fail,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_macro_for_redo_fail,
            !OptTuple ^ ot_use_macro_for_redo_fail := use_macro_for_redo_fail
        ;
            OldValue = use_macro_for_redo_fail
        )
    else
        (
            OldValue = do_not_use_macro_for_redo_fail
        ;
            OldValue = use_macro_for_redo_fail,
            !OptTuple ^ ot_use_macro_for_redo_fail := do_not_use_macro_for_redo_fail
        )
    ).

:- pred update_opt_tuple_bool_emit_c_loops(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_emit_c_loops(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_emit_c_loops,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_emit_c_loops,
            !OptTuple ^ ot_emit_c_loops := emit_c_loops
        ;
            OldValue = emit_c_loops
        )
    else
        (
            OldValue = do_not_emit_c_loops
        ;
            OldValue = emit_c_loops,
            !OptTuple ^ ot_emit_c_loops := do_not_emit_c_loops
        )
    ).

:- pred update_opt_tuple_bool_use_just_one_c_func(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_just_one_c_func(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_just_one_c_func,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_just_one_c_func,
            !OptTuple ^ ot_use_just_one_c_func := use_just_one_c_func
        ;
            OldValue = use_just_one_c_func
        )
    else
        (
            OldValue = do_not_use_just_one_c_func
        ;
            OldValue = use_just_one_c_func,
            !OptTuple ^ ot_use_just_one_c_func := do_not_use_just_one_c_func
        )
    ).

:- pred update_opt_tuple_bool_use_local_thread_engine_base(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_local_thread_engine_base(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_local_thread_engine_base,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_local_thread_engine_base,
            !OptTuple ^ ot_use_local_thread_engine_base := use_local_thread_engine_base
        ;
            OldValue = use_local_thread_engine_base
        )
    else
        (
            OldValue = do_not_use_local_thread_engine_base
        ;
            OldValue = use_local_thread_engine_base,
            !OptTuple ^ ot_use_local_thread_engine_base := do_not_use_local_thread_engine_base
        )
    ).

:- pred update_opt_tuple_bool_inline_alloc(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_alloc(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_alloc,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_alloc,
            !OptTuple ^ ot_inline_alloc := inline_alloc
        ;
            OldValue = inline_alloc
        )
    else
        (
            OldValue = do_not_inline_alloc
        ;
            OldValue = inline_alloc,
            !OptTuple ^ ot_inline_alloc := do_not_inline_alloc
        )
    ).

:- pred update_opt_tuple_bool_opt_c(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_c(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_c,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_c,
            !OptTuple ^ ot_opt_c := opt_c
        ;
            OldValue = opt_c
        )
    else
        (
            OldValue = do_not_opt_c
        ;
            OldValue = opt_c,
            !OptTuple ^ ot_opt_c := do_not_opt_c
        )
    ).

:- pred update_opt_tuple_int_inline_call_cost(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_inline_call_cost(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_inline_call_cost := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_inline_call_cost,
        !OptTuple ^ ot_inline_call_cost := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_inline_compound_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_inline_compound_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_inline_compound_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_inline_compound_threshold,
        !OptTuple ^ ot_inline_compound_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_inline_simple_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_inline_simple_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_inline_simple_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_inline_simple_threshold,
        !OptTuple ^ ot_inline_simple_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_inline_vars_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_inline_vars_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_inline_vars_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_inline_vars_threshold,
        !OptTuple ^ ot_inline_vars_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_intermod_inline_simple_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_intermod_inline_simple_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_intermod_inline_simple_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_intermod_inline_simple_threshold,
        !OptTuple ^ ot_intermod_inline_simple_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_from_ground_term_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_from_ground_term_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_from_ground_term_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_from_ground_term_threshold,
        !OptTuple ^ ot_from_ground_term_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_cv_store_cost(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_cv_store_cost(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_cv_store_cost := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_cv_store_cost,
        !OptTuple ^ ot_opt_svcell_cv_store_cost := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_cv_load_cost(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_cv_load_cost(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_cv_load_cost := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_cv_load_cost,
        !OptTuple ^ ot_opt_svcell_cv_load_cost := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_fv_store_cost(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_fv_store_cost(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_fv_store_cost := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_fv_store_cost,
        !OptTuple ^ ot_opt_svcell_fv_store_cost := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_fv_load_cost(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_fv_load_cost(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_fv_load_cost := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_fv_load_cost,
        !OptTuple ^ ot_opt_svcell_fv_load_cost := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_op_ratio(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_op_ratio(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_op_ratio := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_op_ratio,
        !OptTuple ^ ot_opt_svcell_op_ratio := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_node_ratio(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_node_ratio(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_node_ratio := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_node_ratio,
        !OptTuple ^ ot_opt_svcell_node_ratio := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_svcell_all_path_node_ratio(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_svcell_all_path_node_ratio(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_svcell_all_path_node_ratio := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_svcell_all_path_node_ratio,
        !OptTuple ^ ot_opt_svcell_all_path_node_ratio := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_higher_order_size_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_higher_order_size_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_higher_order_size_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_higher_order_size_limit,
        !OptTuple ^ ot_higher_order_size_limit := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_higher_order_arg_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_higher_order_arg_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_higher_order_arg_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_higher_order_arg_limit,
        !OptTuple ^ ot_higher_order_arg_limit := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_unneeded_code_copy_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_unneeded_code_copy_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_unneeded_code_copy_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_unneeded_code_copy_limit,
        !OptTuple ^ ot_opt_unneeded_code_copy_limit := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_deforestation_depth_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_deforestation_depth_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_deforestation_depth_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_deforestation_depth_limit,
        !OptTuple ^ ot_deforestation_depth_limit := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_deforestation_cost_factor(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_deforestation_cost_factor(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_deforestation_cost_factor := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_deforestation_cost_factor,
        !OptTuple ^ ot_deforestation_cost_factor := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_deforestation_vars_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_deforestation_vars_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_deforestation_vars_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_deforestation_vars_threshold,
        !OptTuple ^ ot_deforestation_vars_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_deforestation_size_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_deforestation_size_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_deforestation_size_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_deforestation_size_threshold,
        !OptTuple ^ ot_deforestation_size_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_tuple_costs_ratio(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_tuple_costs_ratio(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_tuple_costs_ratio := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_tuple_costs_ratio,
        !OptTuple ^ ot_tuple_costs_ratio := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_tuple_min_args(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_tuple_min_args(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_tuple_min_args := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_tuple_min_args,
        !OptTuple ^ ot_tuple_min_args := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_dense_switch_req_density(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_dense_switch_req_density(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_dense_switch_req_density := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_dense_switch_req_density,
        !OptTuple ^ ot_dense_switch_req_density := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_lookup_switch_req_density(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_lookup_switch_req_density(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_lookup_switch_req_density := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_lookup_switch_req_density,
        !OptTuple ^ ot_lookup_switch_req_density := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_dense_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_dense_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_dense_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_dense_switch_size,
        !OptTuple ^ ot_dense_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_lookup_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_lookup_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_lookup_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_lookup_switch_size,
        !OptTuple ^ ot_lookup_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_string_trie_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_string_trie_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_string_trie_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_string_trie_switch_size,
        !OptTuple ^ ot_string_trie_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_string_hash_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_string_hash_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_string_hash_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_string_hash_switch_size,
        !OptTuple ^ ot_string_hash_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_string_binary_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_string_binary_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_string_binary_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_string_binary_switch_size,
        !OptTuple ^ ot_string_binary_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_tag_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_tag_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_tag_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_tag_switch_size,
        !OptTuple ^ ot_tag_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_try_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_try_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_try_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_try_switch_size,
        !OptTuple ^ ot_try_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_binary_switch_size(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_binary_switch_size(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_binary_switch_size := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_binary_switch_size,
        !OptTuple ^ ot_binary_switch_size := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_llds_local_var_access_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_llds_local_var_access_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_llds_local_var_access_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_llds_local_var_access_threshold,
        !OptTuple ^ ot_llds_local_var_access_threshold := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_opt_repeat(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_opt_repeat(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_opt_repeat := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_opt_repeat,
        !OptTuple ^ ot_opt_repeat := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_llds_layout_compression_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_llds_layout_compression_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_llds_layout_compression_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_llds_layout_compression_limit,
        !OptTuple ^ ot_llds_layout_compression_limit := int.max(OldN, N)
    ).

:- pred update_opt_tuple_int_procs_per_c_function(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_procs_per_c_function(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_procs_per_c_function := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_procs_per_c_function,
        !OptTuple ^ ot_procs_per_c_function := int.max(OldN, N)
    ).

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%

:- pred get_default_opt_level(option_table::in, int::out) is det.

get_default_opt_level(OptionTable, DefaultOptLevel) :-
    % default_opt_level takes a "-O<n>" string for compatibility.
    lookup_string_option(OptionTable, default_opt_level, Str0),
    Str = string.strip(Str0),
    ( if
        string.remove_prefix("-O", Str, Suffix),
        string.to_int(string.lstrip(Suffix), Int)
    then
        DefaultOptLevel = Int
    else
        DefaultOptLevel = 2
    ).

:- pred set_opts_upto_level(option_table::in, int::in, int::in,
    opt_tuple::in, opt_tuple::out,
    maybe_seen_opt_level::in, maybe_seen_opt_level::out) is det.

set_opts_upto_level(OptionTable, Cur, Max,
        !OptTuple, !MaybeSeenOptLevel) :-
    ( if
        Cur =< Max,
        opts_enabled_at_level(Cur, _Desc, LevelOptExpOptions)
    then
        UndocFunc = (func(doc_oo(O, _, _)) = O),
        LevelOptOptions = list.map(UndocFunc, LevelOptExpOptions),
        list.foldl2(update_opt_tuple(from_opt_level, OptionTable),
            LevelOptOptions, !OptTuple, !MaybeSeenOptLevel),
        set_opts_upto_level(OptionTable, Cur + 1, Max,
            !OptTuple, !MaybeSeenOptLevel)
    else
        true
    ).

:- pred set_opts_for_space(opt_tuple::in, opt_tuple::out) is det.

set_opts_for_space(!OptTuple) :-
    UnneededCopyLimit = !.OptTuple ^ ot_opt_unneeded_code_copy_limit,
    !OptTuple ^ ot_opt_unneeded_code_copy_limit :=
        int.min(UnneededCopyLimit, 1),
    !OptTuple ^ ot_opt_dead_procs := opt_dead_procs,
    !OptTuple ^ ot_opt_labels := opt_labels,
    !OptTuple ^ ot_opt_dup_instrs_llds := opt_dup_instrs_llds,
    !OptTuple ^ ot_opt_dup_procs_llds := opt_dup_procs_llds,
    !OptTuple ^ ot_opt_fulljumps := opt_fulljumps,
    !OptTuple ^ ot_opt_llds_reassign := opt_llds_reassign,
    !OptTuple ^ ot_inline_alloc := inline_alloc,
    !OptTuple ^ ot_use_macro_for_redo_fail := use_macro_for_redo_fail,
    !OptTuple ^ ot_opt_loop_invariants := do_not_opt_loop_invariants.

opts_enabled_at_level(0, [
    "Aim to minimize overall compilation time."
], [
    doc_oo(oo_use_llds_common_data(yes),
                        optopt_use_llds_common_data,            bool(yes)),
    doc_oo(oo_optimize_llds(yes),       optopt_optimize_llds,   bool(yes)),
    doc_oo(oo_optimize_mlds(yes),       optopt_optimize_mlds,   bool(yes)),
    doc_oo(oo_opt_repeat(1),            optopt_repeat_opts,     int(1)),
    doc_oo(oo_peep_llds(yes),           optopt_peep_llds,       bool(yes)),
    doc_oo(oo_peep_llds_mkword(yes),    optopt_peep_llds_mkword, bool(yes)),
    doc_oo(oo_peep_mlds(yes),           optopt_peep_mlds,       bool(yes)),
    doc_oo(oo_use_static_ground_cells(yes),
                        optopt_use_static_ground_cells,         bool(yes)),
    doc_oo(oo_use_smart_indexing(yes),  optopt_use_smart_indexing,  bool(yes)),
    doc_oo(oo_use_smart_indexing_atomic(yes),
                        optopt_use_smart_indexing_atomic,       bool(yes)),
    doc_oo(oo_use_smart_indexing_string(yes),
                        optopt_use_smart_indexing_string,       bool(yes)),
    doc_oo(oo_use_smart_indexing_tag(yes),
                        optopt_use_smart_indexing_tag,          bool(yes)),
    doc_oo(oo_use_smart_indexing_float(yes),
                        optopt_use_smart_indexing_float,        bool(yes)),
    doc_oo(oo_opt_jumps(yes),           optopt_opt_jumps,       bool(yes)),
    doc_oo(oo_opt_labels(yes),          optopt_opt_labels,      bool(yes)),
    doc_oo(oo_opt_dead_procs(yes),      optopt_opt_dead_procs,      bool(yes)),
    doc_oo(oo_elim_excess_assigns(yes), optopt_elim_excess_assigns, bool(yes))
]).
opts_enabled_at_level(1, [
    "Apply optimizations which are cheap and have a good payoff",
    "while still keeping compilation time small."
], [
    doc_oo(oo_use_local_vars_llds(yes), optopt_use_local_vars_llds, bool(yes)),
    % XXX We want `gcc -O1'
    doc_oo(oo_opt_c(yes),               optopt_c_optimize,      bool(yes)),
    doc_oo(oo_opt_frames(yes),          optopt_opt_frames,      bool(yes)),
    % We ignore oo_opt_delay_slot if have_delay_slot = no.
    doc_oo(oo_opt_delay_slot(yes),      optopt_opt_delay_slot,  bool(yes)),
    doc_oo(oo_opt_middle_rec_llds(yes), optopt_opt_middle_rec_llds, bool(yes)),
    doc_oo(oo_emit_c_loops(yes),        optopt_emit_c_loops,    bool(yes)),
    doc_oo(oo_opt_mlds_tailcalls(yes),  optopt_opt_mlds_tailcalls, bool(yes))
]).
opts_enabled_at_level(2, [
    "Apply optimizations which have a good payoff relative to their cost;",
    "but include optimizations which are more costly than with -O1."
], [
    doc_oo(oo_opt_fulljumps(yes),       optopt_opt_fulljumps,   bool(yes)),
    doc_oo(oo_opt_repeat(3),            optopt_repeat_opts,     int(3)),
    doc_oo(oo_opt_dup_instrs_llds(yes), optopt_opt_dup_instrs_llds, bool(yes)),
    doc_oo(oo_opt_follow_code(yes),     optopt_opt_follow_code, bool(yes)),
    doc_oo(oo_prop_constants(yes),      optopt_prop_constants,  bool(yes)),
    doc_oo(oo_inline_simple(yes),       optopt_inline_simple,   bool(yes)),
    doc_oo(oo_inline_single_use(yes),   optopt_inline_single_use, bool(yes)),
    doc_oo(oo_inline_compound_threshold(10),
                        optopt_inline_compound_threshold,       int(10)),
    doc_oo(oo_opt_common_structs(yes),  optopt_opt_common_structs,  bool(yes)),
    doc_oo(oo_spec_types_user_guided(yes),
                        optopt_spec_types_user_guided,          bool(yes)),
    doc_oo(oo_opt_simple_neg_llds(yes), optopt_opt_simple_neg_llds, bool(yes)),
    doc_oo(oo_merge_code_after_switch(yes),
                        optopt_merge_code_after_switch,         bool(yes)),
    doc_oo(oo_opt_mlds_inits(yes),      optopt_opt_mlds_inits,  bool(yes)),
    doc_oo(oo_split_switch_arms(yes),   optopt_split_switch_arms,   bool(yes))
]).
opts_enabled_at_level(3, [
    "Apply optimizations which usually have a good payoff even if they",
    "increase compilation time quite a bit."
], [
    doc_oo(oo_opt_saved_vars_const(yes),
                                optopt_opt_saved_vars_const,    bool(yes)),
    doc_oo(oo_opt_unused_args(yes),     optopt_opt_unused_args,     bool(yes)),
    doc_oo(oo_opt_higher_order(yes),    optopt_opt_higher_order,    bool(yes)),
    doc_oo(oo_deforest(yes),            optopt_deforest,        bool(yes)),
    doc_oo(oo_prop_constraints(yes),    optopt_prop_constraints,    bool(yes)),
    doc_oo(oo_prop_local_constraints(yes),
                                optopt_prop_local_constraints,  bool(yes)),
    doc_oo(oo_opt_llds_reassign(yes),   optopt_opt_llds_reassign,   bool(yes)),
    doc_oo(oo_opt_repeat(4),            optopt_repeat_opts,     int(4))
]).
opts_enabled_at_level(4, [
    "Apply optimizations which may have some payoff even if they",
    "increase compilation time quite a bit.",
    "",
    "Currently this enables the use of local variables",
    "and increases the inlining thresholds."
], [
    doc_oo(oo_inline_simple_threshold(8),
                            optopt_inline_simple_threshold,     int(8)),
    doc_oo(oo_inline_compound_threshold(20),
                            optopt_inline_compound_threshold,   int(20)),
    doc_oo(oo_higher_order_size_limit(30),
                            optopt_higher_order_size_limit,     int(30))
]).
opts_enabled_at_level(5, [
    "Apply optimizations which may have some payoff even if they",
    "increase compilation time a lot.",
    "",
    "Currently this enables the search for construction unifications that",
    "can be delayed past failing computations, allows more passes of the",
    "low-level optimizations, and increases the inlining thresholds",
    "still further. We also enable eliminate_local_vars only at",
    "this level, because that pass is implemented pretty inefficiently."
], [
    doc_oo(oo_opt_repeat(5),            optopt_repeat_opts,     int(5)),
    doc_oo(oo_delay_constructs(yes),    optopt_delay_constructs, bool(yes)),
    doc_oo(oo_inline_compound_threshold(100),
                            optopt_inline_compound_threshold,   int(100)),
    doc_oo(oo_higher_order_size_limit(40),
                            optopt_higher_order_size_limit,     int(40)),
    doc_oo(oo_elim_local_vars_mlds(yes),
                            optopt_elim_local_vars_mlds,        bool(yes)),
    doc_oo(oo_opt_loop_invariants(yes), optopt_opt_loop_invariants, bool(yes))
]).
opts_enabled_at_level(6, [
    "Apply optimizations which may have any payoff even if they",
    "increase compilation time to completely unreasonable levels.",
    "",
    "Currently this just enables inlining of GC_malloc(), redo(), and fail()."
], [
    doc_oo(oo_inline_alloc(yes),        optopt_inline_alloc,    bool(yes)),
    doc_oo(oo_use_macro_for_redo_fail(yes),
                            optopt_use_macro_for_redo_fail,     bool(yes))
]).

% Many optimization options are not enabled at any level.
% We stopped keeping track of them a long time ago.
% While we did keep track, we listed the reasons for not automatically
% enabling the following optimizations.
%
%   checked_nondet_tailcalls:
%       This is deliberate, because the transformation might make
%       code run slower.
%
%   unneeded_code:
%       Because it can cause slowdowns at high optimization levels;
%       cause unknown.
%
%   introduce_accumulators:
%       Disabled until a bug in extras/trailed_update/var.m is resolved.
%
%   optimize_constructor_last_call:
%       Not a speedup in general.

%---------------------------------------------------------------------------%
:- end_module libs.optimization_options.
%---------------------------------------------------------------------------%
