Merge commit '1bbee3e217
' into sync-cg_gcc-2023-06-19
This commit is contained in:
commit
4d96893d85
23 changed files with 244 additions and 264 deletions
|
@ -181,6 +181,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
debug_assert_eq!(casted_args.len(), args.len());
|
||||
|
||||
Cow::Owned(casted_args)
|
||||
}
|
||||
|
||||
|
@ -207,7 +209,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
|
||||
let func_name = format!("{:?}", func_ptr);
|
||||
|
||||
let casted_args: Vec<_> = param_types
|
||||
let mut casted_args: Vec<_> = param_types
|
||||
.into_iter()
|
||||
.zip(args.iter())
|
||||
.enumerate()
|
||||
|
@ -237,6 +239,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
// NOTE: to take into account variadic functions.
|
||||
for i in casted_args.len()..args.len() {
|
||||
casted_args.push(args[i]);
|
||||
}
|
||||
|
||||
Cow::Owned(casted_args)
|
||||
}
|
||||
|
||||
|
@ -280,8 +287,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn function_ptr_call(&mut self, func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
||||
let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
|
||||
fn function_ptr_call(&mut self, typ: Type<'gcc>, mut func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
||||
let gcc_func =
|
||||
match func_ptr.get_type().dyncast_function_ptr_type() {
|
||||
Some(func) => func,
|
||||
None => {
|
||||
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||
let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr");
|
||||
func_ptr = self.context.new_cast(None, func_ptr, typ);
|
||||
new_func_type
|
||||
},
|
||||
};
|
||||
let func_name = format!("{:?}", func_ptr);
|
||||
let previous_arg_count = args.len();
|
||||
let orig_args = args;
|
||||
|
@ -424,16 +440,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
self.llbb().end_with_void_return(None)
|
||||
}
|
||||
|
||||
fn ret(&mut self, value: RValue<'gcc>) {
|
||||
let value =
|
||||
if self.structs_as_pointer.borrow().contains(&value) {
|
||||
// NOTE: hack to workaround a limitation of the rustc API: see comment on
|
||||
// CodegenCx.structs_as_pointer
|
||||
value.dereference(None).to_rvalue()
|
||||
}
|
||||
else {
|
||||
value
|
||||
};
|
||||
fn ret(&mut self, mut value: RValue<'gcc>) {
|
||||
if self.structs_as_pointer.borrow().contains(&value) {
|
||||
// NOTE: hack to workaround a limitation of the rustc API: see comment on
|
||||
// CodegenCx.structs_as_pointer
|
||||
value = value.dereference(None).to_rvalue();
|
||||
}
|
||||
let expected_return_type = self.current_func().get_return_type();
|
||||
if !expected_return_type.is_compatible_with(value.get_type()) {
|
||||
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||
value = self.context.new_cast(None, value, expected_return_type);
|
||||
}
|
||||
self.llbb().end_with_return(None, value);
|
||||
}
|
||||
|
||||
|
@ -719,17 +736,25 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
unimplemented!();
|
||||
}
|
||||
|
||||
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> {
|
||||
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
|
||||
let block = self.llbb();
|
||||
let function = block.get_function();
|
||||
// NOTE: instead of returning the dereference here, we have to assign it to a variable in
|
||||
// the current basic block. Otherwise, it could be used in another basic block, causing a
|
||||
// dereference after a drop, for instance.
|
||||
// TODO(antoyo): handle align of the load instruction.
|
||||
let ptr = self.context.new_cast(None, ptr, pointee_ty.make_pointer());
|
||||
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
|
||||
// Ideally, we shouldn't need to do this check.
|
||||
let aligned_type =
|
||||
if pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type {
|
||||
pointee_ty
|
||||
}
|
||||
else {
|
||||
pointee_ty.get_aligned(align.bytes())
|
||||
};
|
||||
let ptr = self.context.new_cast(None, ptr, aligned_type.make_pointer());
|
||||
let deref = ptr.dereference(None).to_rvalue();
|
||||
unsafe { RETURN_VALUE_COUNT += 1 };
|
||||
let loaded_value = function.new_local(None, pointee_ty, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT }));
|
||||
let loaded_value = function.new_local(None, aligned_type, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT }));
|
||||
block.add_assignment(None, loaded_value, deref);
|
||||
loaded_value.to_rvalue()
|
||||
}
|
||||
|
@ -909,7 +934,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
self.context.new_bitcast(None, result, ptr_type)
|
||||
}
|
||||
|
||||
fn inbounds_gep(&mut self, _typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
|
||||
fn inbounds_gep(&mut self, typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
|
||||
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||
let ptr = self.context.new_cast(None, ptr, typ.make_pointer());
|
||||
// NOTE: array indexing is always considered in bounds in GCC (TODO(antoyo): to be verified).
|
||||
let mut indices = indices.into_iter();
|
||||
let index = indices.next().expect("first index in inbounds_gep");
|
||||
|
@ -938,6 +965,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
element.get_address(None)
|
||||
}
|
||||
else if let Some(struct_type) = value_type.is_struct() {
|
||||
// NOTE: due to opaque pointers now being used, we need to bitcast here.
|
||||
let ptr = self.bitcast_if_needed(ptr, value_type.make_pointer());
|
||||
ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
|
||||
}
|
||||
else {
|
||||
|
@ -1356,7 +1385,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
|
||||
fn call(
|
||||
&mut self,
|
||||
_typ: Type<'gcc>,
|
||||
typ: Type<'gcc>,
|
||||
_fn_attrs: Option<&CodegenFnAttrs>,
|
||||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||
func: RValue<'gcc>,
|
||||
|
@ -1370,7 +1399,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
}
|
||||
else {
|
||||
// If it's a not function that was defined, it's a function pointer.
|
||||
self.function_ptr_call(func, args, funclet)
|
||||
self.function_ptr_call(typ, func, args, funclet)
|
||||
};
|
||||
if let Some(_fn_abi) = fn_abi {
|
||||
// TODO(bjorn3): Apply function attributes
|
||||
|
@ -1843,7 +1872,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
|
||||
#[cfg(feature="master")]
|
||||
let (cond, element_type) = {
|
||||
let then_val_vector_type = then_val.get_type().dyncast_vector().expect("vector type");
|
||||
// TODO(antoyo): dyncast_vector should not require a call to unqualified.
|
||||
let then_val_vector_type = then_val.get_type().unqualified().dyncast_vector().expect("vector type");
|
||||
let then_val_element_type = then_val_vector_type.get_element_type();
|
||||
let then_val_element_size = then_val_element_type.get_size();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue