Skip to content

Commit a78ae85

Browse files
committed
Auto merge of #53161 - michaelwoerister:cstrings, r=wesleywiser
Avoid many allocations for CStrings during codegen. Giving in to my irrational fear of dynamic allocations. Let's see what perf says to this.
2 parents 147ca2d + 88d84b3 commit a78ae85

File tree

15 files changed

+256
-92
lines changed

15 files changed

+256
-92
lines changed

src/librustc_codegen_llvm/attributes.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010
//! Set and unset common attributes on LLVM values.
1111
12-
use std::ffi::{CStr, CString};
12+
use std::ffi::CString;
1313

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

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

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

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

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

223-
fn cstr(s: &'static str) -> &CStr {
224-
CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
225-
}
226-
227223
pub fn provide(providers: &mut Providers) {
228224
providers.target_features_whitelist = |tcx, cnum| {
229225
assert_eq!(cnum, LOCAL_CRATE);

src/librustc_codegen_llvm/back/write.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
3131
use rustc::ty::TyCtxt;
3232
use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passes_entry};
3333
use rustc_fs_util::{path2cstr, link_or_copy};
34+
use rustc_data_structures::small_c_str::SmallCStr;
3435
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
3536
use errors::emitter::{Emitter};
3637
use syntax::attr;
@@ -170,11 +171,8 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
170171

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

173-
let triple = &sess.target.target.llvm_target;
174-
175-
let triple = CString::new(triple.as_bytes()).unwrap();
176-
let cpu = sess.target_cpu();
177-
let cpu = CString::new(cpu.as_bytes()).unwrap();
174+
let triple = SmallCStr::new(&sess.target.target.llvm_target);
175+
let cpu = SmallCStr::new(sess.target_cpu());
178176
let features = attributes::llvm_target_features(sess)
179177
.collect::<Vec<_>>()
180178
.join(",");
@@ -522,7 +520,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
522520
// If we're verifying or linting, add them to the function pass
523521
// manager.
524522
let addpass = |pass_name: &str| {
525-
let pass_name = CString::new(pass_name).unwrap();
523+
let pass_name = SmallCStr::new(pass_name);
526524
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
527525
Some(pass) => pass,
528526
None => return false,

src/librustc_codegen_llvm/base.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ use type_::Type;
7373
use type_of::LayoutLlvmExt;
7474
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
7575
use CrateInfo;
76+
use rustc_data_structures::small_c_str::SmallCStr;
7677
use rustc_data_structures::sync::Lrc;
7778

7879
use std::any::Any;
@@ -533,7 +534,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
533534
None => return,
534535
};
535536
unsafe {
536-
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
537+
let buf = SmallCStr::new(&sect.as_str());
537538
llvm::LLVMSetSection(llval, buf.as_ptr());
538539
}
539540
}
@@ -681,7 +682,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
681682
unsafe {
682683
llvm::LLVMSetInitializer(llglobal, llconst);
683684
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
684-
let name = CString::new(section_name).unwrap();
685+
let name = SmallCStr::new(section_name);
685686
llvm::LLVMSetSection(llglobal, name.as_ptr());
686687

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

12621263
unsafe {

src/librustc_codegen_llvm/builder.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use libc::{c_uint, c_char};
1818
use rustc::ty::TyCtxt;
1919
use rustc::ty::layout::{Align, Size};
2020
use rustc::session::{config, Session};
21+
use rustc_data_structures::small_c_str::SmallCStr;
2122

2223
use std::borrow::Cow;
23-
use std::ffi::CString;
2424
use std::ops::Range;
2525
use std::ptr;
2626

@@ -58,7 +58,7 @@ impl Builder<'a, 'll, 'tcx> {
5858
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
5959
let bx = Builder::with_cx(cx);
6060
let llbb = unsafe {
61-
let name = CString::new(name).unwrap();
61+
let name = SmallCStr::new(name);
6262
llvm::LLVMAppendBasicBlockInContext(
6363
cx.llcx,
6464
llfn,
@@ -118,7 +118,7 @@ impl Builder<'a, 'll, 'tcx> {
118118
}
119119

120120
pub fn set_value_name(&self, value: &'ll Value, name: &str) {
121-
let cname = CString::new(name.as_bytes()).unwrap();
121+
let cname = SmallCStr::new(name);
122122
unsafe {
123123
llvm::LLVMSetValueName(value, cname.as_ptr());
124124
}
@@ -436,7 +436,7 @@ impl Builder<'a, 'll, 'tcx> {
436436
let alloca = if name.is_empty() {
437437
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
438438
} else {
439-
let name = CString::new(name).unwrap();
439+
let name = SmallCStr::new(name);
440440
llvm::LLVMBuildAlloca(self.llbuilder, ty,
441441
name.as_ptr())
442442
};
@@ -975,7 +975,7 @@ impl Builder<'a, 'll, 'tcx> {
975975
parent: Option<&'ll Value>,
976976
args: &[&'ll Value]) -> &'ll Value {
977977
self.count_insn("cleanuppad");
978-
let name = CString::new("cleanuppad").unwrap();
978+
let name = const_cstr!("cleanuppad");
979979
let ret = unsafe {
980980
llvm::LLVMRustBuildCleanupPad(self.llbuilder,
981981
parent,
@@ -1001,7 +1001,7 @@ impl Builder<'a, 'll, 'tcx> {
10011001
parent: &'ll Value,
10021002
args: &[&'ll Value]) -> &'ll Value {
10031003
self.count_insn("catchpad");
1004-
let name = CString::new("catchpad").unwrap();
1004+
let name = const_cstr!("catchpad");
10051005
let ret = unsafe {
10061006
llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
10071007
args.len() as c_uint, args.as_ptr(),
@@ -1025,7 +1025,7 @@ impl Builder<'a, 'll, 'tcx> {
10251025
num_handlers: usize,
10261026
) -> &'ll Value {
10271027
self.count_insn("catchswitch");
1028-
let name = CString::new("catchswitch").unwrap();
1028+
let name = const_cstr!("catchswitch");
10291029
let ret = unsafe {
10301030
llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
10311031
num_handlers as c_uint,

src/librustc_codegen_llvm/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ pub fn codegen_static<'a, 'tcx>(
328328
} else {
329329
// If we created the global with the wrong type,
330330
// correct the type.
331-
let empty_string = CString::new("").unwrap();
331+
let empty_string = const_cstr!("");
332332
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(g));
333333
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
334334
llvm::LLVMSetValueName(g, empty_string.as_ptr());

src/librustc_codegen_llvm/context.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use type_::Type;
2626
use type_of::PointeeInfo;
2727

2828
use rustc_data_structures::base_n;
29+
use rustc_data_structures::small_c_str::SmallCStr;
2930
use rustc::mir::mono::Stats;
3031
use rustc::session::config::{self, DebugInfo};
3132
use rustc::session::Session;
@@ -34,7 +35,7 @@ use rustc::ty::{self, Ty, TyCtxt};
3435
use rustc::util::nodemap::FxHashMap;
3536
use rustc_target::spec::{HasTargetSpec, Target};
3637

37-
use std::ffi::{CStr, CString};
38+
use std::ffi::CStr;
3839
use std::cell::{Cell, RefCell};
3940
use std::iter;
4041
use std::str;
@@ -161,7 +162,7 @@ pub unsafe fn create_module(
161162
llcx: &'ll llvm::Context,
162163
mod_name: &str,
163164
) -> &'ll llvm::Module {
164-
let mod_name = CString::new(mod_name).unwrap();
165+
let mod_name = SmallCStr::new(mod_name);
165166
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
166167

167168
// Ensure the data-layout values hardcoded remain the defaults.
@@ -201,11 +202,10 @@ pub unsafe fn create_module(
201202
}
202203
}
203204

204-
let data_layout = CString::new(&sess.target.target.data_layout[..]).unwrap();
205+
let data_layout = SmallCStr::new(&sess.target.target.data_layout);
205206
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
206207

207-
let llvm_target = sess.target.target.llvm_target.as_bytes();
208-
let llvm_target = CString::new(llvm_target).unwrap();
208+
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
209209
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
210210

211211
if is_pie_binary(sess) {

0 commit comments

Comments
 (0)