forked from M-Labs/nac3
nac3core: optimize unwrap KernelInvariant
This commit is contained in:
parent
f66f66b3a4
commit
ad9ad22cb8
@ -170,6 +170,16 @@ impl StaticValue for PythonValue {
|
|||||||
let helper = &self.resolver.helper;
|
let helper = &self.resolver.helper;
|
||||||
let ty = helper.type_fn.call1(py, (&self.value,))?;
|
let ty = helper.type_fn.call1(py, (&self.value,))?;
|
||||||
let ty_id: u64 = helper.id_fn.call1(py, (ty,))?.extract(py)?;
|
let ty_id: u64 = helper.id_fn.call1(py, (ty,))?.extract(py)?;
|
||||||
|
// for optimizing unwrap KernelInvariant
|
||||||
|
if ty_id == self.resolver.primitive_ids.option && name == "_nac3_option".into() {
|
||||||
|
let obj = self.value.getattr(py, &name.to_string())?;
|
||||||
|
let id = self.resolver.helper.id_fn.call1(py, (&obj,))?.extract(py)?;
|
||||||
|
if self.id == self.resolver.primitive_ids.none {
|
||||||
|
return Ok(None)
|
||||||
|
} else {
|
||||||
|
return Ok(Some((id, obj)))
|
||||||
|
}
|
||||||
|
}
|
||||||
let def_id = { *self.resolver.pyid_to_def.read().get(&ty_id).unwrap() };
|
let def_id = { *self.resolver.pyid_to_def.read().get(&ty_id).unwrap() };
|
||||||
let mut mutable = true;
|
let mut mutable = true;
|
||||||
let defs = ctx.top_level.definitions.read();
|
let defs = ctx.top_level.definitions.read();
|
||||||
|
@ -1354,23 +1354,66 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// directly generate code for option.unwrap
|
// directly generate code for option.unwrap
|
||||||
// since it needs location information from ast
|
// since it needs to return static value to optimize for kernel invariant
|
||||||
if attr == &"unwrap".into()
|
if attr == &"unwrap".into()
|
||||||
&& id == ctx.primitives.option.get_obj_id(&ctx.unifier)
|
&& id == ctx.primitives.option.get_obj_id(&ctx.unifier)
|
||||||
{
|
{
|
||||||
if let BasicValueEnum::PointerValue(ptr) = val.to_basic_value_enum(ctx, generator, value.custom.unwrap())? {
|
match val {
|
||||||
let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null");
|
ValueEnum::Static(v) => match v.get_field("_nac3_option".into(), ctx) {
|
||||||
ctx.make_assert(
|
// if is none, raise exception directly
|
||||||
generator,
|
None => {
|
||||||
not_null,
|
let err_msg = ctx.gen_string(generator, "");
|
||||||
"0:UnwrapNoneError",
|
let current_fun = ctx
|
||||||
"",
|
.builder
|
||||||
[None, None, None],
|
.get_insert_block()
|
||||||
expr.location,
|
.unwrap()
|
||||||
);
|
.get_parent()
|
||||||
return Ok(Some(ctx.builder.build_load(ptr, "unwrap_some").into()))
|
.unwrap();
|
||||||
} else {
|
let unreachable_block = ctx.ctx.append_basic_block(
|
||||||
unreachable!("option must be ptr")
|
current_fun,
|
||||||
|
"unwrap_none_unreachable"
|
||||||
|
);
|
||||||
|
let exn_block = ctx.ctx.append_basic_block(
|
||||||
|
current_fun,
|
||||||
|
"unwrap_none_exception"
|
||||||
|
);
|
||||||
|
ctx.builder.build_unconditional_branch(exn_block);
|
||||||
|
ctx.builder.position_at_end(exn_block);
|
||||||
|
ctx.raise_exn(
|
||||||
|
generator,
|
||||||
|
"0:UnwrapNoneError",
|
||||||
|
err_msg,
|
||||||
|
[None, None, None],
|
||||||
|
ctx.current_loc
|
||||||
|
);
|
||||||
|
ctx.builder.position_at_end(unreachable_block);
|
||||||
|
let ptr = ctx
|
||||||
|
.get_llvm_type(generator, value.custom.unwrap())
|
||||||
|
.into_pointer_type()
|
||||||
|
.const_null();
|
||||||
|
return Ok(Some(ctx.builder.build_load(
|
||||||
|
ptr,
|
||||||
|
"unwrap_none_unreachable_load"
|
||||||
|
).into()));
|
||||||
|
}
|
||||||
|
Some(v) => return Ok(Some(v)),
|
||||||
|
}
|
||||||
|
ValueEnum::Dynamic(BasicValueEnum::PointerValue(ptr)) => {
|
||||||
|
let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null");
|
||||||
|
ctx.make_assert(
|
||||||
|
generator,
|
||||||
|
not_null,
|
||||||
|
"0:UnwrapNoneError",
|
||||||
|
"",
|
||||||
|
[None, None, None],
|
||||||
|
expr.location,
|
||||||
|
);
|
||||||
|
return Ok(Some(ctx.builder.build_load(
|
||||||
|
ptr,
|
||||||
|
"unwrap_some_load"
|
||||||
|
).into()))
|
||||||
|
}
|
||||||
|
_ => unreachable!("option must be static or ptr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(generator
|
return Ok(generator
|
||||||
|
Loading…
Reference in New Issue
Block a user