1
- // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
7
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
-
11
- // trans.rs: Translate the completed AST to the LLVM IR.
12
- //
13
- // Some functions here, such as trans_block and trans_expr, return a value --
14
- // the result of the translation to LLVM -- while others, such as trans_fn,
15
- // trans_impl, and trans_item, are called only for the side effect of adding a
16
- // particular definition to the LLVM IR output we're producing.
17
- //
18
- // Hopefully useful general knowledge about trans:
19
- //
20
- // * There's no way to find out the Ty type of a ValueRef. Doing so
21
- // would be "trying to get the eggs out of an omelette" (credit:
22
- // pcwalton). You can, instead, find out its TypeRef by calling val_ty,
23
- // but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
24
- // int) and rec(x=int, y=int, z=int) will have the same TypeRef.
10
+ //! Translate the completed AST to the LLVM IR.
11
+ //!
12
+ //! Some functions here, such as trans_block and trans_expr, return a value --
13
+ //! the result of the translation to LLVM -- while others, such as trans_fn,
14
+ //! trans_impl, and trans_item, are called only for the side effect of adding a
15
+ //! particular definition to the LLVM IR output we're producing.
16
+ //!
17
+ //! Hopefully useful general knowledge about trans:
18
+ //!
19
+ //! * There's no way to find out the Ty type of a ValueRef. Doing so
20
+ //! would be "trying to get the eggs out of an omelette" (credit:
21
+ //! pcwalton). You can, instead, find out its TypeRef by calling val_ty,
22
+ //! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
23
+ //! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
25
24
26
25
#![ allow( non_camel_case_types) ]
27
26
@@ -33,7 +32,7 @@ use super::ModuleTranslation;
33
32
use back:: link:: mangle_exported_name;
34
33
use back:: { link, abi} ;
35
34
use lint;
36
- use llvm:: { AttrHelper , BasicBlockRef , Linkage , ValueRef , Vector , get_param} ;
35
+ use llvm:: { BasicBlockRef , Linkage , ValueRef , Vector , get_param} ;
37
36
use llvm;
38
37
use metadata:: { csearch, encoder, loader} ;
39
38
use middle:: astencode;
@@ -46,6 +45,7 @@ use session::config::{self, NoDebugInfo};
46
45
use session:: Session ;
47
46
use trans:: _match;
48
47
use trans:: adt;
48
+ use trans:: attributes;
49
49
use trans:: build:: * ;
50
50
use trans:: builder:: { Builder , noname} ;
51
51
use trans:: callee;
@@ -204,7 +204,7 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
204
204
llvm:: SetUnnamedAddr ( llfn, true ) ;
205
205
206
206
if ccx. is_split_stack_supported ( ) && !ccx. sess ( ) . opts . cg . no_stack_check {
207
- set_split_stack ( llfn) ;
207
+ attributes :: split_stack ( llfn, true ) ;
208
208
}
209
209
210
210
llfn
@@ -245,7 +245,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
245
245
let f = decl_rust_fn ( ccx, fn_ty, name) ;
246
246
247
247
let attrs = csearch:: get_item_attrs ( & ccx. sess ( ) . cstore , did) ;
248
- set_llvm_fn_attrs ( ccx, & attrs[ ..] , f) ;
248
+ attributes :: convert_fn_attrs_to_llvm ( ccx, & attrs[ ..] , f) ;
249
249
250
250
ccx. externs ( ) . borrow_mut ( ) . insert ( name. to_string ( ) , f) ;
251
251
f
@@ -390,77 +390,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
390
390
Result :: new ( r. bcx , PointerCast ( r. bcx , r. val , llty_ptr) )
391
391
}
392
392
393
- #[ allow( dead_code) ] // useful
394
- pub fn set_optimize_for_size ( f : ValueRef ) {
395
- llvm:: SetFunctionAttribute ( f, llvm:: OptimizeForSizeAttribute )
396
- }
397
-
398
- pub fn set_no_inline ( f : ValueRef ) {
399
- llvm:: SetFunctionAttribute ( f, llvm:: NoInlineAttribute )
400
- }
401
-
402
- #[ allow( dead_code) ] // useful
403
- pub fn set_no_unwind ( f : ValueRef ) {
404
- llvm:: SetFunctionAttribute ( f, llvm:: NoUnwindAttribute )
405
- }
406
-
407
- // Tell LLVM to emit the information necessary to unwind the stack for the
408
- // function f.
409
- pub fn set_uwtable ( f : ValueRef ) {
410
- llvm:: SetFunctionAttribute ( f, llvm:: UWTableAttribute )
411
- }
412
-
413
- pub fn set_inline_hint ( f : ValueRef ) {
414
- llvm:: SetFunctionAttribute ( f, llvm:: InlineHintAttribute )
415
- }
416
-
417
- pub fn set_llvm_fn_attrs ( ccx : & CrateContext , attrs : & [ ast:: Attribute ] , llfn : ValueRef ) {
418
- use syntax:: attr:: { find_inline_attr, InlineAttr } ;
419
- // Set the inline hint if there is one
420
- match find_inline_attr ( Some ( ccx. sess ( ) . diagnostic ( ) ) , attrs) {
421
- InlineAttr :: Hint => set_inline_hint ( llfn) ,
422
- InlineAttr :: Always => set_always_inline ( llfn) ,
423
- InlineAttr :: Never => set_no_inline ( llfn) ,
424
- InlineAttr :: None => { /* fallthrough */ }
425
- }
426
-
427
- for attr in attrs {
428
- let mut used = true ;
429
- match & attr. name ( ) [ ..] {
430
- "no_stack_check" => unset_split_stack ( llfn) ,
431
- "cold" => unsafe {
432
- llvm:: LLVMAddFunctionAttribute ( llfn,
433
- llvm:: FunctionIndex as c_uint ,
434
- llvm:: ColdAttribute as uint64_t )
435
- } ,
436
- "allocator" => {
437
- llvm:: NoAliasAttribute . apply_llfn ( llvm:: ReturnIndex as c_uint , llfn) ;
438
- }
439
- _ => used = false ,
440
- }
441
- if used {
442
- attr:: mark_used ( attr) ;
443
- }
444
- }
445
- }
446
-
447
- pub fn set_always_inline ( f : ValueRef ) {
448
- llvm:: SetFunctionAttribute ( f, llvm:: AlwaysInlineAttribute )
449
- }
450
-
451
- pub fn set_split_stack ( f : ValueRef ) {
452
- unsafe {
453
- llvm:: LLVMAddFunctionAttrString ( f, llvm:: FunctionIndex as c_uint ,
454
- "split-stack\0 " . as_ptr ( ) as * const _ ) ;
455
- }
456
- }
457
-
458
- pub fn unset_split_stack ( f : ValueRef ) {
459
- unsafe {
460
- llvm:: LLVMRemoveFunctionAttrString ( f, llvm:: FunctionIndex as c_uint ,
461
- "split-stack\0 " . as_ptr ( ) as * const _ ) ;
462
- }
463
- }
464
393
465
394
// Double-check that we never ask LLVM to declare the same symbol twice. It
466
395
// silently mangles such symbols, breaking our linkage model.
@@ -898,7 +827,7 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
898
827
_ => {
899
828
let llfn = foreign:: register_foreign_item_fn ( ccx, fn_ty. abi , t, & name[ ..] ) ;
900
829
let attrs = csearch:: get_item_attrs ( & ccx. sess ( ) . cstore , did) ;
901
- set_llvm_fn_attrs ( ccx, & attrs, llfn) ;
830
+ attributes :: convert_fn_attrs_to_llvm ( ccx, & attrs, llfn) ;
902
831
llfn
903
832
}
904
833
}
@@ -1708,7 +1637,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1708
1637
ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
1709
1638
1710
1639
let _icx = push_ctxt ( "trans_closure" ) ;
1711
- set_uwtable ( llfndecl) ;
1640
+ attributes :: emit_uwtable ( llfndecl, true ) ;
1712
1641
1713
1642
debug ! ( "trans_closure(..., param_substs={})" ,
1714
1643
param_substs. repr( ccx. tcx( ) ) ) ;
@@ -2312,7 +2241,7 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
2312
2241
// eh_personality functions need to be externally linkable.
2313
2242
let def = ast_util:: local_def ( node_id) ;
2314
2243
if ccx. tcx ( ) . lang_items . stack_exhausted ( ) == Some ( def) {
2315
- unset_split_stack ( llfn) ;
2244
+ attributes :: split_stack ( llfn, false ) ;
2316
2245
llvm:: SetLinkage ( llfn, llvm:: ExternalLinkage ) ;
2317
2246
}
2318
2247
if ccx. tcx ( ) . lang_items . eh_personality ( ) == Some ( def) {
@@ -2733,7 +2662,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
2733
2662
sym,
2734
2663
i. id )
2735
2664
} ;
2736
- set_llvm_fn_attrs ( ccx, & i. attrs , llfn) ;
2665
+ attributes :: convert_fn_attrs_to_llvm ( ccx, & i. attrs , llfn) ;
2737
2666
llfn
2738
2667
}
2739
2668
@@ -2794,7 +2723,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
2794
2723
let ty = ty:: node_id_to_type ( ccx. tcx ( ) , ni. id ) ;
2795
2724
let name = foreign:: link_name ( & * ni) ;
2796
2725
let llfn = foreign:: register_foreign_item_fn ( ccx, abi, ty, & name) ;
2797
- set_llvm_fn_attrs ( ccx, & ni. attrs , llfn) ;
2726
+ attributes :: convert_fn_attrs_to_llvm ( ccx, & ni. attrs , llfn) ;
2798
2727
llfn
2799
2728
}
2800
2729
ast:: ForeignItemStatic ( ..) => {
@@ -2826,7 +2755,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
2826
2755
}
2827
2756
_ => ccx. sess ( ) . bug ( "NodeVariant, shouldn't happen" )
2828
2757
} ;
2829
- set_inline_hint ( llfn) ;
2758
+ attributes :: inline ( llfn, attributes :: InlineHint ) ;
2830
2759
llfn
2831
2760
}
2832
2761
@@ -2848,7 +2777,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
2848
2777
& struct_item. attrs ) ;
2849
2778
let llfn = register_fn ( ccx, struct_item. span ,
2850
2779
sym, ctor_id, ty) ;
2851
- set_inline_hint ( llfn) ;
2780
+ attributes :: inline ( llfn, attributes :: InlineHint ) ;
2852
2781
llfn
2853
2782
}
2854
2783
@@ -2883,7 +2812,7 @@ fn register_method(ccx: &CrateContext, id: ast::NodeId,
2883
2812
} else {
2884
2813
foreign:: register_rust_fn_with_foreign_abi ( ccx, span, sym, id)
2885
2814
} ;
2886
- set_llvm_fn_attrs ( ccx, & attrs, llfn) ;
2815
+ attributes :: convert_fn_attrs_to_llvm ( ccx, & attrs, llfn) ;
2887
2816
return llfn;
2888
2817
} else {
2889
2818
ccx. sess ( ) . span_bug ( span, "expected bare rust function" ) ;
0 commit comments