Skip to content

Commit b52522a

Browse files
committed
Auto merge of #69749 - davidtwco:issue-46477-polymorphization, r=eddyb
Polymorphization This PR implements an analysis to detect when functions could remain polymorphic during code generation. Fixes #46477 r? @eddyb cc @rust-lang/wg-mir-opt @nikomatsakis @pnkfelix
2 parents 734233d + 4b99699 commit b52522a

File tree

67 files changed

+2034
-191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2034
-191
lines changed

src/librustc_codegen_llvm/callee.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use log::debug;
1313
use rustc_codegen_ssa::traits::*;
1414

1515
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
16-
use rustc_middle::ty::{Instance, TypeFoldable};
16+
use rustc_middle::ty::{self, Instance, TypeFoldable};
1717

1818
/// Codegens a reference to a fn/method item, monomorphizing and
1919
/// inlining as it goes.
@@ -29,14 +29,18 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
2929

3030
assert!(!instance.substs.needs_infer());
3131
assert!(!instance.substs.has_escaping_bound_vars());
32-
assert!(!instance.substs.has_param_types_or_consts());
3332

3433
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
3534
return llfn;
3635
}
3736

3837
let sym = tcx.symbol_name(instance).name;
39-
debug!("get_fn({:?}: {:?}) => {}", instance, instance.monomorphic_ty(cx.tcx()), sym);
38+
debug!(
39+
"get_fn({:?}: {:?}) => {}",
40+
instance,
41+
instance.ty(cx.tcx(), ty::ParamEnv::reveal_all()),
42+
sym
43+
);
4044

4145
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
4246

src/librustc_codegen_llvm/consts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ impl CodegenCx<'ll, 'tcx> {
203203
def_id
204204
);
205205

206-
let ty = instance.monomorphic_ty(self.tcx);
206+
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
207207
let sym = self.tcx.symbol_name(instance).name;
208208

209209
debug!("get_static: sym={} instance={:?}", sym, instance);
@@ -361,7 +361,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
361361
};
362362

363363
let instance = Instance::mono(self.tcx, def_id);
364-
let ty = instance.monomorphic_ty(self.tcx);
364+
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
365365
let llty = self.layout_of(ty).llvm_type(self);
366366
let g = if val_llty == llty {
367367
g

src/librustc_codegen_llvm/debuginfo/metadata.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,8 @@ pub fn type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, usage_site_span: Sp
700700
prepare_tuple_metadata(cx, t, &tys, unique_type_id, usage_site_span, NO_SCOPE_METADATA)
701701
.finalize(cx)
702702
}
703+
// Type parameters from polymorphized functions.
704+
ty::Param(_) => MetadataCreationResult::new(param_type_metadata(cx, t), false),
703705
_ => bug!("debuginfo: unexpected type in type_metadata: {:?}", t),
704706
};
705707

@@ -955,6 +957,20 @@ fn pointer_type_metadata(
955957
}
956958
}
957959

960+
fn param_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
961+
debug!("param_type_metadata: {:?}", t);
962+
let name = format!("{:?}", t);
963+
return unsafe {
964+
llvm::LLVMRustDIBuilderCreateBasicType(
965+
DIB(cx),
966+
name.as_ptr().cast(),
967+
name.len(),
968+
Size::ZERO.bits(),
969+
DW_ATE_unsigned,
970+
)
971+
};
972+
}
973+
958974
pub fn compile_unit_metadata(
959975
tcx: TyCtxt<'_>,
960976
codegen_unit_name: &str,
@@ -2465,7 +2481,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
24652481
};
24662482

24672483
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
2468-
let variable_type = Instance::mono(cx.tcx, def_id).monomorphic_ty(cx.tcx);
2484+
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
24692485
let type_metadata = type_metadata(cx, variable_type, span);
24702486
let var_name = tcx.item_name(def_id).as_str();
24712487
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;

src/librustc_codegen_llvm/debuginfo/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_index::vec::IndexVec;
2626
use rustc_middle::mir;
2727
use rustc_middle::ty::layout::HasTyCtxt;
2828
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
29-
use rustc_middle::ty::{self, Instance, ParamEnv, Ty};
29+
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeFoldable};
3030
use rustc_session::config::{self, DebugInfo};
3131
use rustc_span::symbol::Symbol;
3232
use rustc_span::{self, BytePos, Span};
@@ -470,7 +470,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
470470
match impl_self_ty.kind {
471471
ty::Adt(def, ..) if !def.is_box() => {
472472
// Again, only create type information if full debuginfo is enabled
473-
if cx.sess().opts.debuginfo == DebugInfo::Full {
473+
if cx.sess().opts.debuginfo == DebugInfo::Full
474+
&& !impl_self_ty.needs_subst()
475+
{
474476
Some(type_metadata(cx, impl_self_ty, rustc_span::DUMMY_SP))
475477
} else {
476478
Some(namespace::item_namespace(cx, def.did))

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
160160
caller_instance: ty::Instance<'tcx>,
161161
) {
162162
let tcx = self.tcx;
163-
let callee_ty = instance.monomorphic_ty(tcx);
163+
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
164164

165165
let (def_id, substs) = match callee_ty.kind {
166166
ty::FnDef(def_id, substs) => (def_id, substs),

src/librustc_codegen_llvm/mono_item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1010
pub use rustc_middle::mir::mono::MonoItem;
1111
use rustc_middle::mir::mono::{Linkage, Visibility};
1212
use rustc_middle::ty::layout::FnAbiExt;
13-
use rustc_middle::ty::{Instance, TypeFoldable};
13+
use rustc_middle::ty::{self, Instance, TypeFoldable};
1414
use rustc_target::abi::LayoutOf;
1515

1616
impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@@ -22,7 +22,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
2222
symbol_name: &str,
2323
) {
2424
let instance = Instance::mono(self.tcx, def_id);
25-
let ty = instance.monomorphic_ty(self.tcx);
25+
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
2626
let llty = self.layout_of(ty).llvm_type(self);
2727

2828
let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
@@ -47,7 +47,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
4747
visibility: Visibility,
4848
symbol_name: &str,
4949
) {
50-
assert!(!instance.substs.needs_infer() && !instance.substs.has_param_types_or_consts());
50+
assert!(!instance.substs.needs_infer());
5151

5252
let fn_abi = FnAbi::of_instance(self, instance, &[]);
5353
let lldecl = self.declare_fn(symbol_name, &fn_abi);

src/librustc_codegen_ssa/debuginfo/type_names.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,17 @@ pub fn push_debuginfo_type_name<'tcx>(
205205
tcx.def_key(def_id).disambiguated_data.disambiguator
206206
));
207207
}
208+
// Type parameters from polymorphized functions.
209+
ty::Param(_) => {
210+
output.push_str(&format!("{:?}", t));
211+
}
208212
ty::Error(_)
209213
| ty::Infer(_)
210214
| ty::Placeholder(..)
211215
| ty::Projection(..)
212216
| ty::Bound(..)
213217
| ty::Opaque(..)
214-
| ty::GeneratorWitness(..)
215-
| ty::Param(_) => {
218+
| ty::GeneratorWitness(..) => {
216219
bug!(
217220
"debuginfo: Trying to create type name for \
218221
unexpected type: {:?}",

src/librustc_codegen_ssa/meth.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
9494
def_id,
9595
substs,
9696
)
97-
.unwrap(),
97+
.unwrap()
98+
.polymorphize(cx.tcx()),
9899
)
99100
})
100101
});

src/librustc_codegen_ssa/mir/analyze.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
124124
let base_ty = self.fx.monomorphize(&base_ty);
125125

126126
// ZSTs don't require any actual memory access.
127-
let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty;
128-
let elem_ty = self.fx.monomorphize(&elem_ty);
127+
let elem_ty = base_ty.projection_ty(cx.tcx(), self.fx.monomorphize(&elem)).ty;
129128
let span = self.fx.mir.local_decls[place_ref.local].source_info.span;
130129
if cx.spanned_layout_of(elem_ty, span).is_zst() {
131130
return;

src/librustc_codegen_ssa/mir/block.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
543543
Some(
544544
ty::Instance::resolve(bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs)
545545
.unwrap()
546-
.unwrap(),
546+
.unwrap()
547+
.polymorphize(bx.tcx()),
547548
),
548549
None,
549550
),

0 commit comments

Comments
 (0)