[meta] Remove name lookups in formats;
This does a lot at once, since there was no clear way to split the three commits: - Instruction need to be passed an explicit InstructionFormat, - InstructionFormat deduplication is checked once all entities have been defined;
This commit is contained in:
@@ -8,20 +8,25 @@ pub mod legalize;
|
||||
pub mod settings;
|
||||
pub mod types;
|
||||
|
||||
use crate::cdsl::formats::FormatRegistry;
|
||||
use crate::cdsl::formats::{FormatStructure, InstructionFormat};
|
||||
use crate::cdsl::instructions::{AllInstructions, InstructionGroup};
|
||||
use crate::cdsl::settings::SettingGroup;
|
||||
use crate::cdsl::xform::TransformGroups;
|
||||
|
||||
use crate::shared::entities::EntityRefs;
|
||||
use crate::shared::formats::Formats;
|
||||
use crate::shared::immediates::Immediates;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub(crate) struct Definitions {
|
||||
pub settings: SettingGroup,
|
||||
pub all_instructions: AllInstructions,
|
||||
pub instructions: InstructionGroup,
|
||||
pub imm: Immediates,
|
||||
pub format_registry: FormatRegistry,
|
||||
pub formats: Formats,
|
||||
pub transform_groups: TransformGroups,
|
||||
}
|
||||
|
||||
@@ -30,13 +35,9 @@ pub(crate) fn define() -> Definitions {
|
||||
|
||||
let immediates = Immediates::new();
|
||||
let entities = EntityRefs::new();
|
||||
let format_registry = formats::define(&immediates, &entities);
|
||||
let instructions = instructions::define(
|
||||
&mut all_instructions,
|
||||
&format_registry,
|
||||
&immediates,
|
||||
&entities,
|
||||
);
|
||||
let formats = Formats::new(&immediates, &entities);
|
||||
let instructions =
|
||||
instructions::define(&mut all_instructions, &formats, &immediates, &entities);
|
||||
let transform_groups = legalize::define(&instructions, &immediates);
|
||||
|
||||
Definitions {
|
||||
@@ -44,7 +45,53 @@ pub(crate) fn define() -> Definitions {
|
||||
all_instructions,
|
||||
instructions,
|
||||
imm: immediates,
|
||||
format_registry,
|
||||
formats,
|
||||
transform_groups,
|
||||
}
|
||||
}
|
||||
|
||||
impl Definitions {
|
||||
/// Verifies certain properties of formats.
|
||||
///
|
||||
/// - Formats must be uniquely named: if two formats have the same name, they must refer to the
|
||||
/// same data. Otherwise, two format variants in the codegen crate would have the same name.
|
||||
/// - Formats must be structurally different from each other. Otherwise, this would lead to
|
||||
/// code duplicate in the codegen crate.
|
||||
///
|
||||
/// Returns a list of all the instruction formats effectively used.
|
||||
pub fn verify_instruction_formats(&self) -> Vec<&InstructionFormat> {
|
||||
let mut format_names: HashMap<&'static str, &Rc<InstructionFormat>> = HashMap::new();
|
||||
|
||||
// A structure is: number of input value operands / whether there's varargs or not / names
|
||||
// of immediate fields.
|
||||
let mut format_structures: HashMap<FormatStructure, &InstructionFormat> = HashMap::new();
|
||||
|
||||
for inst in self.all_instructions.values() {
|
||||
// Check name.
|
||||
if let Some(existing_format) = format_names.get(&inst.format.name) {
|
||||
assert!(
|
||||
Rc::ptr_eq(&existing_format, &inst.format),
|
||||
"formats must uniquely named; there's a\
|
||||
conflict on the name '{}', please make sure it is used only once.",
|
||||
existing_format.name
|
||||
);
|
||||
} else {
|
||||
format_names.insert(inst.format.name, &inst.format);
|
||||
}
|
||||
|
||||
// Check structure.
|
||||
let key = inst.format.structure();
|
||||
if let Some(existing_format) = format_structures.get(&key) {
|
||||
assert_eq!(
|
||||
existing_format.name, inst.format.name,
|
||||
"duplicate instruction formats {} and {}; please remove one.",
|
||||
existing_format.name, inst.format.name
|
||||
);
|
||||
} else {
|
||||
format_structures.insert(key, &inst.format);
|
||||
}
|
||||
}
|
||||
|
||||
Vec::from_iter(format_structures.into_iter().map(|(_, v)| v))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user