Skip to content

Commit dfef19e

Browse files
authored
Merge pull request #5 from antoyo/reflection-api
Reflection api
2 parents 2538681 + 5ae5252 commit dfef19e

File tree

12 files changed

+69
-206
lines changed

12 files changed

+69
-206
lines changed

Cargo.lock

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gcc-test-backend/Cargo.lock

-25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gcc-test-backend/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2018"
77
[dependencies]
88
#depth1 = { path = "depth1" }
99
#mini_core = { path = "mini_core" }
10-
deflate = "0.7.19"
10+
#deflate = "0.7.19"
1111

1212
[profile.dev]
1313
panic = "abort"

gcc-test-backend/src/main.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ fn main() {
128128
129129
println!("{}", leaves.capacity());*/
130130

131+
println!("Hello, world!");
131132

132-
let mut leaves: Vec<Node> = Vec::with_capacity(286);
133+
/*let mut leaves: Vec<Node> = Vec::with_capacity(286);
133134
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];
134135
let len = 10;
135136
unsafe {
136137
println!("&{:?}[10] = {:?}", frequencies.as_ptr(), frequencies.as_ptr().add(len));
137-
}
138+
}*/
138139
/*leaves.extend(frequencies.iter().enumerate().filter_map(
139140
|(n, f)| if *f > 0 {
140141
Some(Node {

src/abi.rs

-4
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,6 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
162162
fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
163163
let (return_type, params, variadic) = self.gcc_type(cx);
164164
let pointer_type = cx.context.new_function_pointer_type(None, return_type, &params, variadic);
165-
cx.function_type_param_return_value.borrow_mut().insert(pointer_type, FuncSig {
166-
params,
167-
return_type,
168-
});
169165
pointer_type
170166
}
171167

src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (Modul
7373
//let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
7474
let context = Context::default();
7575
//context.set_dump_code_on_compile(true);
76-
//context.set_dump_initial_gimple(true);
76+
context.set_dump_initial_gimple(true);
7777
context.set_debug_info(true);
7878
//context.set_dump_everything(true);
7979
//context.set_keep_intermediates(true);

src/builder.rs

+32-51
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'gcc, 'tcx> Builder<'_, 'gcc, 'tcx> {
131131
Cow::Owned(casted_args)
132132
}
133133

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

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

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

262-
let args = self.check_ptr_call("call", func, args);
259+
let args = self.check_ptr_call("call", func_ptr, args);
263260
//let bundle = funclet.map(|funclet| funclet.bundle());
264261
//let bundle = bundle.as_ref().map(|b| &*b.raw);
265262

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

275271
if return_type != void_type {
276272
unsafe { RETURN_VALUE_COUNT += 1 };
277273
let result = current_func.new_local(None, return_type, &format!("returnValue{}", unsafe { RETURN_VALUE_COUNT }));
278-
current_block.add_assignment(None, result, self.cx.context.new_call_through_ptr(None, func, &args));
274+
current_block.add_assignment(None, result, self.cx.context.new_call_through_ptr(None, func_ptr, &args));
279275
result.to_rvalue()
280276
}
281277
else {
282-
current_block.add_eval(None, self.cx.context.new_call_through_ptr(None, func, &args));
278+
current_block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args));
283279
// Return dummy value when not having return value.
284280
self.context.new_rvalue_from_long(self.isize_type, 0)
285281
}
@@ -599,7 +595,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
599595

600596
fn not(&mut self, a: RValue<'gcc>) -> RValue<'gcc> {
601597
let operation =
602-
if a.get_type().is_bool(&self.cx) {
598+
if a.get_type().is_bool() {
603599
UnaryOp::LogicalNegate
604600
}
605601
else {
@@ -755,23 +751,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
755751

756752
fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {
757753
let aligned_type = ty.get_aligned(align.bytes());
758-
let type_fields = self.fields.borrow().get(&ty).cloned();
759-
// TODO: remove these conditiosn when libgccjit has a reflection API.
760-
if self.array_types.borrow().contains(&ty) {
761-
self.array_types.borrow_mut().insert(aligned_type);
762-
}
763-
else if self.vector_types.borrow().contains_key(&ty) {
764-
let value = self.vector_types.borrow().get(&ty).expect("vector type").clone();
765-
self.vector_types.borrow_mut().insert(aligned_type, value);
766-
}
767-
else if let Some(fields) = type_fields {
768-
self.fields.borrow_mut().insert(aligned_type, fields);
769-
}
770-
else if self.function_type_param_return_value.borrow().contains_key(&ty) {
771-
let func_sig = self.function_type_param_return_value.borrow().get(&ty).expect("function sig").clone();
772-
self.function_type_param_return_value.borrow_mut().insert(aligned_type, func_sig);
773-
}
774-
775754
// TODO: It might be better to return a LValue, but fixing the rustc API is non-trivial.
776755
self.current_func().new_local(None, aligned_type, "stack_var").get_address(None)
777756
}
@@ -1033,12 +1012,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
10331012
let value = ptr.dereference(None).to_rvalue();
10341013
let value_type = value.get_type();
10351014

1036-
if self.array_types.borrow().contains(&value_type) {
1015+
if value_type.is_array() {
10371016
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
10381017
let element = self.context.new_array_access(None, value, index);
10391018
element.get_address(None)
10401019
}
1041-
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
1020+
else if let Some(vector_type) = value_type.is_vector() {
1021+
let count = vector_type.get_num_units();
1022+
let element_type = vector_type.get_element_type();
10421023
let indexes = vec![self.context.new_rvalue_from_long(element_type, i64::try_from(idx).expect("i64::try_from")); count as usize];
10431024
let indexes = self.context.new_rvalue_from_vector(None, value_type, &indexes);
10441025
let variable = self.current_func.borrow().expect("func")
@@ -1047,11 +1028,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
10471028
.add_assignment(None, variable, value + indexes);
10481029
variable.get_address(None)
10491030
}
1031+
else if let Some(struct_type) = value_type.is_struct() {
1032+
ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
1033+
}
10501034
else {
1051-
let fields = self.fields.borrow();
1052-
let fields = &fields.get(&value_type)
1053-
.unwrap_or_else(|| panic!("Structure {:?} ({:?}) not in fields", value, value.get_type()));
1054-
ptr.dereference_field(None, fields[idx as usize]).get_address(None)
1035+
panic!("Unexpected type {:?}", value_type);
10551036
}
10561037
}
10571038

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

1250-
if self.array_types.borrow().contains(&value_type) {
1231+
if value_type.is_array() {
12511232
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
12521233
let element = self.context.new_array_access(None, aggregate_value, index);
12531234
element.get_address(None)
12541235
}
1255-
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
1236+
else if value_type.is_vector().is_some() {
12561237
panic!();
12571238
}
1239+
else if let Some(struct_type) = value_type.is_struct() {
1240+
aggregate_value.access_field(None, struct_type.get_field(idx as i32)).to_rvalue()
1241+
}
12581242
else {
1259-
let fields = self.fields.borrow();
1260-
let fields = &fields.get(&value_type)
1261-
.unwrap_or_else(|| panic!("Structure {:?} not in fields", aggregate_value.get_type()));
1262-
aggregate_value.access_field(None, fields[idx as usize]).to_rvalue()
1243+
panic!("Unexpected type {:?}", value_type);
12631244
}
12641245
/*assert_eq!(idx as c_uint as u64, idx);
12651246
unsafe { llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) }*/
@@ -1271,18 +1252,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
12711252
let value_type = aggregate_value.get_type();
12721253

12731254
let lvalue =
1274-
if self.array_types.borrow().contains(&value_type) {
1255+
if value_type.is_array() {
12751256
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
12761257
self.context.new_array_access(None, aggregate_value, index)
12771258
}
1278-
else if let Some(&(count, element_type)) = self.vector_types.borrow().get(&value_type) {
1259+
else if value_type.is_vector().is_some() {
12791260
panic!();
12801261
}
1262+
else if let Some(struct_type) = value_type.is_struct() {
1263+
aggregate_value.access_field(None, struct_type.get_field(idx as i32))
1264+
}
12811265
else {
1282-
let fields = self.fields.borrow();
1283-
let fields = &fields.get(&value_type)
1284-
.unwrap_or_else(|| panic!("Structure {:?} not in fields", aggregate_value.get_type()));
1285-
aggregate_value.access_field(None, fields[idx as usize])
1266+
panic!("Unexpected type {:?}", value_type);
12861267
};
12871268
self.llbb().add_assignment(None, lvalue, value);
12881269

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

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

0 commit comments

Comments
 (0)