%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2020 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 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_inline_linear_tail_rec_sccs
    --->    inline_linear_tail_rec_sccs
    ;       do_not_inline_linear_tail_rec_sccs.
:- 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
    --->    opt_middle_rec
    ;       do_not_opt_middle_rec.
:- type maybe_opt_simple_neg
    --->    opt_simple_neg
    ;       do_not_opt_simple_neg.
:- 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_initializations
    --->    opt_initializations
    ;       do_not_opt_initializations.
:- type maybe_elim_unused_mlds_assigns
    --->    elim_unused_mlds_assigns
    ;       do_not_elim_unused_mlds_assigns.
:- type maybe_elim_local_vars
    --->    elim_local_vars
    ;       do_not_elim_local_vars.
:- type maybe_gen_trail_ops_inline
    --->    gen_trail_ops_inline
    ;       do_not_gen_trail_ops_inline.
:- type maybe_use_common_data
    --->    use_common_data
    ;       do_not_use_common_data.
:- type maybe_use_common_layout_data
    --->    use_common_layout_data
    ;       do_not_use_common_layout_data.
:- type maybe_optimize
    --->    optimize
    ;       do_not_optimize.
:- type maybe_opt_peep
    --->    opt_peep
    ;       do_not_opt_peep.
:- type maybe_opt_peep_mkword
    --->    opt_peep_mkword
    ;       do_not_opt_peep_mkword.
:- type maybe_opt_jumps
    --->    opt_jumps
    ;       do_not_opt_jumps.
:- type maybe_opt_fulljumps
    --->    opt_fulljumps
    ;       do_not_opt_fulljumps.
:- type maybe_pessimize_tailcalls
    --->    pessimize_tailcalls
    ;       do_not_pessimize_tailcalls.
:- type maybe_opt_checked_nondet_tailcalls
    --->    opt_checked_nondet_tailcalls
    ;       do_not_opt_checked_nondet_tailcalls.
:- type maybe_use_local_vars
    --->    use_local_vars
    ;       do_not_use_local_vars.
:- type maybe_standardize_labels
    --->    standardize_labels
    ;       do_not_standardize_labels.
:- type maybe_opt_labels
    --->    opt_labels
    ;       do_not_opt_labels.
:- type maybe_opt_dups
    --->    opt_dups
    ;       do_not_opt_dups.
:- type maybe_opt_proc_dups
    --->    opt_proc_dups
    ;       do_not_opt_proc_dups.
:- 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_reassign
    --->    opt_reassign
    ;       do_not_opt_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_inline_linear_tail_rec_sccs(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(bool)
    ;       oo_opt_simple_neg(bool)
    ;       oo_allow_hijacks(bool)
    ;       oo_opt_mlds_tailcalls(bool)
    ;       oo_opt_initializations(bool)
    ;       oo_elim_unused_mlds_assigns(bool)
    ;       oo_elim_local_vars(bool)
    ;       oo_gen_trail_ops_inline(bool)
    ;       oo_use_common_data(bool)
    ;       oo_use_common_layout_data(bool)
    ;       oo_optimize(bool)
    ;       oo_opt_peep(bool)
    ;       oo_opt_peep_mkword(bool)
    ;       oo_opt_jumps(bool)
    ;       oo_opt_fulljumps(bool)
    ;       oo_pessimize_tailcalls(bool)
    ;       oo_opt_checked_nondet_tailcalls(bool)
    ;       oo_use_local_vars(bool)
    ;       oo_standardize_labels(bool)
    ;       oo_opt_labels(bool)
    ;       oo_opt_dups(bool)
    ;       oo_opt_proc_dups(bool)
    ;       oo_opt_frames(bool)
    ;       oo_opt_delay_slot(bool)
    ;       oo_opt_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_inline_linear_tail_rec_sccs_max_extra(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_local_var_access_threshold(int)
    ;       oo_opt_repeat(int)
    ;       oo_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_inline_linear_tail_rec_sccs :: maybe_inline_linear_tail_rec_sccs,
                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             :: maybe_opt_middle_rec,
                ot_opt_simple_neg             :: maybe_opt_simple_neg,
                ot_allow_hijacks              :: maybe_allow_hijacks,
                ot_opt_mlds_tailcalls         :: maybe_opt_mlds_tailcalls,
                ot_opt_initializations        :: maybe_opt_initializations,
                ot_elim_unused_mlds_assigns   :: maybe_elim_unused_mlds_assigns,
                ot_elim_local_vars            :: maybe_elim_local_vars,
                ot_gen_trail_ops_inline       :: maybe_gen_trail_ops_inline,
                ot_use_common_data            :: maybe_use_common_data,
                ot_use_common_layout_data     :: maybe_use_common_layout_data,
                ot_optimize                   :: maybe_optimize,
                ot_opt_peep                   :: maybe_opt_peep,
                ot_opt_peep_mkword            :: maybe_opt_peep_mkword,
                ot_opt_jumps                  :: maybe_opt_jumps,
                ot_opt_fulljumps              :: maybe_opt_fulljumps,
                ot_pessimize_tailcalls        :: maybe_pessimize_tailcalls,
                ot_opt_checked_nondet_tailcalls :: maybe_opt_checked_nondet_tailcalls,
                ot_use_local_vars             :: maybe_use_local_vars,
                ot_standardize_labels         :: maybe_standardize_labels,
                ot_opt_labels                 :: maybe_opt_labels,
                ot_opt_dups                   :: maybe_opt_dups,
                ot_opt_proc_dups              :: maybe_opt_proc_dups,
                ot_opt_frames                 :: maybe_opt_frames,
                ot_opt_delay_slot             :: maybe_opt_delay_slot,
                ot_opt_reassign               :: maybe_opt_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_inline_linear_tail_rec_sccs_max_extra :: 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_local_var_access_threshold :: int,
                ot_opt_repeat                 :: int,
                ot_layout_compression_limit   :: int,
                ot_procs_per_c_function       :: int,
                ot_tuple_trace_counts_file    :: string
            ).

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

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

:- implementation.

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

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

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,
        do_not_inline_linear_tail_rec_sccs,
        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,
        use_smart_indexing_atomic,
        use_smart_indexing_string,
        use_smart_indexing_tag,
        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,
        do_not_opt_simple_neg,
        allow_hijacks,
        do_not_opt_mlds_tailcalls,
        do_not_opt_initializations,
        elim_unused_mlds_assigns,
        do_not_elim_local_vars,
        gen_trail_ops_inline,
        do_not_use_common_data,
        use_common_layout_data,
        do_not_optimize,
        do_not_opt_peep,
        do_not_opt_peep_mkword,
        do_not_opt_jumps,
        do_not_opt_fulljumps,
        do_not_pessimize_tailcalls,
        do_not_opt_checked_nondet_tailcalls,
        do_not_use_local_vars,
        do_not_standardize_labels,
        do_not_opt_labels,
        do_not_opt_dups,
        do_not_opt_proc_dups,
        do_not_opt_frames,
        do_not_opt_delay_slot,
        do_not_opt_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,
        0,
        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_inline_linear_tail_rec_sccs(Bool),
        update_opt_tuple_bool_inline_linear_tail_rec_sccs(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(Bool),
        update_opt_tuple_bool_opt_middle_rec(Bool, !OptTuple)
    ;
        OptOption = oo_opt_simple_neg(Bool),
        update_opt_tuple_bool_opt_simple_neg(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_initializations(Bool),
        update_opt_tuple_bool_opt_initializations(Bool, !OptTuple)
    ;
        OptOption = oo_elim_unused_mlds_assigns(Bool),
        update_opt_tuple_bool_elim_unused_mlds_assigns(Bool, !OptTuple)
    ;
        OptOption = oo_elim_local_vars(Bool),
        update_opt_tuple_bool_elim_local_vars(Bool, !OptTuple)
    ;
        OptOption = oo_gen_trail_ops_inline(Bool),
        update_opt_tuple_bool_gen_trail_ops_inline(Bool, !OptTuple)
    ;
        OptOption = oo_use_common_data(Bool),
        update_opt_tuple_bool_use_common_data(Bool, !OptTuple)
    ;
        OptOption = oo_use_common_layout_data(Bool),
        update_opt_tuple_bool_use_common_layout_data(Bool, !OptTuple)
    ;
        OptOption = oo_optimize(Bool),
        update_opt_tuple_bool_optimize(Bool, !OptTuple)
    ;
        OptOption = oo_opt_peep(Bool),
        update_opt_tuple_bool_opt_peep(Bool, !OptTuple)
    ;
        OptOption = oo_opt_peep_mkword(Bool),
        update_opt_tuple_bool_opt_peep_mkword(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_tailcalls(Bool),
        update_opt_tuple_bool_pessimize_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(Bool),
        update_opt_tuple_bool_use_local_vars(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_dups(Bool),
        update_opt_tuple_bool_opt_dups(Bool, !OptTuple)
    ;
        OptOption = oo_opt_proc_dups(Bool),
        update_opt_tuple_bool_opt_proc_dups(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_reassign(Bool),
        update_opt_tuple_bool_opt_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_inline_linear_tail_rec_sccs_max_extra(N),
        update_opt_tuple_int_inline_linear_tail_rec_sccs_max_extra(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_local_var_access_threshold(N),
        update_opt_tuple_int_local_var_access_threshold(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_opt_repeat(N),
        update_opt_tuple_int_opt_repeat(FromOptLevel, N, !OptTuple)
    ;
        OptOption = oo_layout_compression_limit(N),
        update_opt_tuple_int_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_inline_linear_tail_rec_sccs(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_inline_linear_tail_rec_sccs(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_inline_linear_tail_rec_sccs,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_inline_linear_tail_rec_sccs,
            !OptTuple ^ ot_inline_linear_tail_rec_sccs := inline_linear_tail_rec_sccs
        ;
            OldValue = inline_linear_tail_rec_sccs
        )
    else
        (
            OldValue = do_not_inline_linear_tail_rec_sccs
        ;
            OldValue = inline_linear_tail_rec_sccs,
            !OptTuple ^ ot_inline_linear_tail_rec_sccs := do_not_inline_linear_tail_rec_sccs
        )
    ).

:- 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(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_middle_rec(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_middle_rec,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_middle_rec,
            !OptTuple ^ ot_opt_middle_rec := opt_middle_rec
        ;
            OldValue = opt_middle_rec
        )
    else
        (
            OldValue = do_not_opt_middle_rec
        ;
            OldValue = opt_middle_rec,
            !OptTuple ^ ot_opt_middle_rec := do_not_opt_middle_rec
        )
    ).

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

update_opt_tuple_bool_opt_simple_neg(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_simple_neg,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_simple_neg,
            !OptTuple ^ ot_opt_simple_neg := opt_simple_neg
        ;
            OldValue = opt_simple_neg
        )
    else
        (
            OldValue = do_not_opt_simple_neg
        ;
            OldValue = opt_simple_neg,
            !OptTuple ^ ot_opt_simple_neg := do_not_opt_simple_neg
        )
    ).

:- 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_initializations(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_initializations(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_initializations,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_initializations,
            !OptTuple ^ ot_opt_initializations := opt_initializations
        ;
            OldValue = opt_initializations
        )
    else
        (
            OldValue = do_not_opt_initializations
        ;
            OldValue = opt_initializations,
            !OptTuple ^ ot_opt_initializations := do_not_opt_initializations
        )
    ).

:- 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(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_elim_local_vars(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_elim_local_vars,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_elim_local_vars,
            !OptTuple ^ ot_elim_local_vars := elim_local_vars
        ;
            OldValue = elim_local_vars
        )
    else
        (
            OldValue = do_not_elim_local_vars
        ;
            OldValue = elim_local_vars,
            !OptTuple ^ ot_elim_local_vars := do_not_elim_local_vars
        )
    ).

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

update_opt_tuple_bool_gen_trail_ops_inline(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_gen_trail_ops_inline,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_gen_trail_ops_inline,
            !OptTuple ^ ot_gen_trail_ops_inline := gen_trail_ops_inline
        ;
            OldValue = gen_trail_ops_inline
        )
    else
        (
            OldValue = do_not_gen_trail_ops_inline
        ;
            OldValue = gen_trail_ops_inline,
            !OptTuple ^ ot_gen_trail_ops_inline := do_not_gen_trail_ops_inline
        )
    ).

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

update_opt_tuple_bool_use_common_data(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_common_data,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_common_data,
            !OptTuple ^ ot_use_common_data := use_common_data
        ;
            OldValue = use_common_data
        )
    else
        (
            OldValue = do_not_use_common_data
        ;
            OldValue = use_common_data,
            !OptTuple ^ ot_use_common_data := do_not_use_common_data
        )
    ).

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

update_opt_tuple_bool_use_common_layout_data(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_common_layout_data,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_common_layout_data,
            !OptTuple ^ ot_use_common_layout_data := use_common_layout_data
        ;
            OldValue = use_common_layout_data
        )
    else
        (
            OldValue = do_not_use_common_layout_data
        ;
            OldValue = use_common_layout_data,
            !OptTuple ^ ot_use_common_layout_data := do_not_use_common_layout_data
        )
    ).

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

update_opt_tuple_bool_optimize(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_optimize,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_optimize,
            !OptTuple ^ ot_optimize := optimize
        ;
            OldValue = optimize
        )
    else
        (
            OldValue = do_not_optimize
        ;
            OldValue = optimize,
            !OptTuple ^ ot_optimize := do_not_optimize
        )
    ).

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

update_opt_tuple_bool_opt_peep(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_peep,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_peep,
            !OptTuple ^ ot_opt_peep := opt_peep
        ;
            OldValue = opt_peep
        )
    else
        (
            OldValue = do_not_opt_peep
        ;
            OldValue = opt_peep,
            !OptTuple ^ ot_opt_peep := do_not_opt_peep
        )
    ).

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

update_opt_tuple_bool_opt_peep_mkword(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_peep_mkword,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_peep_mkword,
            !OptTuple ^ ot_opt_peep_mkword := opt_peep_mkword
        ;
            OldValue = opt_peep_mkword
        )
    else
        (
            OldValue = do_not_opt_peep_mkword
        ;
            OldValue = opt_peep_mkword,
            !OptTuple ^ ot_opt_peep_mkword := do_not_opt_peep_mkword
        )
    ).

:- 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_tailcalls(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_pessimize_tailcalls(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_pessimize_tailcalls,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_pessimize_tailcalls,
            !OptTuple ^ ot_pessimize_tailcalls := pessimize_tailcalls
        ;
            OldValue = pessimize_tailcalls
        )
    else
        (
            OldValue = do_not_pessimize_tailcalls
        ;
            OldValue = pessimize_tailcalls,
            !OptTuple ^ ot_pessimize_tailcalls := do_not_pessimize_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(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_use_local_vars(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_use_local_vars,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_use_local_vars,
            !OptTuple ^ ot_use_local_vars := use_local_vars
        ;
            OldValue = use_local_vars
        )
    else
        (
            OldValue = do_not_use_local_vars
        ;
            OldValue = use_local_vars,
            !OptTuple ^ ot_use_local_vars := do_not_use_local_vars
        )
    ).

:- 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_dups(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_dups(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_dups,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_dups,
            !OptTuple ^ ot_opt_dups := opt_dups
        ;
            OldValue = opt_dups
        )
    else
        (
            OldValue = do_not_opt_dups
        ;
            OldValue = opt_dups,
            !OptTuple ^ ot_opt_dups := do_not_opt_dups
        )
    ).

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

update_opt_tuple_bool_opt_proc_dups(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_proc_dups,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_proc_dups,
            !OptTuple ^ ot_opt_proc_dups := opt_proc_dups
        ;
            OldValue = opt_proc_dups
        )
    else
        (
            OldValue = do_not_opt_proc_dups
        ;
            OldValue = opt_proc_dups,
            !OptTuple ^ ot_opt_proc_dups := do_not_opt_proc_dups
        )
    ).

:- 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_reassign(bool::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_bool_opt_reassign(Bool, !OptTuple) :-
    OldValue = !.OptTuple ^ ot_opt_reassign,
    ( if
        Bool = yes
    then
        (
            OldValue = do_not_opt_reassign,
            !OptTuple ^ ot_opt_reassign := opt_reassign
        ;
            OldValue = opt_reassign
        )
    else
        (
            OldValue = do_not_opt_reassign
        ;
            OldValue = opt_reassign,
            !OptTuple ^ ot_opt_reassign := do_not_opt_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_inline_linear_tail_rec_sccs_max_extra(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_inline_linear_tail_rec_sccs_max_extra(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_inline_linear_tail_rec_sccs_max_extra := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_inline_linear_tail_rec_sccs_max_extra,
        !OptTuple ^ ot_inline_linear_tail_rec_sccs_max_extra := 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_local_var_access_threshold(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_local_var_access_threshold(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_local_var_access_threshold := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_local_var_access_threshold,
        !OptTuple ^ ot_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_layout_compression_limit(
    maybe_from_opt_level::in, int::in,
    opt_tuple::in, opt_tuple::out) is det.

update_opt_tuple_int_layout_compression_limit(FromOptLevel, N, !OptTuple) :-
    (
        FromOptLevel = not_from_opt_level,
        !OptTuple ^ ot_layout_compression_limit := N
    ;
        FromOptLevel = from_opt_level,
        OldN = !.OptTuple ^ ot_layout_compression_limit,
        !OptTuple ^ ot_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, LevelOptOptions)
    then
        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_dups := opt_dups,
    !OptTuple ^ ot_opt_proc_dups := opt_proc_dups,
    !OptTuple ^ ot_opt_fulljumps := opt_fulljumps,
    !OptTuple ^ ot_opt_reassign := opt_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.

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

opts_enabled_at_level(0, [
    % Optimization level 0: aim to minimize overall compilation time.
    oo_use_common_data(yes),
    oo_optimize(yes),
    oo_opt_repeat(1),
    oo_opt_peep(yes),
    oo_opt_peep_mkword(yes),
    oo_use_static_ground_cells(yes),
    oo_use_smart_indexing(yes),
    oo_opt_jumps(yes),
    oo_opt_labels(yes),
    oo_opt_dead_procs(yes),
    oo_elim_excess_assigns(yes)
]).
opts_enabled_at_level(1, [
    % Optimization level 1: apply optimizations which are cheap and
    % have a good payoff while still keeping compilation time small.
    oo_use_local_vars(yes),
    oo_opt_c(yes),              % XXX We want `gcc -O1'
    oo_opt_frames(yes),
    % We ignore oo_opt_delay_slot if have_delay_slot = no.
    oo_opt_delay_slot(yes),
    oo_opt_middle_rec(yes),
    oo_emit_c_loops(yes),
    oo_opt_mlds_tailcalls(yes)
]).
opts_enabled_at_level(2, [
    % Optimization level 2: apply optimizations which have a good payoff
    % relative to their cost; but include optimizations which are
    % more costly than with -O1.
    oo_opt_fulljumps(yes),
    oo_opt_repeat(3),
    oo_opt_dups(yes),
    oo_opt_follow_code(yes),
    oo_prop_constants(yes),
    oo_inline_simple(yes),
    oo_inline_single_use(yes),
    oo_inline_compound_threshold(10),
    oo_opt_common_structs(yes),
    oo_spec_types_user_guided(yes),
    oo_opt_simple_neg(yes),
    oo_merge_code_after_switch(yes),
    oo_opt_initializations(yes),
    oo_split_switch_arms(yes)
]).
opts_enabled_at_level(3, [
    % Optimization level 3: apply optimizations which usually have a good
    % payoff even if they increase compilation time quite a bit.
    oo_opt_saved_vars_const(yes),
    oo_opt_unused_args(yes),
    oo_opt_higher_order(yes),
    oo_deforest(yes),
    oo_prop_constraints(yes),
    oo_prop_local_constraints(yes),
    oo_opt_reassign(yes),
    oo_opt_repeat(4)
]).
opts_enabled_at_level(4, [
    % Optimization 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.
    oo_inline_simple_threshold(8),
    oo_inline_compound_threshold(20),
    oo_higher_order_size_limit(30)
]).
opts_enabled_at_level(5, [
    % Optimization 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.
    oo_opt_repeat(5),
    oo_delay_constructs(yes),
    oo_inline_compound_threshold(100),
    oo_higher_order_size_limit(40),
    oo_elim_local_vars(yes),
    oo_opt_loop_invariants(yes)
]).
opts_enabled_at_level(6, [
     % Optimization level 6: apply optimizations which may have any payoff
    % even if they increase compilation time to completely unreasonable
    % levels.
    %
    % Currently this sets `use_just_one_c_func', which causes the compiler
    % to put everything in the one C function and treat calls to predicates
    % in the same module as local. We also enable inlining of GC_malloc(),
    % redo(), and fail().
    oo_use_just_one_c_func(yes),
    oo_inline_alloc(yes),
    oo_use_macro_for_redo_fail(yes)
]).

% The following optimization options are not enabled at any level:
% XXX This comment is old. Since then, we have added many optimizations
% that are not enabled automatically at any level :-(
%
%   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
%
%   type_specialization:
%       XXX why not?
%
%   introduce_accumulators:
%       XXX 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.
%---------------------------------------------------------------------------%
