diff --git a/cranelift/codegen/meta-python/build.py b/cranelift/codegen/meta-python/build.py index 7f890a4bb1..90a0cf254d 100644 --- a/cranelift/codegen/meta-python/build.py +++ b/cranelift/codegen/meta-python/build.py @@ -5,7 +5,6 @@ from __future__ import absolute_import import argparse import isa -import gen_settings import gen_build_deps import gen_encoding import gen_binemit @@ -43,7 +42,6 @@ def main(): isas = isa.all_isas() number_all_instructions(isas) - gen_settings.generate(isas, out_dir) gen_encoding.generate(isas, out_dir) gen_binemit.generate(isas, out_dir) gen_build_deps.generate() diff --git a/cranelift/codegen/meta-python/gen_settings.py b/cranelift/codegen/meta-python/gen_settings.py deleted file mode 100644 index cb9d3615e3..0000000000 --- a/cranelift/codegen/meta-python/gen_settings.py +++ /dev/null @@ -1,335 +0,0 @@ -""" -Generate sources with settings. -""" -from __future__ import absolute_import -import srcgen -from unique_table import UniqueSeqTable -import constant_hash -from cdsl import camel_case -from cdsl.settings import BoolSetting, NumSetting, EnumSetting -from base import settings - -try: - from typing import Sequence, Set, Tuple, List, Union, TYPE_CHECKING # noqa - if TYPE_CHECKING: - from cdsl.isa import TargetISA # noqa - from cdsl.settings import Setting, Preset, SettingGroup # noqa - from cdsl.predicates import Predicate, PredContext # noqa -except ImportError: - pass - - -def gen_to_and_from_str(ty, values, fmt): - # type: (str, Tuple[str, ...], srcgen.Formatter) -> None - """ - Emit Display and FromStr implementations for enum settings. - """ - with fmt.indented('impl fmt::Display for {} {{'.format(ty), '}'): - with fmt.indented( - 'fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {', - '}'): - with fmt.indented('f.write_str(match *self {', '})'): - for v in values: - fmt.line('{}::{} => "{}",' - .format(ty, camel_case(v), v)) - - with fmt.indented('impl str::FromStr for {} {{'.format(ty), '}'): - fmt.line('type Err = ();') - with fmt.indented( - 'fn from_str(s: &str) -> Result {', - '}'): - with fmt.indented('match s {', '}'): - for v in values: - fmt.line('"{}" => Ok({}::{}),' - .format(v, ty, camel_case(v))) - fmt.line('_ => Err(()),') - - -def gen_enum_types(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Emit enum types for any enum settings. - """ - for setting in sgrp.settings: - if not isinstance(setting, EnumSetting): - continue - ty = camel_case(setting.name) - fmt.doc_comment('Values for `{}`.'.format(setting)) - fmt.line('#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]') - with fmt.indented('pub enum {} {{'.format(ty), '}'): - for v in setting.values: - fmt.doc_comment('`{}`.'.format(v)) - fmt.line(camel_case(v) + ',') - - gen_to_and_from_str(ty, setting.values, fmt) - - -def gen_getter(setting, sgrp, fmt): - # type: (Setting, SettingGroup, srcgen.Formatter) -> None - """ - Emit a getter function for `setting`. - """ - fmt.doc_comment(setting.__doc__) - - if isinstance(setting, BoolSetting): - proto = 'pub fn {}(&self) -> bool'.format(setting.name) - with fmt.indented(proto + ' {', '}'): - fmt.line( - 'self.numbered_predicate({})' - .format(sgrp.predicate_number[setting])) - elif isinstance(setting, NumSetting): - proto = 'pub fn {}(&self) -> u8'.format(setting.name) - with fmt.indented(proto + ' {', '}'): - fmt.line('self.bytes[{}]'.format(setting.byte_offset)) - elif isinstance(setting, EnumSetting): - ty = camel_case(setting.name) - proto = 'pub fn {}(&self) -> {}'.format(setting.name, ty) - with fmt.indented(proto + ' {', '}'): - m = srcgen.Match('self.bytes[{}]'.format(setting.byte_offset)) - for i, v in enumerate(setting.values): - m.arm(str(i), [], '{}::{}'.format(ty, camel_case(v))) - m.arm('_', [], 'panic!("Invalid enum value")') - fmt.match(m) - else: - raise AssertionError("Unknown setting kind") - - -def gen_pred_getter(name, pred, sgrp, fmt): - # type: (str, Predicate, SettingGroup, srcgen.Formatter) -> None - """ - Emit a getter for a named pre-computed predicate. - """ - fmt.doc_comment('Computed predicate `{}`.'.format(pred.rust_predicate(0))) - proto = 'pub fn {}(&self) -> bool'.format(name) - with fmt.indented(proto + ' {', '}'): - fmt.line( - 'self.numbered_predicate({})' - .format(sgrp.predicate_number[pred])) - - -def gen_getters(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Emit getter functions for all the settings in fmt. - """ - fmt.doc_comment("User-defined settings.") - fmt.line('#[allow(dead_code)]') - with fmt.indented('impl Flags {', '}'): - fmt.doc_comment('Get a view of the boolean predicates.') - with fmt.indented( - 'pub fn predicate_view(&self) -> ' - 'crate::settings::PredicateView {', '}'): - fmt.format( - 'crate::settings::PredicateView::new(&self.bytes[{}..])', - sgrp.boolean_offset) - if sgrp.settings: - fmt.doc_comment('Dynamic numbered predicate getter.') - with fmt.indented( - 'fn numbered_predicate(&self, p: usize) -> bool {', '}'): - fmt.line( - 'self.bytes[{} + p / 8] & (1 << (p % 8)) != 0' - .format(sgrp.boolean_offset)) - for setting in sgrp.settings: - gen_getter(setting, sgrp, fmt) - for name, pred in sgrp.named_predicates.items(): - gen_pred_getter(name, pred, sgrp, fmt) - - -def gen_descriptors(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Generate the DESCRIPTORS, ENUMERATORS, and PRESETS tables. - """ - - enums = UniqueSeqTable() - - with fmt.indented( - 'static DESCRIPTORS: [detail::Descriptor; {}] = [' - .format(len(sgrp.settings) + len(sgrp.presets)), - '];'): - for idx, setting in enumerate(sgrp.settings): - setting.descriptor_index = idx - with fmt.indented('detail::Descriptor {', '},'): - fmt.line('name: "{}",'.format(setting.name)) - fmt.line('offset: {},'.format(setting.byte_offset)) - if isinstance(setting, BoolSetting): - fmt.line( - 'detail: detail::Detail::Bool {{ bit: {} }},' - .format(setting.bit_offset)) - elif isinstance(setting, NumSetting): - fmt.line('detail: detail::Detail::Num,') - elif isinstance(setting, EnumSetting): - offs = enums.add(setting.values) - fmt.line( - 'detail: detail::Detail::Enum ' + - '{{ last: {}, enumerators: {} }},' - .format(len(setting.values)-1, offs)) - else: - raise AssertionError("Unknown setting kind") - - for idx, preset in enumerate(sgrp.presets): - preset.descriptor_index = len(sgrp.settings) + idx - with fmt.indented('detail::Descriptor {', '},'): - fmt.line('name: "{}",'.format(preset.name)) - fmt.line('offset: {},'.format(idx * sgrp.settings_size)) - fmt.line('detail: detail::Detail::Preset,') - - with fmt.indented( - 'static ENUMERATORS: [&str; {}] = [' - .format(len(enums.table)), - '];'): - for txt in enums.table: - fmt.line('"{}",'.format(txt)) - - def hash_setting(s): - # type: (Union[Setting, Preset]) -> int - return constant_hash.simple_hash(s.name) - - hash_elems = [] # type: List[Union[Setting, Preset]] - hash_elems.extend(sgrp.settings) - hash_elems.extend(sgrp.presets) - hash_table = constant_hash.compute_quadratic(hash_elems, hash_setting) - with fmt.indented( - 'static HASH_TABLE: [u16; {}] = [' - .format(len(hash_table)), - '];'): - for h in hash_table: - if h is None: - fmt.line('0xffff,') - else: - fmt.line('{},'.format(h.descriptor_index)) - - with fmt.indented( - 'static PRESETS: [(u8, u8); {}] = [' - .format(len(sgrp.presets) * sgrp.settings_size), - '];'): - for preset in sgrp.presets: - fmt.comment(preset.name) - for mask, value in preset.layout(): - fmt.format('(0b{:08b}, 0b{:08b}),', mask, value) - - -def gen_template(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Emit a Template constant. - """ - v = [0] * sgrp.settings_size - for setting in sgrp.settings: - v[setting.byte_offset] |= setting.default_byte() - - with fmt.indented( - 'static TEMPLATE: detail::Template = detail::Template {', '};'): - fmt.line('name: "{}",'.format(sgrp.name)) - fmt.line('descriptors: &DESCRIPTORS,') - fmt.line('enumerators: &ENUMERATORS,') - fmt.line('hash_table: &HASH_TABLE,') - vs = ', '.join('{:#04x}'.format(x) for x in v) - fmt.line('defaults: &[{}],'.format(vs)) - fmt.line('presets: &PRESETS,') - - fmt.doc_comment( - 'Create a `settings::Builder` for the {} settings group.' - .format(sgrp.name)) - with fmt.indented('pub fn builder() -> Builder {', '}'): - fmt.line('Builder::new(&TEMPLATE)') - - -def gen_display(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Generate the Display impl for Flags. - """ - with fmt.indented('impl fmt::Display for Flags {', '}'): - with fmt.indented( - 'fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {', - '}'): - fmt.line('writeln!(f, "[{}]")?;'.format(sgrp.name)) - with fmt.indented('for d in &DESCRIPTORS {', '}'): - with fmt.indented('if !d.detail.is_preset() {', '}'): - fmt.line('write!(f, "{} = ", d.name)?;') - fmt.line( - 'TEMPLATE.format_toml_value(d.detail, ' + - 'self.bytes[d.offset as usize], f)?;') - fmt.line('writeln!(f)?;') - fmt.line('Ok(())') - - -def gen_constructor(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Generate a Flags constructor. - """ - - with fmt.indented('impl Flags {', '}'): - args = 'builder: Builder' - if sgrp.parent: - p = sgrp.parent - args = '{}: &{}::Flags, {}'.format(p.name, p.qual_mod, args) - fmt.doc_comment('Create flags {} settings group.'.format(sgrp.name)) - fmt.line('#[allow(unused_variables)]') - with fmt.indented( - 'pub fn new({}) -> Self {{'.format(args), '}'): - fmt.line('let bvec = builder.state_for("{}");'.format(sgrp.name)) - fmt.line( - 'let mut {} = Self {{ bytes: [0; {}] }};' - .format(sgrp.name, sgrp.byte_size())) - fmt.line( - 'debug_assert_eq!(bvec.len(), {});' - .format(sgrp.settings_size)) - fmt.line( - '{}.bytes[0..{}].copy_from_slice(&bvec);' - .format(sgrp.name, sgrp.settings_size)) - - # Now compute the predicates. - for pred, number in sgrp.predicate_number.items(): - # Don't compute our own settings. - if number < sgrp.boolean_settings: - continue - fmt.comment('Precompute #{}.'.format(number)) - with fmt.indented( - 'if {} {{'.format(pred.rust_predicate(0)), - '}'): - fmt.line( - '{}.bytes[{}] |= 1 << {};' - .format( - sgrp.name, - sgrp.boolean_offset + number // 8, - number % 8)) - - fmt.line(sgrp.name) - - -def gen_group(sgrp, fmt): - # type: (SettingGroup, srcgen.Formatter) -> None - """ - Generate a Flags struct representing `sgrp`. - """ - fmt.line('#[derive(Clone)]') - fmt.doc_comment('Flags group `{}`.'.format(sgrp.name)) - with fmt.indented('pub struct Flags {', '}'): - fmt.line('bytes: [u8; {}],'.format(sgrp.byte_size())) - - gen_constructor(sgrp, fmt) - gen_enum_types(sgrp, fmt) - gen_getters(sgrp, fmt) - gen_descriptors(sgrp, fmt) - gen_template(sgrp, fmt) - gen_display(sgrp, fmt) - - -def generate(isas, out_dir): - # type: (Sequence[TargetISA], str) -> None - # Generate shared settings. - fmt = srcgen.Formatter() - settings.group.qual_mod = 'settings' - gen_group(settings.group, fmt) - fmt.update_file('settings.rs', out_dir) - - # Generate ISA-specific settings. - for isa in isas: - isa.settings.qual_mod = 'isa::{}::settings'.format( - isa.settings.name) - fmt = srcgen.Formatter() - gen_group(isa.settings, fmt) - fmt.update_file('settings-{}.rs'.format(isa.name), out_dir) diff --git a/cranelift/codegen/meta/src/lib.rs b/cranelift/codegen/meta/src/lib.rs index 2dff027076..9ac2a54306 100644 --- a/cranelift/codegen/meta/src/lib.rs +++ b/cranelift/codegen/meta/src/lib.rs @@ -27,7 +27,7 @@ pub fn generate(isas: &Vec, out_dir: &str) -> Result<(), error::Error> gen_settings::generate( &shared_defs.settings, gen_settings::ParentGroup::None, - "new_settings.rs", + "settings.rs", &out_dir, )?; gen_types::generate("types.rs", &out_dir)?; @@ -59,7 +59,7 @@ pub fn generate(isas: &Vec, out_dir: &str) -> Result<(), error::Error> gen_settings::generate( &isa.settings, gen_settings::ParentGroup::Shared, - &format!("new_settings-{}.rs", isa.name), + &format!("settings-{}.rs", isa.name), &out_dir, )?; } diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 404bf58cd5..6da73076e4 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -379,6 +379,8 @@ mod tests { f.to_string(), "[shared]\n\ opt_level = \"default\"\n\ + baldrdash_prologue_words = 0\n\ + probestack_size_log2 = 12\n\ enable_verifier = true\n\ is_pic = false\n\ colocated_libcalls = false\n\ @@ -387,11 +389,9 @@ mod tests { enable_nan_canonicalization = false\n\ enable_simd = true\n\ enable_atomics = true\n\ - baldrdash_prologue_words = 0\n\ allones_funcaddrs = false\n\ probestack_enabled = true\n\ probestack_func_adjusts_sp = false\n\ - probestack_size_log2 = 12\n\ jump_tables_enabled = true\n" ); assert_eq!(f.opt_level(), super::OptLevel::Default);