Cleanup const generics implementation #363

Merged
sb10q merged 4 commits from feat/const-generics into master 2023-12-12 15:36:40 +08:00
5 changed files with 29 additions and 47 deletions

View File

@ -86,7 +86,13 @@ def ceil64(x):
import device_db import device_db
core_arguments = device_db.device_db["core"]["arguments"] core_arguments = device_db.device_db["core"]["arguments"]
compiler = nac3artiq.NAC3(core_arguments["target"]) artiq_builtins = {
"none": none,
"virtual": virtual,
"_ConstGenericMarker": _ConstGenericMarker,
"Option": Option,
}
compiler = nac3artiq.NAC3(core_arguments["target"], artiq_builtins)
allow_registration = True allow_registration = True
# Delay NAC3 analysis until all referenced variables are supposed to exist on the CPython side. # Delay NAC3 analysis until all referenced variables are supposed to exist on the CPython side.
registered_functions = set() registered_functions = set()

View File

@ -75,7 +75,7 @@ pub struct PrimitivePythonId {
list: u64, list: u64,
tuple: u64, tuple: u64,
typevar: u64, typevar: u64,
const_generic_dummy: u64, const_generic_marker: u64,
none: u64, none: u64,
exception: u64, exception: u64,
generic_alias: (u64, u64), generic_alias: (u64, u64),
@ -776,7 +776,7 @@ fn add_exceptions(
#[pymethods] #[pymethods]
impl Nac3 { impl Nac3 {
#[new] #[new]
fn new(isa: &str, py: Python) -> PyResult<Self> { fn new(isa: &str, artiq_builtins: &PyDict, py: Python) -> PyResult<Self> {
let isa = match isa { let isa = match isa {
"host" => Isa::Host, "host" => Isa::Host,
"rv32g" => Isa::RiscV32G, "rv32g" => Isa::RiscV32G,
@ -842,44 +842,18 @@ impl Nac3 {
let typing_mod = PyModule::import(py, "typing").unwrap(); let typing_mod = PyModule::import(py, "typing").unwrap();
let types_mod = PyModule::import(py, "types").unwrap(); let types_mod = PyModule::import(py, "types").unwrap();
let get_id = |x| id_fn.call1((x,)).unwrap().extract().unwrap(); let get_id = |x: &PyAny| id_fn.call1((x,)).and_then(PyAny::extract).unwrap();
let get_attr_id = |obj: &PyModule, attr| id_fn.call1((obj.getattr(attr).unwrap(),)) let get_attr_id = |obj: &PyModule, attr| id_fn.call1((obj.getattr(attr).unwrap(),))
.unwrap().extract().unwrap(); .unwrap().extract().unwrap();
let primitive_ids = PrimitivePythonId { let primitive_ids = PrimitivePythonId {
virtual_id: get_id( virtual_id: get_id(artiq_builtins.get_item("virtual").ok().flatten().unwrap()),
builtins_mod
.getattr("globals")
.unwrap()
.call0()
.unwrap()
.get_item("virtual")
.unwrap(
)),
generic_alias: ( generic_alias: (
get_attr_id(typing_mod, "_GenericAlias"), get_attr_id(typing_mod, "_GenericAlias"),
get_attr_id(types_mod, "GenericAlias"), get_attr_id(types_mod, "GenericAlias"),
), ),
none: id_fn none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap()),
.call1((builtins_mod
.getattr("globals")
.unwrap()
.call0()
.unwrap()
.get_item("none")
.unwrap(),))
.unwrap()
.extract()
.unwrap(),
typevar: get_attr_id(typing_mod, "TypeVar"), typevar: get_attr_id(typing_mod, "TypeVar"),
const_generic_dummy: id_fn const_generic_marker: get_id(artiq_builtins.get_item("_ConstGenericMarker").ok().flatten().unwrap()),
.call1((
builtins_mod.getattr("globals")
.and_then(|v| v.call0())
.and_then(|v| v.get_item("_ConstGenericMarker"))
.unwrap(),
))
.and_then(PyAny::extract)
.unwrap(),
int: get_attr_id(builtins_mod, "int"), int: get_attr_id(builtins_mod, "int"),
int32: get_attr_id(numpy_mod, "int32"), int32: get_attr_id(numpy_mod, "int32"),
int64: get_attr_id(numpy_mod, "int64"), int64: get_attr_id(numpy_mod, "int64"),
@ -891,17 +865,7 @@ impl Nac3 {
list: get_attr_id(builtins_mod, "list"), list: get_attr_id(builtins_mod, "list"),
tuple: get_attr_id(builtins_mod, "tuple"), tuple: get_attr_id(builtins_mod, "tuple"),
exception: get_attr_id(builtins_mod, "Exception"), exception: get_attr_id(builtins_mod, "Exception"),
option: id_fn option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap()),
.call1((builtins_mod
.getattr("globals")
.unwrap()
.call0()
.unwrap()
.get_item("Option")
.unwrap(),))
.unwrap()
.extract()
.unwrap(),
}; };
let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap(); let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap();

View File

@ -353,7 +353,7 @@ impl InnerResolver {
for i in 0usize.. { for i in 0usize.. {
if let Ok(constr) = constraints.get_item(i) { if let Ok(constr) = constraints.get_item(i) {
let constr_id: u64 = self.helper.id_fn.call1(py, (constr,))?.extract(py)?; let constr_id: u64 = self.helper.id_fn.call1(py, (constr,))?.extract(py)?;
if constr_id == self.primitive_ids.const_generic_dummy { if constr_id == self.primitive_ids.const_generic_marker {
is_const_generic = true; is_const_generic = true;
continue continue
} }

View File

@ -60,6 +60,10 @@ pub enum ConcreteTypeEnum {
ret: ConcreteType, ret: ConcreteType,
vars: HashMap<u32, ConcreteType>, vars: HashMap<u32, ConcreteType>,
}, },
TConstant {
value: SymbolValue,
ty: ConcreteType,
},
} }
impl ConcreteTypeStore { impl ConcreteTypeStore {
@ -198,7 +202,11 @@ impl ConcreteTypeStore {
TypeEnum::TFunc(signature) => { TypeEnum::TFunc(signature) => {
self.from_signature(unifier, primitives, signature, cache) self.from_signature(unifier, primitives, signature, cache)
} }
_ => unreachable!(), TypeEnum::TConstant { value, ty, .. } => ConcreteTypeEnum::TConstant {
value: value.clone(),
ty: self.from_unifier_type(unifier, primitives, *ty, cache),
},
_ => unreachable!("{:?}", ty_enum.get_type_name()),
}; };
let index = if let Some(ConcreteType(index)) = cache.get(&ty).unwrap() { let index = if let Some(ConcreteType(index)) = cache.get(&ty).unwrap() {
self.store[*index] = result; self.store[*index] = result;
@ -285,6 +293,11 @@ impl ConcreteTypeStore {
.map(|(id, cty)| (*id, self.to_unifier_type(unifier, primitives, *cty, cache))) .map(|(id, cty)| (*id, self.to_unifier_type(unifier, primitives, *cty, cache)))
.collect::<HashMap<_, _>>(), .collect::<HashMap<_, _>>(),
}), }),
ConcreteTypeEnum::TConstant { value, ty } => TypeEnum::TConstant {
value: value.clone(),
ty: self.to_unifier_type(unifier, primitives, *ty, cache),
loc: None,
}
}; };
let result = unifier.add_ty(result); let result = unifier.add_ty(result);
if let Some(ty) = cache.get(&cty).unwrap() { if let Some(ty) = cache.get(&cty).unwrap() {

View File

@ -746,7 +746,6 @@ impl Unifier {
(TConstant { value: val1, ty: ty1, .. }, TConstant { value: val2, ty: ty2, .. }) => { (TConstant { value: val1, ty: ty1, .. }, TConstant { value: val2, ty: ty2, .. }) => {
if val1 != val2 { if val1 != val2 {
eprintln!("VALUE MISMATCH: lhs={val1:?} rhs={val2:?} eq={}", val1 == val2);
return self.incompatible_types(a, b) return self.incompatible_types(a, b)
} }
self.unify_impl(*ty1, *ty2, false)?; self.unify_impl(*ty1, *ty2, false)?;