@@ -77,6 +77,7 @@ use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
77
77
use trans:: declare;
78
78
use trans:: expr;
79
79
use trans:: glue;
80
+ use trans:: inline;
80
81
use trans:: intrinsic;
81
82
use trans:: machine;
82
83
use trans:: machine:: { llalign_of_min, llsize_of, llsize_of_real} ;
@@ -1392,34 +1393,53 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1392
1393
pub fn new ( ccx : & ' blk CrateContext < ' blk , ' tcx > ,
1393
1394
llfndecl : ValueRef ,
1394
1395
fn_ty : FnType ,
1395
- id : ast :: NodeId ,
1396
+ def_id : Option < DefId > ,
1396
1397
param_substs : & ' tcx Substs < ' tcx > ,
1397
- sp : Option < Span > ,
1398
1398
block_arena : & ' blk TypedArena < common:: BlockS < ' blk , ' tcx > > )
1399
1399
-> FunctionContext < ' blk , ' tcx > {
1400
1400
common:: validate_substs ( param_substs) ;
1401
1401
1402
- debug ! ( "FunctionContext::new(path={}, id={}, param_substs={:?})" ,
1403
- if id == !0 {
1404
- "" . to_string( )
1405
- } else {
1402
+ let inlined_did = def_id. and_then ( |def_id| inline:: get_local_instance ( ccx, def_id) ) ;
1403
+ let inlined_id = inlined_did. and_then ( |id| ccx. tcx ( ) . map . as_local_node_id ( id) ) ;
1404
+ let local_id = def_id. and_then ( |id| ccx. tcx ( ) . map . as_local_node_id ( id) ) ;
1405
+
1406
+ debug ! ( "FunctionContext::new(path={}, def_id={:?}, param_substs={:?})" ,
1407
+ inlined_id. map_or( String :: new( ) , |id| {
1406
1408
ccx. tcx( ) . map. path_to_string( id) . to_string( )
1407
- } ,
1408
- id ,
1409
+ } ) ,
1410
+ def_id ,
1409
1411
param_substs) ;
1410
1412
1411
- let debug_context = debuginfo:: create_function_debug_context ( ccx, id ,
1412
- param_substs,
1413
- llfndecl ) ;
1414
- let ( blk_id , cfg) = build_cfg ( ccx. tcx ( ) , id) ;
1415
- let nested_returns = if let Some ( ref cfg) = cfg {
1413
+ let debug_context = debuginfo:: create_function_debug_context ( ccx,
1414
+ inlined_id . unwrap_or ( ast :: DUMMY_NODE_ID ) , param_substs, llfndecl ) ;
1415
+
1416
+ let cfg = inlined_id . map ( |id| build_cfg ( ccx. tcx ( ) , id) ) ;
1417
+ let nested_returns = if let Some ( ( blk_id , Some ( ref cfg) ) ) = cfg {
1416
1418
has_nested_returns ( ccx. tcx ( ) , cfg, blk_id)
1417
1419
} else {
1418
1420
false
1419
1421
} ;
1420
1422
1423
+ let check_attrs = |attrs : & [ ast:: Attribute ] | {
1424
+ attrs. iter ( ) . any ( |item| item. check_name ( "rustc_mir" ) )
1425
+ } ;
1426
+
1427
+ let use_mir = if let Some ( id) = local_id {
1428
+ check_attrs ( ccx. tcx ( ) . map . attrs ( id) )
1429
+ } else if let Some ( def_id) = def_id {
1430
+ check_attrs ( & ccx. sess ( ) . cstore . item_attrs ( def_id) )
1431
+ } else {
1432
+ check_attrs ( & [ ] )
1433
+ } ;
1434
+
1435
+ let mir = if use_mir {
1436
+ def_id. and_then ( |id| ccx. get_mir ( id) )
1437
+ } else {
1438
+ None
1439
+ } ;
1440
+
1421
1441
FunctionContext {
1422
- mir : ccx . mir_map ( ) . map . get ( & id ) ,
1442
+ mir : mir ,
1423
1443
llfn : llfndecl,
1424
1444
llretslotptr : Cell :: new ( None ) ,
1425
1445
param_env : ccx. tcx ( ) . empty_parameter_environment ( ) ,
@@ -1431,21 +1451,21 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1431
1451
llupvars : RefCell :: new ( NodeMap ( ) ) ,
1432
1452
lldropflag_hints : RefCell :: new ( DropFlagHintsMap :: new ( ) ) ,
1433
1453
fn_ty : fn_ty,
1434
- id : id,
1435
1454
param_substs : param_substs,
1436
- span : sp ,
1455
+ span : inlined_id . and_then ( |id| ccx . tcx ( ) . map . opt_span ( id ) ) ,
1437
1456
block_arena : block_arena,
1438
1457
lpad_arena : TypedArena :: new ( ) ,
1439
1458
ccx : ccx,
1440
1459
debug_context : debug_context,
1441
1460
scopes : RefCell :: new ( Vec :: new ( ) ) ,
1442
- cfg : cfg,
1461
+ cfg : cfg. and_then ( | ( _ , cfg ) | cfg )
1443
1462
}
1444
1463
}
1445
1464
1446
1465
/// Performs setup on a newly created function, creating the entry
1447
1466
/// scope block and allocating space for the return pointer.
1448
- pub fn init ( & ' blk self , skip_retptr : bool ) -> Block < ' blk , ' tcx > {
1467
+ pub fn init ( & ' blk self , skip_retptr : bool , fn_did : Option < DefId > )
1468
+ -> Block < ' blk , ' tcx > {
1449
1469
let entry_bcx = self . new_temp_block ( "entry-block" ) ;
1450
1470
1451
1471
// Use a dummy instruction as the insertion point for all allocas.
@@ -1493,15 +1513,15 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1493
1513
1494
1514
// Create the drop-flag hints for every unfragmented path in the function.
1495
1515
let tcx = self . ccx . tcx ( ) ;
1496
- let fn_did = tcx. map . local_def_id ( self . id ) ;
1497
1516
let tables = tcx. tables . borrow ( ) ;
1498
1517
let mut hints = self . lldropflag_hints . borrow_mut ( ) ;
1499
1518
let fragment_infos = tcx. fragment_infos . borrow ( ) ;
1500
1519
1501
1520
// Intern table for drop-flag hint datums.
1502
1521
let mut seen = HashMap :: new ( ) ;
1503
1522
1504
- if let Some ( fragment_infos) = fragment_infos. get ( & fn_did) {
1523
+ let fragment_infos = fn_did. and_then ( |did| fragment_infos. get ( & did) ) ;
1524
+ if let Some ( fragment_infos) = fragment_infos {
1505
1525
for & info in fragment_infos {
1506
1526
1507
1527
let make_datum = |id| {
@@ -1558,11 +1578,13 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1558
1578
fn bind_args ( & ' blk self ,
1559
1579
args : & [ hir:: Arg ] ,
1560
1580
abi : Abi ,
1581
+ id : ast:: NodeId ,
1561
1582
closure_env : closure:: ClosureEnv ,
1562
1583
arg_scope : cleanup:: CustomScopeIndex )
1563
1584
-> Block < ' blk , ' tcx > {
1564
1585
let _icx = push_ctxt ( "FunctionContext::bind_args" ) ;
1565
- let mut bcx = self . init ( false ) ;
1586
+ let fn_did = self . ccx . tcx ( ) . map . local_def_id ( id) ;
1587
+ let mut bcx = self . init ( false , Some ( fn_did) ) ;
1566
1588
let arg_scope_id = cleanup:: CustomScope ( arg_scope) ;
1567
1589
1568
1590
let mut idx = 0 ;
@@ -1774,19 +1796,24 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1774
1796
/// Builds an LLVM function out of a source function.
1775
1797
///
1776
1798
/// If the function closes over its environment a closure will be returned.
1777
- pub fn trans_closure < ' a , ' b , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1778
- decl : & hir:: FnDecl ,
1779
- body : & hir:: Block ,
1780
- llfndecl : ValueRef ,
1781
- param_substs : & ' tcx Substs < ' tcx > ,
1782
- fn_ast_id : ast :: NodeId ,
1783
- attributes : & [ ast:: Attribute ] ,
1784
- fn_ty : FnType ,
1785
- abi : Abi ,
1786
- closure_env : closure:: ClosureEnv < ' b > ) {
1799
+ pub fn trans_closure < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1800
+ decl : & hir:: FnDecl ,
1801
+ body : & hir:: Block ,
1802
+ llfndecl : ValueRef ,
1803
+ param_substs : & ' tcx Substs < ' tcx > ,
1804
+ def_id : DefId ,
1805
+ inlined_id : ast:: NodeId ,
1806
+ fn_ty : FnType ,
1807
+ abi : Abi ,
1808
+ closure_env : closure:: ClosureEnv ) {
1787
1809
ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
1788
1810
1789
- record_translation_item_as_generated ( ccx, fn_ast_id, param_substs) ;
1811
+ if collector:: collecting_debug_information ( ccx) {
1812
+ ccx. record_translation_item_as_generated ( TransItem :: Fn ( Instance {
1813
+ def : def_id,
1814
+ params : & param_substs. types
1815
+ } ) )
1816
+ }
1790
1817
1791
1818
let _icx = push_ctxt ( "trans_closure" ) ;
1792
1819
attributes:: emit_uwtable ( llfndecl, true ) ;
@@ -1795,23 +1822,20 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1795
1822
1796
1823
let ( arena, fcx) : ( TypedArena < _ > , FunctionContext ) ;
1797
1824
arena = TypedArena :: new ( ) ;
1798
- fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, fn_ast_id,
1799
- param_substs, Some ( body. span ) , & arena) ;
1825
+ fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, Some ( def_id) , param_substs, & arena) ;
1800
1826
1801
- if attributes . iter ( ) . any ( |item| item . check_name ( "rustc_mir" ) ) {
1827
+ if fcx . mir . is_some ( ) {
1802
1828
return mir:: trans_mir ( & fcx) ;
1803
1829
}
1804
1830
1805
1831
// cleanup scope for the incoming arguments
1806
- let fn_cleanup_debug_loc = debuginfo:: get_cleanup_debug_loc_for_ast_node ( ccx,
1807
- fn_ast_id,
1808
- body. span ,
1809
- true ) ;
1832
+ let fn_cleanup_debug_loc = debuginfo:: get_cleanup_debug_loc_for_ast_node (
1833
+ ccx, inlined_id, body. span , true ) ;
1810
1834
let arg_scope = fcx. push_custom_cleanup_scope_with_debug_loc ( fn_cleanup_debug_loc) ;
1811
1835
1812
1836
// Set up arguments to the function.
1813
1837
debug ! ( "trans_closure: function: {:?}" , Value ( fcx. llfn) ) ;
1814
- let bcx = fcx. bind_args ( & decl. inputs , abi, closure_env, arg_scope) ;
1838
+ let bcx = fcx. bind_args ( & decl. inputs , abi, inlined_id , closure_env, arg_scope) ;
1815
1839
1816
1840
// Up until here, IR instructions for this function have explicitly not been annotated with
1817
1841
// source code location, so we don't step into call setup code. From here on, source location
@@ -1862,28 +1886,6 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1862
1886
1863
1887
// Insert the mandatory first few basic blocks before lltop.
1864
1888
fcx. finish ( bcx, ret_debug_loc) ;
1865
-
1866
- fn record_translation_item_as_generated < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1867
- node_id : ast:: NodeId ,
1868
- param_substs : & ' tcx Substs < ' tcx > ) {
1869
- if !collector:: collecting_debug_information ( ccx) {
1870
- return ;
1871
- }
1872
-
1873
- let def_id = match ccx. tcx ( ) . node_id_to_type ( node_id) . sty {
1874
- ty:: TyClosure ( def_id, _) => def_id,
1875
- _ => ccx. external_srcs ( )
1876
- . borrow ( )
1877
- . get ( & node_id)
1878
- . map ( |did| * did)
1879
- . unwrap_or_else ( || ccx. tcx ( ) . map . local_def_id ( node_id) ) ,
1880
- } ;
1881
-
1882
- ccx. record_translation_item_as_generated ( TransItem :: Fn ( Instance {
1883
- def : def_id,
1884
- params : & param_substs. types ,
1885
- } ) ) ;
1886
- }
1887
1889
}
1888
1890
1889
1891
/// Creates an LLVM function corresponding to a source language function.
@@ -1892,8 +1894,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1892
1894
body : & hir:: Block ,
1893
1895
llfndecl : ValueRef ,
1894
1896
param_substs : & ' tcx Substs < ' tcx > ,
1895
- id : ast:: NodeId ,
1896
- attrs : & [ ast:: Attribute ] ) {
1897
+ id : ast:: NodeId ) {
1897
1898
let _s = StatRecorder :: new ( ccx, ccx. tcx ( ) . map . path_to_string ( id) . to_string ( ) ) ;
1898
1899
debug ! ( "trans_fn(param_substs={:?})" , param_substs) ;
1899
1900
let _icx = push_ctxt ( "trans_fn" ) ;
@@ -1903,13 +1904,18 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1903
1904
let sig = infer:: normalize_associated_type ( ccx. tcx ( ) , & sig) ;
1904
1905
let abi = fn_ty. fn_abi ( ) ;
1905
1906
let fn_ty = FnType :: new ( ccx, abi, & sig, & [ ] ) ;
1907
+ let def_id = if let Some ( & def_id) = ccx. external_srcs ( ) . borrow ( ) . get ( & id) {
1908
+ def_id
1909
+ } else {
1910
+ ccx. tcx ( ) . map . local_def_id ( id)
1911
+ } ;
1906
1912
trans_closure ( ccx,
1907
1913
decl,
1908
1914
body,
1909
1915
llfndecl,
1910
1916
param_substs,
1917
+ def_id,
1911
1918
id,
1912
- attrs,
1913
1919
fn_ty,
1914
1920
abi,
1915
1921
closure:: ClosureEnv :: NotClosure ) ;
@@ -2001,9 +2007,10 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
2001
2007
2002
2008
let ( arena, fcx) : ( TypedArena < _ > , FunctionContext ) ;
2003
2009
arena = TypedArena :: new ( ) ;
2004
- fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty, ctor_id,
2005
- param_substs, None , & arena) ;
2006
- let bcx = fcx. init ( false ) ;
2010
+ fcx = FunctionContext :: new ( ccx, llfndecl, fn_ty,
2011
+ Some ( ccx. tcx ( ) . map . local_def_id ( ctor_id) ) ,
2012
+ param_substs, & arena) ;
2013
+ let bcx = fcx. init ( false , None ) ;
2007
2014
2008
2015
assert ! ( !fcx. needs_ret_allocas) ;
2009
2016
@@ -2239,7 +2246,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
2239
2246
let empty_substs = tcx. mk_substs ( Substs :: trans_empty ( ) ) ;
2240
2247
let def_id = tcx. map . local_def_id ( item. id ) ;
2241
2248
let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2242
- trans_fn ( ccx, & decl, & body, llfn, empty_substs, item. id , & item . attrs ) ;
2249
+ trans_fn ( ccx, & decl, & body, llfn, empty_substs, item. id ) ;
2243
2250
set_global_section ( ccx, llfn, item) ;
2244
2251
update_linkage ( ccx,
2245
2252
llfn,
@@ -2278,8 +2285,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
2278
2285
let empty_substs = tcx. mk_substs ( Substs :: trans_empty ( ) ) ;
2279
2286
let def_id = tcx. map . local_def_id ( impl_item. id ) ;
2280
2287
let llfn = Callee :: def ( ccx, def_id, empty_substs) . reify ( ccx) . val ;
2281
- trans_fn ( ccx, & sig. decl , body, llfn, empty_substs,
2282
- impl_item. id , & impl_item. attrs ) ;
2288
+ trans_fn ( ccx, & sig. decl , body, llfn, empty_substs, impl_item. id ) ;
2283
2289
update_linkage ( ccx, llfn, Some ( impl_item. id ) ,
2284
2290
if is_origin {
2285
2291
OriginalTranslation
0 commit comments