Skip to content

Reflection api #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 0 additions & 25 deletions gcc-test-backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gcc-test-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
#depth1 = { path = "depth1" }
#mini_core = { path = "mini_core" }
deflate = "0.7.19"
#deflate = "0.7.19"

[profile.dev]
panic = "abort"
Expand Down
5 changes: 3 additions & 2 deletions gcc-test-backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,14 @@ fn main() {
println!("{}", leaves.capacity());*/

println!("Hello, world!");

let mut leaves: Vec<Node> = Vec::with_capacity(286);
/*let mut leaves: Vec<Node> = Vec::with_capacity(286);
let frequencies/*: &[i32]*/ = &[526, 124, 128, 125, 107, 92, 84, 75, 88, 53, 63, 43, 54, 68, 56, 60, 38, 53, 37, 23, 36, 32, 21, 25, 20, 21, 27, 26, 16, 15, 20, 24, 22, 14, 12, 19, 19, 10, 15, 11, 13, 4, 15, 7, 6, 10, 10, 2, 1, 3, 3, 2, 2, 3, 2, 1, 1, 0, 0, 0, 2, 1, 0, 0, 0, 1, 3, 0, 1, 2, 3, 0, 2, 1, 4, 0, 1, 1, 1, 2, 2, 2, 3, 1, 1, 0, 0, 3, 0, 1, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 2, 0, 0, 1, 0, 2, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 2, 0, 0, 1, 1, 0, 2, 0, 1, 1, 0, 0, 1, 2, 0, 2, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 0, 2, 1, 2, 0, 2, 0, 0, 1, 0, 0, 0, 2, 1, 0, 0, 1, 0, 0, 2, 0, 2, 0, 4, 6, 3, 4, 8, 7, 2, 7, 6, 8, 5, 8, 8, 17, 11, 16, 10, 8, 7, 13, 9, 14, 18, 12, 10, 19, 12, 11, 17, 15, 13, 17, 14, 17, 23, 31, 44, 27, 25, 30, 18, 17, 20, 25, 72, 52, 55, 69, 87, 75, 1, 7754, 5054, 3016, 2120, 1790, 1263, 606, 602, 958, 783, 481, 333, 510, 392, 211, 177, 169, 89, 58, 70, 110, 56, 37, 52, 63, 38, 48, 13, 1373];
let len = 10;
unsafe {
println!("&{:?}[10] = {:?}", frequencies.as_ptr(), frequencies.as_ptr().add(len));
}
}*/
/*leaves.extend(frequencies.iter().enumerate().filter_map(
|(n, f)| if *f > 0 {
Some(Node {
Expand Down
4 changes: 0 additions & 4 deletions src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
let (return_type, params, variadic) = self.gcc_type(cx);
let pointer_type = cx.context.new_function_pointer_type(None, return_type, &params, variadic);
cx.function_type_param_return_value.borrow_mut().insert(pointer_type, FuncSig {
params,
return_type,
});
pointer_type
}

Expand Down
2 changes: 1 addition & 1 deletion src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (Modul
//let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
let context = Context::default();
//context.set_dump_code_on_compile(true);
//context.set_dump_initial_gimple(true);
context.set_dump_initial_gimple(true);
context.set_debug_info(true);
//context.set_dump_everything(true);
//context.set_keep_intermediates(true);
Expand Down
83 changes: 32 additions & 51 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl<'gcc, 'tcx> Builder<'_, 'gcc, 'tcx> {
Cow::Owned(casted_args)
}

fn check_ptr_call<'b>(&mut self, typ: &str, func: RValue<'gcc>, args: &'b [RValue<'gcc>]) -> Cow<'b, [RValue<'gcc>]> {
fn check_ptr_call<'b>(&mut self, typ: &str, func_ptr: RValue<'gcc>, args: &'b [RValue<'gcc>]) -> Cow<'b, [RValue<'gcc>]> {
//let mut fn_ty = self.cx.val_ty(func);
// Strip off pointers
/*while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
Expand All @@ -154,12 +154,9 @@ impl<'gcc, 'tcx> Builder<'_, 'gcc, 'tcx> {

let mut all_args_match = true;
let mut param_types = vec![];
let func_types = self.cx.function_type_param_return_value.borrow();
let ptr: *mut usize = unsafe { std::mem::transmute(func.get_type()) };
let func_sig = func_types.get(&func.get_type())
.unwrap_or_else(|| panic!("No function_type_param_return_value for {:?}", func.get_type()));
for (index, arg) in args.iter().enumerate().take(func_sig.params.len()) {
let param = func_sig.params[index];
let gcc_func = func_ptr.get_type().is_function_ptr_type().expect("function ptr");
for (index, arg) in args.iter().enumerate().take(gcc_func.get_param_count()) {
let param = gcc_func.get_param_type(index);
if param != arg.get_type() {
all_args_match = false;
}
Expand Down Expand Up @@ -256,30 +253,29 @@ impl<'gcc, 'tcx> Builder<'_, 'gcc, 'tcx> {
}
}

fn function_ptr_call(&mut self, mut func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> {
fn function_ptr_call(&mut self, mut func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> {
//debug!("func ptr call {:?} with args ({:?})", func, args);

let args = self.check_ptr_call("call", func, args);
let args = self.check_ptr_call("call", func_ptr, args);
//let bundle = funclet.map(|funclet| funclet.bundle());
//let bundle = bundle.as_ref().map(|b| &*b.raw);

// gccjit requires to use the result of functions, even when it's not used.
// That's why we assign the result to a local or call add_eval().
let return_type = self.function_type_param_return_value.borrow().get(&func.get_type())
.map(|func_sig| func_sig.return_type)
.unwrap_or_else(|| panic!("No return type for {:?}", func));
let gcc_func = func_ptr.get_type().is_function_ptr_type().expect("function ptr");
let return_type = gcc_func.get_return_type();
let current_block = self.current_block.borrow().expect("block");
let void_type = self.context.new_type::<()>();
let current_func = current_block.get_function();

if return_type != void_type {
unsafe { RETURN_VALUE_COUNT += 1 };
let result = current_func.new_local(None, return_type, &format!("returnValue{}", unsafe { RETURN_VALUE_COUNT }));
current_block.add_assignment(None, result, self.cx.context.new_call_through_ptr(None, func, &args));
current_block.add_assignment(None, result, self.cx.context.new_call_through_ptr(None, func_ptr, &args));
result.to_rvalue()
}
else {
current_block.add_eval(None, self.cx.context.new_call_through_ptr(None, func, &args));
current_block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args));
// Return dummy value when not having return value.
self.context.new_rvalue_from_long(self.isize_type, 0)
}
Expand Down Expand Up @@ -599,7 +595,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

fn not(&mut self, a: RValue<'gcc>) -> RValue<'gcc> {
let operation =
if a.get_type().is_bool(&self.cx) {
if a.get_type().is_bool() {
UnaryOp::LogicalNegate
}
else {
Expand Down Expand Up @@ -755,23 +751,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {
let aligned_type = ty.get_aligned(align.bytes());
let type_fields = self.fields.borrow().get(&ty).cloned();
// TODO: remove these conditiosn when libgccjit has a reflection API.
if self.array_types.borrow().contains(&ty) {
self.array_types.borrow_mut().insert(aligned_type);
}
else if self.vector_types.borrow().contains_key(&ty) {
let value = self.vector_types.borrow().get(&ty).expect("vector type").clone();
self.vector_types.borrow_mut().insert(aligned_type, value);
}
else if let Some(fields) = type_fields {
self.fields.borrow_mut().insert(aligned_type, fields);
}
else if self.function_type_param_return_value.borrow().contains_key(&ty) {
let func_sig = self.function_type_param_return_value.borrow().get(&ty).expect("function sig").clone();
self.function_type_param_return_value.borrow_mut().insert(aligned_type, func_sig);
}

// TODO: It might be better to return a LValue, but fixing the rustc API is non-trivial.
self.current_func().new_local(None, aligned_type, "stack_var").get_address(None)
}
Expand Down Expand Up @@ -1033,12 +1012,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
let value = ptr.dereference(None).to_rvalue();
let value_type = value.get_type();

if self.array_types.borrow().contains(&value_type) {
if value_type.is_array() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
let element = self.context.new_array_access(None, value, index);
element.get_address(None)
}
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
else if let Some(vector_type) = value_type.is_vector() {
let count = vector_type.get_num_units();
let element_type = vector_type.get_element_type();
let indexes = vec![self.context.new_rvalue_from_long(element_type, i64::try_from(idx).expect("i64::try_from")); count as usize];
let indexes = self.context.new_rvalue_from_vector(None, value_type, &indexes);
let variable = self.current_func.borrow().expect("func")
Expand All @@ -1047,11 +1028,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
.add_assignment(None, variable, value + indexes);
variable.get_address(None)
}
else if let Some(struct_type) = value_type.is_struct() {
ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
}
else {
let fields = self.fields.borrow();
let fields = &fields.get(&value_type)
.unwrap_or_else(|| panic!("Structure {:?} ({:?}) not in fields", value, value.get_type()));
ptr.dereference_field(None, fields[idx as usize]).get_address(None)
panic!("Unexpected type {:?}", value_type);
}
}

Expand Down Expand Up @@ -1247,19 +1228,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
assert_eq!(idx as usize as u64, idx);
let value_type = aggregate_value.get_type();

if self.array_types.borrow().contains(&value_type) {
if value_type.is_array() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
let element = self.context.new_array_access(None, aggregate_value, index);
element.get_address(None)
}
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
else if value_type.is_vector().is_some() {
panic!();
}
else if let Some(struct_type) = value_type.is_struct() {
aggregate_value.access_field(None, struct_type.get_field(idx as i32)).to_rvalue()
}
else {
let fields = self.fields.borrow();
let fields = &fields.get(&value_type)
.unwrap_or_else(|| panic!("Structure {:?} not in fields", aggregate_value.get_type()));
aggregate_value.access_field(None, fields[idx as usize]).to_rvalue()
panic!("Unexpected type {:?}", value_type);
}
/*assert_eq!(idx as c_uint as u64, idx);
unsafe { llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) }*/
Expand All @@ -1271,18 +1252,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
let value_type = aggregate_value.get_type();

let lvalue =
if self.array_types.borrow().contains(&value_type) {
if value_type.is_array() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
self.context.new_array_access(None, aggregate_value, index)
}
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
else if value_type.is_vector().is_some() {
panic!();
}
else if let Some(struct_type) = value_type.is_struct() {
aggregate_value.access_field(None, struct_type.get_field(idx as i32))
}
else {
let fields = self.fields.borrow();
let fields = &fields.get(&value_type)
.unwrap_or_else(|| panic!("Structure {:?} not in fields", aggregate_value.get_type()));
aggregate_value.access_field(None, fields[idx as usize])
panic!("Unexpected type {:?}", value_type);
};
self.llbb().add_assignment(None, lvalue, value);

Expand Down Expand Up @@ -1469,7 +1450,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
// FIXME: this does not zero-extend.
if value.get_type().is_bool(&self.cx) && dest_typ.is_i8(&self.cx) {
if value.get_type().is_bool() && dest_typ.is_i8(&self.cx) {
// FIXME: hack because base::from_immediate converts i1 to i8.
// Fix the code in codegen_ssa::base::from_immediate.
return value;
Expand Down
Loading