Skip to content

Commit

Permalink
Auto merge of #53161 - michaelwoerister:cstrings, r=wesleywiser
Browse files Browse the repository at this point in the history
Avoid many allocations for CStrings during codegen.

Giving in to my irrational fear of dynamic allocations. Let's see what perf says to this.
  • Loading branch information
bors committed Aug 13, 2018
2 parents 147ca2d + 88d84b3 commit a78ae85
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 92 deletions.
16 changes: 6 additions & 10 deletions src/librustc_codegen_llvm/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.
//! Set and unset common attributes on LLVM values.

use std::ffi::{CStr, CString};
use std::ffi::CString;

use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
Expand Down Expand Up @@ -75,7 +75,7 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value)
if cx.sess().must_not_eliminate_frame_pointers() {
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
cstr("no-frame-pointer-elim\0"), cstr("true\0"));
const_cstr!("no-frame-pointer-elim"), const_cstr!("true"));
}
}

Expand Down Expand Up @@ -108,7 +108,7 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
// This is defined in the `compiler-builtins` crate for each architecture.
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
cstr("probe-stack\0"), cstr("__rust_probestack\0"));
const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
}

pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
Expand All @@ -128,7 +128,7 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
cstr("target-cpu\0"),
const_cstr!("target-cpu"),
target_cpu.as_c_str());
}

Expand Down Expand Up @@ -202,7 +202,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
let val = CString::new(features).unwrap();
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
cstr("target-features\0"), &val);
const_cstr!("target-features"), &val);
}

// Note that currently the `wasm-import-module` doesn't do anything, but
Expand All @@ -213,17 +213,13 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
cstr("wasm-import-module\0"),
const_cstr!("wasm-import-module"),
&module,
);
}
}
}

fn cstr(s: &'static str) -> &CStr {
CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
}

pub fn provide(providers: &mut Providers) {
providers.target_features_whitelist = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Expand Down
10 changes: 4 additions & 6 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc::ty::TyCtxt;
use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passes_entry};
use rustc_fs_util::{path2cstr, link_or_copy};
use rustc_data_structures::small_c_str::SmallCStr;
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
use errors::emitter::{Emitter};
use syntax::attr;
Expand Down Expand Up @@ -170,11 +171,8 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)

let singlethread = sess.target.target.options.singlethread;

let triple = &sess.target.target.llvm_target;

let triple = CString::new(triple.as_bytes()).unwrap();
let cpu = sess.target_cpu();
let cpu = CString::new(cpu.as_bytes()).unwrap();
let triple = SmallCStr::new(&sess.target.target.llvm_target);
let cpu = SmallCStr::new(sess.target_cpu());
let features = attributes::llvm_target_features(sess)
.collect::<Vec<_>>()
.join(",");
Expand Down Expand Up @@ -522,7 +520,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
// If we're verifying or linting, add them to the function pass
// manager.
let addpass = |pass_name: &str| {
let pass_name = CString::new(pass_name).unwrap();
let pass_name = SmallCStr::new(pass_name);
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
Some(pass) => pass,
None => return false,
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_codegen_llvm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ use type_::Type;
use type_of::LayoutLlvmExt;
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
use CrateInfo;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_data_structures::sync::Lrc;

use std::any::Any;
Expand Down Expand Up @@ -533,7 +534,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
None => return,
};
unsafe {
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
let buf = SmallCStr::new(&sect.as_str());
llvm::LLVMSetSection(llval, buf.as_ptr());
}
}
Expand Down Expand Up @@ -681,7 +682,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
let name = CString::new(section_name).unwrap();
let name = SmallCStr::new(section_name);
llvm::LLVMSetSection(llglobal, name.as_ptr());

// Also generate a .section directive to force no
Expand Down Expand Up @@ -1255,8 +1256,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Create the llvm.used variable
// This variable has type [N x i8*] and is stored in the llvm.metadata section
if !cx.used_statics.borrow().is_empty() {
let name = CString::new("llvm.used").unwrap();
let section = CString::new("llvm.metadata").unwrap();
let name = const_cstr!("llvm.used");
let section = const_cstr!("llvm.metadata");
let array = C_array(Type::i8(&cx).ptr_to(), &*cx.used_statics.borrow());

unsafe {
Expand Down
14 changes: 7 additions & 7 deletions src/librustc_codegen_llvm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use libc::{c_uint, c_char};
use rustc::ty::TyCtxt;
use rustc::ty::layout::{Align, Size};
use rustc::session::{config, Session};
use rustc_data_structures::small_c_str::SmallCStr;

use std::borrow::Cow;
use std::ffi::CString;
use std::ops::Range;
use std::ptr;

Expand Down Expand Up @@ -58,7 +58,7 @@ impl Builder<'a, 'll, 'tcx> {
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
let bx = Builder::with_cx(cx);
let llbb = unsafe {
let name = CString::new(name).unwrap();
let name = SmallCStr::new(name);
llvm::LLVMAppendBasicBlockInContext(
cx.llcx,
llfn,
Expand Down Expand Up @@ -118,7 +118,7 @@ impl Builder<'a, 'll, 'tcx> {
}

pub fn set_value_name(&self, value: &'ll Value, name: &str) {
let cname = CString::new(name.as_bytes()).unwrap();
let cname = SmallCStr::new(name);
unsafe {
llvm::LLVMSetValueName(value, cname.as_ptr());
}
Expand Down Expand Up @@ -436,7 +436,7 @@ impl Builder<'a, 'll, 'tcx> {
let alloca = if name.is_empty() {
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
} else {
let name = CString::new(name).unwrap();
let name = SmallCStr::new(name);
llvm::LLVMBuildAlloca(self.llbuilder, ty,
name.as_ptr())
};
Expand Down Expand Up @@ -975,7 +975,7 @@ impl Builder<'a, 'll, 'tcx> {
parent: Option<&'ll Value>,
args: &[&'ll Value]) -> &'ll Value {
self.count_insn("cleanuppad");
let name = CString::new("cleanuppad").unwrap();
let name = const_cstr!("cleanuppad");
let ret = unsafe {
llvm::LLVMRustBuildCleanupPad(self.llbuilder,
parent,
Expand All @@ -1001,7 +1001,7 @@ impl Builder<'a, 'll, 'tcx> {
parent: &'ll Value,
args: &[&'ll Value]) -> &'ll Value {
self.count_insn("catchpad");
let name = CString::new("catchpad").unwrap();
let name = const_cstr!("catchpad");
let ret = unsafe {
llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
args.len() as c_uint, args.as_ptr(),
Expand All @@ -1025,7 +1025,7 @@ impl Builder<'a, 'll, 'tcx> {
num_handlers: usize,
) -> &'ll Value {
self.count_insn("catchswitch");
let name = CString::new("catchswitch").unwrap();
let name = const_cstr!("catchswitch");
let ret = unsafe {
llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
num_handlers as c_uint,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ pub fn codegen_static<'a, 'tcx>(
} else {
// If we created the global with the wrong type,
// correct the type.
let empty_string = CString::new("").unwrap();
let empty_string = const_cstr!("");
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(g));
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
llvm::LLVMSetValueName(g, empty_string.as_ptr());
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_codegen_llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use type_::Type;
use type_of::PointeeInfo;

use rustc_data_structures::base_n;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc::mir::mono::Stats;
use rustc::session::config::{self, DebugInfo};
use rustc::session::Session;
Expand All @@ -34,7 +35,7 @@ use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FxHashMap;
use rustc_target::spec::{HasTargetSpec, Target};

use std::ffi::{CStr, CString};
use std::ffi::CStr;
use std::cell::{Cell, RefCell};
use std::iter;
use std::str;
Expand Down Expand Up @@ -161,7 +162,7 @@ pub unsafe fn create_module(
llcx: &'ll llvm::Context,
mod_name: &str,
) -> &'ll llvm::Module {
let mod_name = CString::new(mod_name).unwrap();
let mod_name = SmallCStr::new(mod_name);
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);

// Ensure the data-layout values hardcoded remain the defaults.
Expand Down Expand Up @@ -201,11 +202,10 @@ pub unsafe fn create_module(
}
}

let data_layout = CString::new(&sess.target.target.data_layout[..]).unwrap();
let data_layout = SmallCStr::new(&sess.target.target.data_layout);
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());

let llvm_target = sess.target.target.llvm_target.as_bytes();
let llvm_target = CString::new(llvm_target).unwrap();
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());

if is_pie_binary(sess) {
Expand Down
Loading

0 comments on commit a78ae85

Please sign in to comment.