Remove const_{cstr,str_slice,get_elt,get_real} and is_const_real methods from cg_ssa

This introduces the static_panic_msg trait method to StaticBuilderMethods.
This commit is contained in:
bjorn3 2018-12-02 16:53:39 +01:00
parent a3fa1161d2
commit 7b94195c22
5 changed files with 126 additions and 108 deletions

View File

@ -5,6 +5,7 @@ use crate::context::CodegenCx;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use syntax::symbol::LocalInternedString;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
use rustc_codegen_ssa::MemFlags;
use libc::{c_uint, c_char};
@ -1475,6 +1476,36 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
// Forward to the `get_static` method of `CodegenCx`
self.cx().get_static(def_id)
}
fn static_panic_msg(
&mut self,
msg: Option<LocalInternedString>,
filename: LocalInternedString,
line: Self::Value,
col: Self::Value,
kind: &str,
) -> Self::Value {
let align = self.tcx.data_layout.aggregate_align.abi
.max(self.tcx.data_layout.i32_align.abi)
.max(self.tcx.data_layout.pointer_align.abi);
let filename = self.const_str_slice(filename);
let with_msg_components;
let without_msg_components;
let components = if let Some(msg) = msg {
let msg = self.const_str_slice(msg);
with_msg_components = [msg, filename, line, col];
&with_msg_components as &[_]
} else {
without_msg_components = [filename, line, col];
&without_msg_components as &[_]
};
let struct_ = self.const_struct(&components, false);
self.static_addr_of(struct_, align, Some(kind))
}
}
impl Builder<'a, 'll, 'tcx> {

View File

@ -119,6 +119,72 @@ impl CodegenCx<'ll, 'tcx> {
pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
bytes_in_context(self.llcx, bytes)
}
fn const_cstr(
&self,
s: LocalInternedString,
null_terminated: bool,
) -> &'ll Value {
unsafe {
if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) {
return llval;
}
let sc = llvm::LLVMConstStringInContext(self.llcx,
s.as_ptr() as *const c_char,
s.len() as c_uint,
!null_terminated as Bool);
let sym = self.generate_local_symbol_name("str");
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", sym);
});
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
self.const_cstr_cache.borrow_mut().insert(s, g);
g
}
}
pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
let len = s.len();
let cs = consts::ptrcast(self.const_cstr(s, false),
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
self.const_fat_ptr(cs, self.const_usize(len as u64))
}
pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
unsafe {
assert_eq!(idx as c_uint as u64, idx);
let us = &[idx as c_uint];
let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
debug!("const_get_elt(v={:?}, idx={}, r={:?})",
v, idx, r);
r
}
}
pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
unsafe {
if self.is_const_real(v) {
let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
let loses_info = if loses_info == 1 { true } else { false };
Some((r, loses_info))
} else {
None
}
}
}
fn is_const_real(&self, v: &'ll Value) -> bool {
unsafe {
llvm::LLVMIsAConstantFP(v).is_some()
}
}
}
impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@ -183,40 +249,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.const_uint(self.type_i8(), i as u64)
}
fn const_cstr(
&self,
s: LocalInternedString,
null_terminated: bool,
) -> &'ll Value {
unsafe {
if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) {
return llval;
}
let sc = llvm::LLVMConstStringInContext(self.llcx,
s.as_ptr() as *const c_char,
s.len() as c_uint,
!null_terminated as Bool);
let sym = self.generate_local_symbol_name("str");
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", sym);
});
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
self.const_cstr_cache.borrow_mut().insert(s, g);
g
}
}
fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
let len = s.len();
let cs = consts::ptrcast(self.const_cstr(s, false),
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
self.const_fat_ptr(cs, self.const_usize(len as u64))
}
fn const_struct(
&self,
elts: &[&'ll Value],
@ -225,32 +257,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
struct_in_context(self.llcx, elts, packed)
}
fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
unsafe {
assert_eq!(idx as c_uint as u64, idx);
let us = &[idx as c_uint];
let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
debug!("const_get_elt(v={:?}, idx={}, r={:?})",
v, idx, r);
r
}
}
fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
unsafe {
if self.is_const_real(v) {
let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
let loses_info = if loses_info == 1 { true } else { false };
Some((r, loses_info))
} else {
None
}
}
}
fn const_to_uint(&self, v: &'ll Value) -> u64 {
unsafe {
llvm::LLVMConstIntGetZExtValue(v)
@ -263,12 +269,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
fn is_const_real(&self, v: &'ll Value) -> bool {
unsafe {
llvm::LLVMIsAConstantFP(v).is_some()
}
}
fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
unsafe {
if self.is_const_integral(v) {

View File

@ -399,12 +399,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Get the location information.
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
let filename = bx.const_str_slice(filename);
let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
let align = self.cx.tcx().data_layout.aggregate_align.abi
.max(self.cx.tcx().data_layout.i32_align.abi)
.max(self.cx.tcx().data_layout.pointer_align.abi);
// Put together the arguments to the panic entry point.
let (lang_item, args) = match *msg {
@ -412,30 +408,28 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let len = self.codegen_operand(&mut bx, len).immediate();
let index = self.codegen_operand(&mut bx, index).immediate();
let file_line_col = bx.const_struct(&[filename, line, col], false);
let file_line_col = bx.static_addr_of(
file_line_col,
align,
Some("panic_bounds_check_loc")
let file_line_col = bx.static_panic_msg(
None,
filename,
line,
col,
"panic_bounds_check_loc",
);
(lang_items::PanicBoundsCheckFnLangItem,
vec![file_line_col, index, len])
vec![file_line_col, index, len])
}
_ => {
let str = msg.description();
let msg_str = Symbol::intern(str).as_str();
let msg_str = bx.const_str_slice(msg_str);
let msg_file_line_col = bx.const_struct(
&[msg_str, filename, line, col],
false
);
let msg_file_line_col = bx.static_addr_of(
msg_file_line_col,
align,
Some("panic_loc")
let msg_file_line_col = bx.static_panic_msg(
Some(msg_str),
filename,
line,
col,
"panic_loc",
);
(lang_items::PanicFnLangItem,
vec![msg_file_line_col])
vec![msg_file_line_col])
}
};
@ -539,27 +533,20 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if layout.abi.is_uninhabited() {
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
let filename = bx.const_str_slice(filename);
let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
let align = self.cx.tcx().data_layout.aggregate_align.abi
.max(self.cx.tcx().data_layout.i32_align.abi)
.max(self.cx.tcx().data_layout.pointer_align.abi);
let str = format!(
"Attempted to instantiate uninhabited type {}",
ty
);
let msg_str = Symbol::intern(&str).as_str();
let msg_str = bx.const_str_slice(msg_str);
let msg_file_line_col = bx.const_struct(
&[msg_str, filename, line, col],
false,
);
let msg_file_line_col = bx.static_addr_of(
msg_file_line_col,
align,
Some("panic_loc"),
let msg_file_line_col = bx.static_panic_msg(
Some(msg_str),
filename,
line,
col,
"panic_loc",
);
// Obtain the panic entry point.

View File

@ -3,7 +3,6 @@ use crate::mir::place::PlaceRef;
use rustc::mir::interpret::Allocation;
use rustc::mir::interpret::Scalar;
use rustc::ty::layout;
use syntax::symbol::LocalInternedString;
pub trait ConstMethods<'tcx>: BackendTypes {
// Constant constructors
@ -19,20 +18,12 @@ pub trait ConstMethods<'tcx>: BackendTypes {
fn const_usize(&self, i: u64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value;
// This is a 'c-like' raw string, which differs from
// our boxed-and-length-annotated strings.
fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
fn const_get_elt(&self, v: Self::Value, idx: u64) -> Self::Value;
fn const_get_real(&self, v: Self::Value) -> Option<(f64, bool)>;
fn const_to_uint(&self, v: Self::Value) -> 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 is_const_real(&self, v: Self::Value) -> bool;
fn scalar_to_backend(
&self,

View File

@ -1,4 +1,5 @@
use super::BackendTypes;
use syntax_pos::symbol::LocalInternedString;
use rustc::hir::def_id::DefId;
use rustc::ty::layout::Align;
@ -9,4 +10,12 @@ pub trait StaticMethods: BackendTypes {
pub trait StaticBuilderMethods<'tcx>: BackendTypes {
fn get_static(&mut self, def_id: DefId) -> Self::Value;
fn static_panic_msg(
&mut self,
msg: Option<LocalInternedString>,
filename: LocalInternedString,
line: Self::Value,
col: Self::Value,
kind: &str,
) -> Self::Value;
}