mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #65340 - bjorn3:cg_ssa_refactor4, r=eddyb
Several changes to the codegen backend organization * Split functions from values in cg_ssa `BackendTypes`. * Remove `is_const_integral` function from `ConstMethods`. * Actually register the invalid monomorphization of intrinsic long diagnostic and remove the `diagnostics` method from `CodegenBackends`, as it was unused. * Add cg_ssa and cg_utils provided methods to `default_provide`, so codegen backend don't have to do it themself.
This commit is contained in:
commit
6241a4a108
@ -52,6 +52,7 @@ const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr();
|
||||
|
||||
impl BackendTypes for Builder<'_, 'll, 'tcx> {
|
||||
type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
|
||||
type Function = <CodegenCx<'ll, 'tcx> as BackendTypes>::Function;
|
||||
type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
|
||||
type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
|
||||
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
|
||||
|
@ -33,7 +33,7 @@ pub fn get_fn(
|
||||
assert!(!instance.substs.has_param_types());
|
||||
|
||||
let sig = instance.fn_sig(cx.tcx());
|
||||
if let Some(&llfn) = cx.instances().borrow().get(&instance) {
|
||||
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
|
||||
return llfn;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
//! Code that is useful in various codegen modules.
|
||||
|
||||
use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef};
|
||||
use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef, ConstantInt};
|
||||
use crate::abi;
|
||||
use crate::consts;
|
||||
use crate::type_::Type;
|
||||
@ -86,6 +86,8 @@ impl Funclet<'ll> {
|
||||
|
||||
impl BackendTypes for CodegenCx<'ll, 'tcx> {
|
||||
type Value = &'ll Value;
|
||||
type Function = &'ll Value;
|
||||
|
||||
type BasicBlock = &'ll BasicBlock;
|
||||
type Type = &'ll Type;
|
||||
type Funclet = Funclet<'ll>;
|
||||
@ -243,33 +245,23 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
struct_in_context(self.llcx, elts, packed)
|
||||
}
|
||||
|
||||
fn const_to_uint(&self, v: &'ll Value) -> u64 {
|
||||
unsafe {
|
||||
fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
|
||||
try_as_const_integral(v).map(|v| unsafe {
|
||||
llvm::LLVMConstIntGetZExtValue(v)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_const_integral(&self, v: &'ll Value) -> bool {
|
||||
unsafe {
|
||||
llvm::LLVMIsAConstantInt(v).is_some()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
|
||||
unsafe {
|
||||
if self.is_const_integral(v) {
|
||||
let (mut lo, mut hi) = (0u64, 0u64);
|
||||
let success = llvm::LLVMRustConstInt128Get(v, sign_ext,
|
||||
&mut hi, &mut lo);
|
||||
if success {
|
||||
Some(hi_lo_to_u128(lo, hi))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
try_as_const_integral(v).and_then(|v| unsafe {
|
||||
let (mut lo, mut hi) = (0u64, 0u64);
|
||||
let success = llvm::LLVMRustConstInt128Get(v, sign_ext,
|
||||
&mut hi, &mut lo);
|
||||
if success {
|
||||
Some(hi_lo_to_u128(lo, hi))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn scalar_to_backend(
|
||||
@ -305,7 +297,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
Some(GlobalAlloc::Function(fn_instance)) => {
|
||||
self.get_fn(fn_instance)
|
||||
self.get_fn_addr(fn_instance)
|
||||
}
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
assert!(self.tcx.is_static(def_id));
|
||||
@ -386,3 +378,9 @@ pub fn struct_in_context(
|
||||
fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 {
|
||||
((hi as u128) << 64) | (lo as u128)
|
||||
}
|
||||
|
||||
fn try_as_const_integral(v: &'ll Value) -> Option<&'ll ConstantInt> {
|
||||
unsafe {
|
||||
llvm::LLVMIsAConstantInt(v)
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ use rustc::ty::layout::{
|
||||
use rustc::ty::{self, Ty, TyCtxt, Instance};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
use rustc_codegen_ssa::callee::resolve_and_get_fn;
|
||||
use rustc_codegen_ssa::base::wants_msvc_seh;
|
||||
use crate::callee::get_fn;
|
||||
|
||||
@ -327,11 +326,11 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
&self.vtables
|
||||
}
|
||||
|
||||
fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, &'ll Value>> {
|
||||
&self.instances
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
|
||||
get_fn(self, instance)
|
||||
}
|
||||
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
|
||||
fn get_fn_addr(&self, instance: Instance<'tcx>) -> &'ll Value {
|
||||
get_fn(self, instance)
|
||||
}
|
||||
|
||||
@ -362,7 +361,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let llfn = match tcx.lang_items().eh_personality() {
|
||||
Some(def_id) if !wants_msvc_seh(self.sess()) => {
|
||||
resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]))
|
||||
self.get_fn_addr(
|
||||
ty::Instance::resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
tcx.intern_substs(&[]),
|
||||
).unwrap()
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let name = if wants_msvc_seh(self.sess()) {
|
||||
@ -390,7 +396,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
assert!(self.sess().target.target.options.custom_unwind_resume);
|
||||
if let Some(def_id) = tcx.lang_items().eh_unwind_resume() {
|
||||
let llfn = resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]));
|
||||
let llfn = self.get_fn_addr(
|
||||
ty::Instance::resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
tcx.intern_substs(&[]),
|
||||
).unwrap()
|
||||
);
|
||||
unwresume.set(Some(llfn));
|
||||
return llfn;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
register_diagnostics! {
|
||||
|
||||
E0511: r##"
|
||||
Invalid monomorphization of an intrinsic function was used. Erroneous code
|
||||
example:
|
||||
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { simd_add(0, 1); }
|
||||
// error: invalid monomorphization of `simd_add` intrinsic
|
||||
}
|
||||
```
|
||||
|
||||
The generic type has to be a SIMD type. Example:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct i32x2(i32, i32);
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
@ -20,9 +20,9 @@ use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
use rustc::hir;
|
||||
use syntax::ast::{self, FloatTy};
|
||||
|
||||
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
||||
use rustc::session::Session;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
@ -1026,10 +1026,6 @@ fn get_rust_try_fn<'ll, 'tcx>(
|
||||
rust_try
|
||||
}
|
||||
|
||||
fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
|
||||
span_err!(a, b, E0511, "{}", c);
|
||||
}
|
||||
|
||||
fn generic_simd_intrinsic(
|
||||
bx: &mut Builder<'a, 'll, 'tcx>,
|
||||
name: &str,
|
||||
|
@ -38,7 +38,7 @@ extern crate rustc_fs_util;
|
||||
extern crate rustc_driver as _;
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_errors as errors;
|
||||
|
||||
@ -64,8 +64,6 @@ use rustc::util::common::ErrorReported;
|
||||
use rustc_codegen_ssa::ModuleCodegen;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
|
||||
mod error_codes;
|
||||
|
||||
mod back {
|
||||
pub mod archive;
|
||||
pub mod bytecode;
|
||||
@ -258,10 +256,6 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
llvm_util::print_version();
|
||||
}
|
||||
|
||||
fn diagnostics(&self) -> &[(&'static str, &'static str)] {
|
||||
&error_codes::DIAGNOSTICS
|
||||
}
|
||||
|
||||
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
|
||||
target_features(sess)
|
||||
}
|
||||
@ -271,15 +265,10 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
}
|
||||
|
||||
fn provide(&self, providers: &mut ty::query::Providers<'_>) {
|
||||
rustc_codegen_utils::symbol_names::provide(providers);
|
||||
rustc_codegen_ssa::back::symbol_export::provide(providers);
|
||||
rustc_codegen_ssa::base::provide_both(providers);
|
||||
attributes::provide(providers);
|
||||
}
|
||||
|
||||
fn provide_extern(&self, providers: &mut ty::query::Providers<'_>) {
|
||||
rustc_codegen_ssa::back::symbol_export::provide_extern(providers);
|
||||
rustc_codegen_ssa::base::provide_both(providers);
|
||||
attributes::provide_extern(providers);
|
||||
}
|
||||
|
||||
|
@ -510,6 +510,7 @@ extern { pub type Module; }
|
||||
extern { pub type Context; }
|
||||
extern { pub type Type; }
|
||||
extern { pub type Value; }
|
||||
extern { pub type ConstantInt; }
|
||||
extern { pub type Metadata; }
|
||||
extern { pub type BasicBlock; }
|
||||
#[repr(C)]
|
||||
@ -719,8 +720,8 @@ extern "C" {
|
||||
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
|
||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
|
||||
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
|
||||
pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
|
||||
pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
|
||||
pub fn LLVMConstIntGetZExtValue(ConstantVal: &ConstantInt) -> c_ulonglong;
|
||||
pub fn LLVMRustConstInt128Get(ConstantVal: &ConstantInt, SExt: bool,
|
||||
high: &mut u64, low: &mut u64) -> bool;
|
||||
|
||||
|
||||
@ -1666,7 +1667,7 @@ extern "C" {
|
||||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
|
||||
|
||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>;
|
||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
|
||||
|
||||
pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
|
||||
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
|
||||
|
@ -84,7 +84,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
{
|
||||
fn new_block<'b>(
|
||||
cx: &'a Self::CodegenCx,
|
||||
llfn: Self::Value,
|
||||
llfn: Self::Function,
|
||||
name: &'b str
|
||||
) -> Self;
|
||||
/* ... */
|
||||
|
@ -36,7 +36,6 @@ use crate::mir::place::PlaceRef;
|
||||
use crate::back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm,
|
||||
submit_post_lto_module_to_llvm};
|
||||
use crate::{MemFlags, CrateInfo};
|
||||
use crate::callee;
|
||||
use crate::common::{RealPredicate, TypeKind, IntPredicate};
|
||||
use crate::meth;
|
||||
use crate::mir;
|
||||
@ -377,8 +376,7 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
let sig = instance.fn_sig(cx.tcx());
|
||||
let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
||||
|
||||
let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(||
|
||||
bug!("Instance `{:?}` not already declared", instance));
|
||||
let lldecl = cx.get_fn(instance);
|
||||
|
||||
let mir = cx.tcx().instance_mir(instance.def);
|
||||
mir::codegen_mir::<Bx>(cx, lldecl, &mir, instance, sig);
|
||||
@ -400,7 +398,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
||||
return;
|
||||
}
|
||||
|
||||
let main_llfn = cx.get_fn(instance);
|
||||
let main_llfn = cx.get_fn_addr(instance);
|
||||
|
||||
let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
|
||||
match et {
|
||||
@ -455,10 +453,13 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
||||
|
||||
let (start_fn, args) = if use_start_lang_item {
|
||||
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
|
||||
let start_fn = callee::resolve_and_get_fn(
|
||||
cx,
|
||||
start_def_id,
|
||||
cx.tcx().intern_substs(&[main_ret_ty.into()]),
|
||||
let start_fn = cx.get_fn_addr(
|
||||
ty::Instance::resolve(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
cx.tcx().intern_substs(&[main_ret_ty.into()]),
|
||||
).unwrap()
|
||||
);
|
||||
(start_fn, vec![bx.pointercast(rust_main, cx.type_ptr_to(cx.type_i8p())),
|
||||
arg_argc, arg_argv])
|
||||
|
@ -1,53 +0,0 @@
|
||||
use crate::traits::*;
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
||||
pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||
cx: &Cx,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Cx::Value {
|
||||
cx.get_fn(
|
||||
ty::Instance::resolve(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs
|
||||
).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn resolve_and_get_fn_for_ptr<'tcx,
|
||||
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
|
||||
>(
|
||||
cx: &Cx,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Cx::Value {
|
||||
cx.get_fn(
|
||||
ty::Instance::resolve_for_fn_ptr(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs
|
||||
).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn resolve_and_get_fn_for_vtable<'tcx,
|
||||
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
|
||||
>(
|
||||
cx: &Cx,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Cx::Value {
|
||||
cx.get_fn(
|
||||
ty::Instance::resolve_for_vtable(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs
|
||||
).unwrap()
|
||||
)
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#![allow(non_camel_case_types, non_snake_case)]
|
||||
|
||||
use rustc::ty::{Ty, TyCtxt};
|
||||
use rustc::session::Session;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
@ -200,3 +201,7 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
_ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
|
||||
span_err!(a, b, E0511, "{}", c);
|
||||
}
|
||||
|
@ -1,5 +1,40 @@
|
||||
syntax::register_diagnostics! {
|
||||
|
||||
E0511: r##"
|
||||
Invalid monomorphization of an intrinsic function was used. Erroneous code
|
||||
example:
|
||||
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { simd_add(0, 1); }
|
||||
// error: invalid monomorphization of `simd_add` intrinsic
|
||||
}
|
||||
```
|
||||
|
||||
The generic type has to be a SIMD type. Example:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct i32x2(i32, i32);
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0668: r##"
|
||||
Malformed inline assembly rejected by LLVM.
|
||||
|
||||
|
@ -27,6 +27,7 @@ use rustc::dep_graph::WorkProduct;
|
||||
use rustc::session::config::{OutputFilenames, OutputType};
|
||||
use rustc::middle::lang_items::LangItem;
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
@ -41,7 +42,6 @@ pub mod traits;
|
||||
pub mod mir;
|
||||
pub mod debuginfo;
|
||||
pub mod base;
|
||||
pub mod callee;
|
||||
pub mod glue;
|
||||
pub mod meth;
|
||||
pub mod mono_item;
|
||||
@ -156,3 +156,13 @@ pub struct CodegenResults {
|
||||
pub linker_info: back::linker::LinkerInfo,
|
||||
pub crate_info: CrateInfo,
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers<'_>) {
|
||||
crate::back::symbol_export::provide(providers);
|
||||
crate::base::provide_both(providers);
|
||||
}
|
||||
|
||||
pub fn provide_extern(providers: &mut Providers<'_>) {
|
||||
crate::back::symbol_export::provide_extern(providers);
|
||||
crate::base::provide_both(providers);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use rustc_target::abi::call::FnType;
|
||||
|
||||
use crate::callee;
|
||||
use crate::traits::*;
|
||||
|
||||
use rustc::ty::{self, Ty, Instance};
|
||||
@ -92,7 +91,14 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||
|
||||
let methods = methods.cloned().map(|opt_mth| {
|
||||
opt_mth.map_or(nullptr, |(def_id, substs)| {
|
||||
callee::resolve_and_get_fn_for_vtable(cx, def_id, substs)
|
||||
cx.get_fn_addr(
|
||||
ty::Instance::resolve_for_vtable(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
).unwrap()
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
@ -102,7 +108,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||
// `get_vtable` in rust_mir/interpret/traits.rs
|
||||
// /////////////////////////////////////////////////////////////////////////////////////////////
|
||||
let components: Vec<_> = [
|
||||
cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)),
|
||||
cx.get_fn_addr(Instance::resolve_drop_in_place(cx.tcx(), ty)),
|
||||
cx.const_usize(layout.size.bytes()),
|
||||
cx.const_usize(layout.align.abi.bytes())
|
||||
].iter().cloned().chain(methods).collect();
|
||||
|
@ -358,7 +358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
(meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty)
|
||||
}
|
||||
_ => {
|
||||
(bx.get_fn(drop_fn),
|
||||
(bx.get_fn_addr(drop_fn),
|
||||
FnType::of_instance(&bx, drop_fn))
|
||||
}
|
||||
};
|
||||
@ -460,7 +460,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let fn_ty = FnType::of_instance(&bx, instance);
|
||||
let llfn = bx.get_fn(instance);
|
||||
let llfn = bx.get_fn_addr(instance);
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
helper.do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup);
|
||||
@ -576,7 +576,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let fn_ty = FnType::of_instance(&bx, instance);
|
||||
let llfn = bx.get_fn(instance);
|
||||
let llfn = bx.get_fn_addr(instance);
|
||||
|
||||
if let Some((_, target)) = destination.as_ref() {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
|
||||
@ -793,7 +793,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
let fn_ptr = match (llfn, instance) {
|
||||
(Some(llfn), _) => llfn,
|
||||
(None, Some(instance)) => bx.get_fn(instance),
|
||||
(None, Some(instance)) => bx.get_fn_addr(instance),
|
||||
_ => span_bug!(span, "no llfn for call"),
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
||||
|
||||
debug_context: FunctionDebugContext<Bx::DIScope>,
|
||||
|
||||
llfn: Bx::Value,
|
||||
llfn: Bx::Function,
|
||||
|
||||
cx: &'a Bx::CodegenCx,
|
||||
|
||||
@ -183,7 +183,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
|
||||
|
||||
pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
cx: &'a Bx::CodegenCx,
|
||||
llfn: Bx::Value,
|
||||
llfn: Bx::Function,
|
||||
mir: &'a Body<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
|
@ -394,8 +394,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
||||
// Statically compute the offset if we can, otherwise just use the element size,
|
||||
// as this will yield the lowest alignment.
|
||||
let layout = self.layout.field(bx, 0);
|
||||
let offset = if bx.is_const_integral(llindex) {
|
||||
layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
|
||||
let offset = if let Some(llindex) = bx.const_to_opt_uint(llindex) {
|
||||
layout.size.checked_mul(llindex, bx).unwrap_or(layout.size)
|
||||
} else {
|
||||
layout.size
|
||||
};
|
||||
|
@ -10,7 +10,6 @@ use syntax::source_map::{DUMMY_SP, Span};
|
||||
|
||||
use crate::base;
|
||||
use crate::MemFlags;
|
||||
use crate::callee;
|
||||
use crate::common::{self, RealPredicate, IntPredicate};
|
||||
|
||||
use crate::traits::*;
|
||||
@ -95,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let size = bx.const_usize(dest.layout.size.bytes());
|
||||
|
||||
// Use llvm.memset.p0i8.* to initialize all zero arrays
|
||||
if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 {
|
||||
if bx.cx().const_to_opt_uint(v) == Some(0) {
|
||||
let fill = bx.cx().const_u8(0);
|
||||
bx.memset(start, fill, size, dest.align, MemFlags::empty());
|
||||
return bx;
|
||||
@ -190,7 +189,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bug!("reifying a fn ptr that requires const arguments");
|
||||
}
|
||||
OperandValue::Immediate(
|
||||
callee::resolve_and_get_fn_for_ptr(bx.cx(), def_id, substs))
|
||||
bx.get_fn_addr(
|
||||
ty::Instance::resolve_for_fn_ptr(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs
|
||||
).unwrap()
|
||||
)
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
bug!("{} cannot be reified to a fn ptr", operand.layout.ty)
|
||||
@ -205,7 +212,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
def_id,
|
||||
substs,
|
||||
ty::ClosureKind::FnOnce);
|
||||
OperandValue::Immediate(bx.cx().get_fn(instance))
|
||||
OperandValue::Immediate(bx.cx().get_fn_addr(instance))
|
||||
}
|
||||
_ => {
|
||||
bug!("{} cannot be cast to a fn ptr", operand.layout.ty)
|
||||
@ -488,7 +495,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
};
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let r = bx.cx().get_fn(instance);
|
||||
let r = bx.cx().get_fn_addr(instance);
|
||||
let call = bx.call(r, &[llsize, llalign], None);
|
||||
let val = bx.pointercast(call, llty_ptr);
|
||||
|
||||
|
@ -14,6 +14,8 @@ use syntax_pos::symbol::InternedString;
|
||||
|
||||
pub trait BackendTypes {
|
||||
type Value: CodegenObject;
|
||||
type Function: CodegenObject;
|
||||
|
||||
type BasicBlock: Copy;
|
||||
type Type: CodegenObject;
|
||||
type Funclet;
|
||||
|
@ -34,7 +34,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
+ HasTargetSpec
|
||||
|
||||
{
|
||||
fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
|
||||
fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self;
|
||||
fn with_cx(cx: &'a Self::CodegenCx) -> Self;
|
||||
fn build_sibling_block(&self, name: &str) -> Self;
|
||||
fn cx(&self) -> &Self::CodegenCx;
|
||||
|
@ -21,11 +21,9 @@ pub trait ConstMethods<'tcx>: BackendTypes {
|
||||
|
||||
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
|
||||
|
||||
fn const_to_uint(&self, v: Self::Value) -> u64;
|
||||
fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
|
||||
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
|
||||
|
||||
fn is_const_integral(&self, v: Self::Value) -> bool;
|
||||
|
||||
fn scalar_to_backend(
|
||||
&self,
|
||||
cv: Scalar,
|
||||
|
@ -20,7 +20,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
|
||||
&self,
|
||||
instance: Instance<'tcx>,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
llfn: Self::Value,
|
||||
llfn: Self::Function,
|
||||
mir: &mir::Body<'_>,
|
||||
) -> FunctionDebugContext<Self::DIScope>;
|
||||
|
||||
|
@ -17,13 +17,13 @@ pub trait DeclareMethods<'tcx>: BackendTypes {
|
||||
///
|
||||
/// If there’s a value with the same name already declared, the function will
|
||||
/// update the declaration and return existing Value instead.
|
||||
fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Value;
|
||||
fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function;
|
||||
|
||||
/// Declare a Rust function.
|
||||
///
|
||||
/// If there’s a value with the same name already declared, the function will
|
||||
/// update the declaration and return existing Value instead.
|
||||
fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Value;
|
||||
fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Function;
|
||||
|
||||
/// Declare a global with an intention to define it.
|
||||
///
|
||||
|
@ -11,14 +11,14 @@ pub trait MiscMethods<'tcx>: BackendTypes {
|
||||
&self,
|
||||
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
|
||||
fn check_overflow(&self) -> bool;
|
||||
fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, Self::Value>>;
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function;
|
||||
fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value;
|
||||
fn eh_personality(&self) -> Self::Value;
|
||||
fn eh_unwind_resume(&self) -> Self::Value;
|
||||
fn sess(&self) -> &Session;
|
||||
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
|
||||
fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
|
||||
fn set_frame_pointer_elimination(&self, llfn: Self::Value);
|
||||
fn apply_target_cpu_attr(&self, llfn: Self::Value);
|
||||
fn set_frame_pointer_elimination(&self, llfn: Self::Function);
|
||||
fn apply_target_cpu_attr(&self, llfn: Self::Function);
|
||||
fn create_used_variable(&self);
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ pub trait HasCodegen<'tcx>:
|
||||
type CodegenCx: CodegenMethods<'tcx>
|
||||
+ BackendTypes<
|
||||
Value = Self::Value,
|
||||
Function = Self::Function,
|
||||
BasicBlock = Self::BasicBlock,
|
||||
Type = Self::Type,
|
||||
Funclet = Self::Funclet,
|
||||
|
@ -25,7 +25,6 @@ pub trait CodegenBackend {
|
||||
fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
|
||||
fn print_passes(&self) {}
|
||||
fn print_version(&self) {}
|
||||
fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
|
||||
|
||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
|
||||
fn provide(&self, _providers: &mut Providers<'_>);
|
||||
|
@ -18,6 +18,7 @@
|
||||
extern crate rustc;
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use syntax::symbol::sym;
|
||||
|
||||
@ -37,3 +38,7 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers<'_>) {
|
||||
crate::symbol_names::provide(providers);
|
||||
}
|
||||
|
@ -791,10 +791,13 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
|
||||
cstore::provide(providers);
|
||||
lint::provide(providers);
|
||||
rustc_lint::provide(providers);
|
||||
rustc_codegen_utils::provide(providers);
|
||||
rustc_codegen_ssa::provide(providers);
|
||||
}
|
||||
|
||||
pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) {
|
||||
cstore::provide_extern(providers);
|
||||
rustc_codegen_ssa::provide_extern(providers);
|
||||
}
|
||||
|
||||
declare_box_region_type!(
|
||||
|
Loading…
Reference in New Issue
Block a user