Skip to content

Commit

Permalink
Conform with recent changes in rustc (alloc id, scalar ptr, vtable me…
Browse files Browse the repository at this point in the history
…thod) (#361)

* Refactor for alloc_id iterators

* Access scalar pointer values via `into_parts`

* Trait compile fixes

* Vtable field name workaround

* Remove `unused doc comment` warning
  • Loading branch information
adpaco-aws authored Jul 27, 2021
1 parent 63e39a9 commit 22d72ef
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 47 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_codegen_llvm/src/gotoc/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ impl<'tcx> GotocCtx<'tcx> {
/// functions can share the same name, we need to use the index of the entry in the
/// vtable. This is the same index that will be passed in virtual function calls as
/// InstanceDef::Virtual(def_id, idx). We could use solely the index as a key into
/// the vtable struct, but we add the trait and function names for debugging
/// readability.
/// Example: 3_Shape::vol
pub fn vtable_field_name(&self, def_id: DefId, idx: usize) -> String {
format!("{}_{}", idx, with_no_trimmed_paths(|| self.tcx.def_path_str(def_id)))
/// the vtable struct, but we add the method name for debugging readability.
/// Example: 3_vol
pub fn vtable_field_name(&self, _def_id: DefId, idx: usize) -> String {
// format!("{}_{}", idx, with_no_trimmed_paths(|| self.tcx.item_name(def_id)))
// TODO: use def_id https://github.com/model-checking/rmc/issues/364
idx.to_string()
}

/// A human readable name in Rust for reference, should not be used as a key.
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_codegen_llvm/src/gotoc/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ fn collect_items_rec<'tcx>(
recursion_depth_reset = None;

if let Ok(alloc) = tcx.eval_static_initializer(def_id) {
for &((), id) in alloc.relocations().values() {
for &id in alloc.relocations().values() {
collect_miri(tcx, id, &mut neighbors);
}
}
Expand Down Expand Up @@ -815,16 +815,13 @@ fn create_mono_items_for_vtable_methods<'tcx>(
.iter()
.cloned()
.filter_map(|entry| match entry {
VtblEntry::Method(def_id, substs) => ty::Instance::resolve_for_vtable(
tcx,
ty::ParamEnv::reveal_all(),
def_id,
substs,
),
VtblEntry::Method(instance) => Some(instance),
VtblEntry::MetadataDropInPlace
| VtblEntry::MetadataSize
| VtblEntry::MetadataAlign
| VtblEntry::Vacant => None,
// Super trait vtable entries already handled by now
VtblEntry::TraitVPtr(..) => None,
})
.filter(|&instance| should_codegen_locally(tcx, &instance))
.map(|item| create_fn_mono_item(item, source));
Expand Down Expand Up @@ -1039,7 +1036,7 @@ fn collect_miri<'tcx>(
}
GlobalAlloc::Memory(alloc) => {
trace!("collecting {:?} with {:#?}", alloc_id, alloc);
for &((), inner) in alloc.relocations().values() {
for &inner in alloc.relocations().values() {
rustc_data_structures::stack::ensure_sufficient_stack(|| {
collect_miri(tcx, inner, output);
});
Expand Down Expand Up @@ -1073,9 +1070,12 @@ fn collect_const_value<'tcx>(
output: &mut Vec<Spanned<MonoItem<'tcx>>>,
) {
match value {
ConstValue::Scalar(Scalar::Ptr(ptr)) => collect_miri(tcx, ptr.alloc_id, output),
ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => {
let (alloc_id, _offset) = ptr.into_parts();
collect_miri(tcx, alloc_id, output);
}
ConstValue::Slice { data: alloc, start: _, end: _ } | ConstValue::ByRef { alloc, .. } => {
for &((), id) in alloc.relocations().values() {
for &id in alloc.relocations().values() {
collect_miri(tcx, id, output);
}
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_codegen_llvm/src/gotoc/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,10 @@ impl<'tcx> GotocCtx<'tcx> {
&self.symbol_table,
)
}
(Scalar::Ptr(ptr), _) => {
(Scalar::Ptr(ptr, _size), _) => {
let res_t = self.codegen_ty(ty);
self.codegen_alloc_pointer(res_t, ptr.alloc_id, ptr.offset, span)
let (alloc_id, offset) = ptr.into_parts();
self.codegen_alloc_pointer(res_t, alloc_id, offset, span)
}
_ => unimplemented!(),
}
Expand Down Expand Up @@ -382,7 +383,7 @@ impl<'tcx> GotocCtx<'tcx> {
let pointer_size = self.ptr_width() as usize / 8;

let mut next_offset = 0;
for &(offset, ((), alloc_id)) in alloc.relocations().iter() {
for &(offset, alloc_id) in alloc.relocations().iter() {
let offset = offset.bytes_usize();
if offset > next_offset {
let bytes =
Expand Down
26 changes: 8 additions & 18 deletions compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ use crate::btree_string_map;
use num::bigint::BigInt;
use rustc_middle::mir::{AggregateKind, BinOp, CastKind, NullOp, Operand, Place, Rvalue, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{
self, Binder, GenericParamDefKind, Instance, IntTy, TraitRef, Ty, UintTy, VtblEntry,
COMMON_VTABLE_ENTRIES,
};
use rustc_span::def_id::DefId;
use rustc_middle::ty::{self, Instance, IntTy, Ty, UintTy, VtblEntry, COMMON_VTABLE_ENTRIES};
use rustc_target::abi::{FieldsShape, LayoutOf, Primitive, TagEncoding, Variants};
use tracing::{debug, warn};

Expand Down Expand Up @@ -702,26 +697,18 @@ impl<'tcx> GotocCtx<'tcx> {

fn codegen_vtable_method_field(
&mut self,
def_id: DefId,
substs: ty::subst::SubstsRef<'tcx>,
instance: Instance<'tcx>,
t: Ty<'tcx>,
idx: usize,
) -> Expr {
let vtable_field_name = self.vtable_field_name(def_id, idx);
let vtable_field_name = self.vtable_field_name(instance.def_id(), idx);
let vtable_type_name = aggr_name(&self.vtable_name(t));
let field_type = self
.symbol_table
.lookup_field_type(&vtable_type_name, &vtable_field_name)
.cloned()
.unwrap();

// We use Instance::resolve to more closely match Rust proper behavior. The comment
// there says "used to find the precise code that will run for a trait method invocation"
// and it is used (in a more indirect way) to generate vtables.
let instance = Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
.unwrap()
.unwrap();

// Lookup in the symbol table using the full symbol table name/key
let fn_name = self.symbol_name(instance);
if let Some(fn_symbol) = self.symbol_table.lookup(&fn_name) {
Expand Down Expand Up @@ -858,8 +845,11 @@ impl<'tcx> GotocCtx<'tcx> {
VtblEntry::MetadataSize => Some(vt_size.clone()),
VtblEntry::MetadataAlign => Some(vt_align.clone()),
VtblEntry::Vacant => None,
VtblEntry::Method(def_id, substs) => {
Some(ctx.codegen_vtable_method_field(*def_id, substs, trait_type, idx))
// TODO: trait upcasting
// https://github.com/model-checking/rmc/issues/358
VtblEntry::TraitVPtr(_trait_ref) => None,
VtblEntry::Method(instance) => {
Some(ctx.codegen_vtable_method_field(*instance, trait_type, idx))
}
})
.collect();
Expand Down
25 changes: 14 additions & 11 deletions compiler/rustc_codegen_llvm/src/gotoc/typ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_index::vec::IndexVec;
use rustc_middle::mir::{HasLocalDecls, Local};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::print::FmtPrinter;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{
self, AdtDef, FloatTy, Instance, IntTy, PolyFnSig, Ty, TyS, UintTy, VariantDef, VtblEntry,
};
Expand Down Expand Up @@ -117,22 +117,17 @@ impl<'tcx> GotocCtx<'tcx> {
/// In particular, these fields are function pointers.
fn trait_method_vtable_field_type(
&mut self,
def_id: DefId,
substs: SubstsRef<'tcx>,
instance: Instance<'tcx>,
idx: usize,
) -> DatatypeComponent {
let instance = Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
.unwrap()
.unwrap();

// gives a binder with function signature
let sig = self.fn_sig_of_instance(instance);

// gives an Irep Pointer object for the signature
let fnptr = self.codegen_dynamic_function_sig(sig).to_pointer();

// vtable field name, i.e., 3_Shape::vol (idx_Trait::method)
let vtable_field_name = self.vtable_field_name(def_id, idx);
// vtable field name, i.e., 3_vol (idx_method)
let vtable_field_name = self.vtable_field_name(instance.def_id(), idx);

let ins_ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
let _layout = self.layout_of(ins_ty);
Expand Down Expand Up @@ -198,9 +193,12 @@ impl<'tcx> GotocCtx<'tcx> {
.cloned()
.enumerate()
.filter_map(|(idx, entry)| match entry {
VtblEntry::Method(def_id, substs) => {
Some(self.trait_method_vtable_field_type(def_id, substs, idx))
VtblEntry::Method(instance) => {
Some(self.trait_method_vtable_field_type(instance, idx))
}
// TODO: trait upcasting
// https://github.com/model-checking/rmc/issues/358
VtblEntry::TraitVPtr(..) => None,
VtblEntry::MetadataDropInPlace
| VtblEntry::MetadataSize
| VtblEntry::MetadataAlign
Expand All @@ -225,6 +223,11 @@ impl<'tcx> GotocCtx<'tcx> {

/// Gives the vtable name for a type.
/// In some cases, we have &T, in other cases T, so normalize.
///
/// TODO: to handle trait upcasting, this will need to use a
/// poly existential trait type as a part of the key as well.
/// See compiler/rustc_middle/src/ty/vtable.rs
/// https://github.com/model-checking/rmc/issues/358
pub fn vtable_name(&self, t: Ty<'tcx>) -> String {
self.normalized_trait_name(t) + "::vtable"
}
Expand Down

0 comments on commit 22d72ef

Please sign in to comment.