Skip to content

Commit

Permalink
feat: top leval variable back reference
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <xpf6677@163.com>
  • Loading branch information
Peefy committed Mar 4, 2024
1 parent 29b421f commit 325da1b
Show file tree
Hide file tree
Showing 29 changed files with 624 additions and 43 deletions.
84 changes: 80 additions & 4 deletions kclvm/compiler/src/codegen/llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,20 @@ impl<'ctx> BuilderMethods for LLVMCodeGenContext<'ctx> {
self.module.add_function(name, fn_ty, None)
}
}

/// Add a setter function named `name`.
fn add_setter_function(&self, name: &str) -> Self::Function {
let fn_ty = self.setter_func_type();
if self.no_link {
let pkgpath = self.current_pkgpath();
let msg = format!("pkgpath {} is not found", pkgpath);
let modules = self.modules.borrow_mut();
let module = modules.get(&pkgpath).expect(&msg).borrow_mut();
module.add_function(name, fn_ty, None)
} else {
self.module.add_function(name, fn_ty, None)
}
}
}

/* Value methods */
Expand Down Expand Up @@ -583,6 +597,16 @@ impl<'ctx> ValueMethods for LLVMCodeGenContext<'ctx> {
.get_first_param()
.expect(kcl_error::CONTEXT_VAR_NOT_FOUND_MSG)
}
/// Get the global evaluation scope pointer.
fn current_scope_ptr(&self) -> Self::Value {
self.builder
.get_insert_block()
.unwrap()
.get_parent()
.unwrap()
.get_last_param()
.expect(kcl_error::CONTEXT_VAR_NOT_FOUND_MSG)
}
}

impl<'ctx> ValueCalculationMethods for LLVMCodeGenContext<'ctx> {
Expand Down Expand Up @@ -1261,7 +1285,10 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
let tpe = self.value_ptr_type().into_pointer_type();
let void_type = self.context.void_type();
let context_ptr_type = self.context_ptr_type();
let fn_type = tpe.fn_type(&[context_ptr_type.into()], false);
let fn_type = tpe.fn_type(
&[context_ptr_type.into(), self.scope_ptr_type().into()],
false,
);
let void_fn_type = void_type.fn_type(&[context_ptr_type.into()], false);
let has_main_pkg = self.program.pkgs.contains_key(MAIN_PKG_PATH);
let function = if self.no_link {
Expand Down Expand Up @@ -1436,8 +1463,16 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
format!("{}_{}{}", path_str, index, OBJECT_FILE_SUFFIX)
};
let path = std::path::Path::new(&path);
module.borrow().print_to_file("_a.ll")?;
// Build LLVM module to a `.o` object file.
self.build_object_file(&module.borrow(), path)?;
match self.build_object_file(&module.borrow(), path) {
Ok(_) => return Ok(()),
Err(err) => {
// Only for debuging
module.borrow().print_to_file("_a.ll")?;
return Err(Box::new(err));
}
};
}
} else {
// Build LLVM module to a `.o` object file.
Expand Down Expand Up @@ -1727,6 +1762,16 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
let variables_mut = last.variables.borrow_mut();
if let Some(var) = variables_mut.get(&name.to_string()) {
self.builder.build_store(*var, value);
self.build_void_call(
&ApiFunc::kclvm_scope_set_global.name(),
&[
self.current_runtime_ctx_ptr(),
self.current_scope_ptr(),
self.native_global_string(&current_pkgpath, "").into(),
self.native_global_string(name, "").into(),
value,
],
);
existed = true;
}
}
Expand All @@ -1737,6 +1782,16 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
let var_name = format!("${}.${}", pkgpath_without_prefix!(pkgpath), name);
let pointer = self.new_global_kcl_value_ptr(&var_name);
self.builder.build_store(pointer, value);
self.build_void_call(
&ApiFunc::kclvm_scope_set_global.name(),
&[
self.current_runtime_ctx_ptr(),
self.current_scope_ptr(),
self.native_global_string(&current_pkgpath, "").into(),
self.native_global_string(name, "").into(),
value,
],
);
if !variables.contains_key(name) {
variables.insert(name.to_string(), pointer);
}
Expand Down Expand Up @@ -1853,6 +1908,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
} else {
pkgpath.to_string()
};
let is_in_schema = self.schema_stack.borrow().len() > 0;
let mut result = Err(kcl_error::KCLError {
message: format!("name '{}' is not defined", name),
ty: kcl_error::KCLErrorType::Compile,
Expand Down Expand Up @@ -1923,6 +1979,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
));
// User pkgpath
} else {
// Global or local variables.
let scopes = pkg_scopes
.get(&pkgpath)
.unwrap_or_else(|| panic!("package {} is not found", pkgpath));
Expand Down Expand Up @@ -1956,7 +2013,27 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
None => self.builder.build_load(*var, name),
}
} else {
self.builder.build_load(*var, name)
if !is_in_schema {
let target = self
.target_vars
.borrow_mut()
.last()
.expect(kcl_error::INTERNAL_ERROR_MSG)
.clone();
self.build_call(
&ApiFunc::kclvm_scope_get_global.name(),
&[
self.current_runtime_ctx_ptr(),
self.current_scope_ptr(),
self.native_global_string(&pkgpath, "").into(),
self.native_global_string(name, "").into(),
self.native_global_string_value(&target).into(),
self.builder.build_load(*var, name),
],
)
} else {
self.builder.build_load(*var, name)
}
};
result = Ok(value);
break;
Expand All @@ -1965,7 +2042,6 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
match result {
Ok(_) => result,
Err(ref err) => {
let is_in_schema = self.schema_stack.borrow().len() > 0;
if !is_in_schema {
let mut handler = self.handler.borrow_mut();
let pos = Position {
Expand Down
8 changes: 4 additions & 4 deletions kclvm/compiler/src/codegen/llvm/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn emit_code(
program: &ast::Program,
workdir: String,
import_names: IndexMap<String, IndexMap<String, String>>,
opt: &EmitOptions,
opts: &EmitOptions,
) -> Result<(), Box<dyn error::Error>> {
// Init LLVM targets
LLVM_INIT.get_or_init(|| {
Expand All @@ -40,7 +40,7 @@ pub fn emit_code(
// Create a LLVM context
let context = Context::create();
// Create a LLVM module using an exist LLVM bitcode file
let module = if let Some(path) = &opt.from_path {
let module = if let Some(path) = &opts.from_path {
Module::parse_bitcode_from_path(std::path::Path::new(path), &context).unwrap()
} else {
load_runtime(&context)
Expand All @@ -51,9 +51,9 @@ pub fn emit_code(
module,
program,
import_names,
opt.no_link,
opts.no_link,
workdir,
);
// Generate user KCL code LLVM IR
crate::codegen::emit_code(ctx, opt)
crate::codegen::emit_code(ctx, opts)
}
Loading

0 comments on commit 325da1b

Please sign in to comment.