Skip to content

Commit 2f3fde6

Browse files
committed
Implement an address_insignificant attribute
This can be applied to statics and it will indicate that LLVM will attempt to merge the constant in .data with other statics. I have preliminarily applied this to all of the statics generated by the new `ifmt!` syntax extension. I compiled a file with 1000 calls to `ifmt!` and a separate file with 1000 calls to `fmt!` to compare the sizes, and the results were: fmt 310k ifmt (before) 529k ifmt (after) 202k This now means that ifmt! is both faster and smaller than fmt!, yay!
1 parent 74efdf6 commit 2f3fde6

File tree

5 files changed

+47
-16
lines changed

5 files changed

+47
-16
lines changed

src/librustc/lib/llvm.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,6 +2080,9 @@ pub mod llvm {
20802080
Elements: ValueRef,
20812081
RunTimeLang: c_uint)
20822082
-> ValueRef;
2083+
2084+
#[fast_ffi]
2085+
pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
20832086
}
20842087
}
20852088

@@ -2099,6 +2102,12 @@ pub fn SetLinkage(Global: ValueRef, Link: Linkage) {
20992102
}
21002103
}
21012104

2105+
pub fn SetUnnamedAddr(Global: ValueRef, Unnamed: bool) {
2106+
unsafe {
2107+
llvm::LLVMSetUnnamedAddr(Global, Unnamed as Bool);
2108+
}
2109+
}
2110+
21022111
pub fn ConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
21032112
unsafe {
21042113
llvm::LLVMConstICmp(Pred as c_ushort, V1, V2)

src/librustc/middle/trans/base.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,19 +2159,18 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
21592159
}
21602160
ast::item_static(_, m, expr) => {
21612161
consts::trans_const(ccx, m, item.id);
2162-
// Do static_assert checking. It can't really be done much earlier because we need to get
2163-
// the value of the bool out of LLVM
2164-
for attr in item.attrs.iter() {
2165-
if "static_assert" == attr.name() {
2166-
if m == ast::m_mutbl {
2167-
ccx.sess.span_fatal(expr.span,
2168-
"cannot have static_assert on a mutable static");
2169-
}
2170-
let v = ccx.const_values.get_copy(&item.id);
2171-
unsafe {
2172-
if !(llvm::LLVMConstIntGetZExtValue(v) as bool) {
2173-
ccx.sess.span_fatal(expr.span, "static assertion failed");
2174-
}
2162+
// Do static_assert checking. It can't really be done much earlier
2163+
// because we need to get the value of the bool out of LLVM
2164+
if attr::contains_name(item.attrs, "static_assert") {
2165+
if m == ast::m_mutbl {
2166+
ccx.sess.span_fatal(expr.span,
2167+
"cannot have static_assert on a mutable \
2168+
static");
2169+
}
2170+
let v = ccx.const_values.get_copy(&item.id);
2171+
unsafe {
2172+
if !(llvm::LLVMConstIntGetZExtValue(v) as bool) {
2173+
ccx.sess.span_fatal(expr.span, "static assertion failed");
21752174
}
21762175
}
21772176
}
@@ -2432,6 +2431,15 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
24322431
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
24332432
};
24342433

2434+
// Apply the `unnamed_addr` attribute if
2435+
// requested
2436+
if attr::contains_name(i.attrs,
2437+
"address_insignificant"){
2438+
lib::llvm::SetUnnamedAddr(g, true);
2439+
lib::llvm::SetLinkage(g,
2440+
lib::llvm::InternalLinkage);
2441+
}
2442+
24352443
ccx.item_symbols.insert(i.id, sym);
24362444
g
24372445
}

src/libsyntax/ext/ifmt.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,12 @@ impl Context {
429429
let st = ast::item_static(ty, ast::m_imm, method);
430430
let static_name = self.ecx.ident_of(fmt!("__static_method_%u",
431431
self.method_statics.len()));
432-
let item = self.ecx.item(sp, static_name, ~[], st);
432+
// Flag these statics as `address_insignificant` so LLVM can
433+
// merge duplicate globals as much as possible (which we're
434+
// generating a whole lot of).
435+
let unnamed = self.ecx.meta_word(self.fmtsp, @"address_insignificant");
436+
let unnamed = self.ecx.attribute(self.fmtsp, unnamed);
437+
let item = self.ecx.item(sp, static_name, ~[unnamed], st);
433438
self.method_statics.push(item);
434439
self.ecx.expr_ident(sp, static_name)
435440
};
@@ -550,7 +555,10 @@ impl Context {
550555
let ty = self.ecx.ty(self.fmtsp, ty);
551556
let st = ast::item_static(ty, ast::m_imm, fmt);
552557
let static_name = self.ecx.ident_of("__static_fmtstr");
553-
let item = self.ecx.item(self.fmtsp, static_name, ~[], st);
558+
// see above comment for `address_insignificant` and why we do it
559+
let unnamed = self.ecx.meta_word(self.fmtsp, @"address_insignificant");
560+
let unnamed = self.ecx.attribute(self.fmtsp, unnamed);
561+
let item = self.ecx.item(self.fmtsp, static_name, ~[unnamed], st);
554562
let decl = respan(self.fmtsp, ast::decl_item(item));
555563
lets.push(@respan(self.fmtsp, ast::stmt_decl(@decl, self.ecx.next_id())));
556564

@@ -613,6 +621,7 @@ impl Context {
613621
if ty == Unknown {
614622
ty = Known(@"?");
615623
}
624+
616625
let argptr = self.ecx.expr_addr_of(sp, self.ecx.expr_ident(sp, ident));
617626
match ty {
618627
Known(tyname) => {
@@ -685,7 +694,7 @@ pub fn expand_syntax_ext(ecx: @ExtCtxt, sp: span,
685694
};
686695
cx.fmtsp = efmt.span;
687696
let fmt = expr_to_str(ecx, efmt,
688-
~"first argument to ifmt! must be a string literal.");
697+
"first argument to ifmt! must be a string literal.");
689698

690699
let mut err = false;
691700
do parse::parse_error::cond.trap(|m| {

src/rustllvm/RustWrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,3 +833,7 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
833833
unwrapDI<DIArray>(Elements),
834834
RunTimeLang));
835835
}
836+
837+
extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
838+
unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
839+
}

src/rustllvm/rustllvm.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,3 +613,4 @@ LLVMDIBuilderInsertDeclareBefore
613613
LLVMDIBuilderCreateEnumerator
614614
LLVMDIBuilderCreateEnumerationType
615615
LLVMDIBuilderCreateUnionType
616+
LLVMSetUnnamedAddr

0 commit comments

Comments
 (0)