Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d662083a
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d662083a
编写于
8月 14, 2018
作者:
M
Michael Woerister
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use CGU name as LLVM module name and add some caching to CGU name generation.
上级
e192e498
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
208 addition
and
170 deletion
+208
-170
src/librustc/mir/mono.rs
src/librustc/mir/mono.rs
+92
-74
src/librustc_codegen_llvm/back/link.rs
src/librustc_codegen_llvm/back/link.rs
+0
-7
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/lto.rs
+5
-6
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/back/write.rs
+1
-2
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/base.rs
+24
-43
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/lib.rs
+1
-3
src/librustc_incremental/assert_module_sources.rs
src/librustc_incremental/assert_module_sources.rs
+5
-5
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/monomorphize/partitioning.rs
+79
-29
src/test/ui/lto-duplicate-symbols.stderr
src/test/ui/lto-duplicate-symbols.stderr
+1
-1
未找到文件。
src/librustc/mir/mono.rs
浏览文件 @
d662083a
...
...
@@ -171,80 +171,6 @@ pub fn modify_size_estimate(&mut self, delta: usize) {
self
.size_estimate
=
Some
(
size_estimate
+
delta
);
}
}
/// CGU names should fulfill the following requirements:
/// - They should be able to act as a file name on any kind of file system
/// - They should not collide with other CGU names, even for different versions
/// of the same crate.
///
/// Consequently, we don't use special characters except for '.' and '-' and we
/// prefix each name with the crate-name and crate-disambiguator.
///
/// This function will build CGU names of the form:
///
/// ```
/// <crate-name>.<crate-disambiguator>(-<component>)*[.<special-suffix>]
/// ```
///
/// The '.' before `<special-suffix>` makes sure that names with a special
/// suffix can never collide with a name built out of regular Rust
/// identifiers (e.g. module paths).
pub
fn
build_cgu_name
<
I
,
C
,
S
>
(
tcx
:
TyCtxt
,
cnum
:
CrateNum
,
components
:
I
,
special_suffix
:
Option
<
S
>
)
->
InternedString
where
I
:
IntoIterator
<
Item
=
C
>
,
C
:
fmt
::
Display
,
S
:
fmt
::
Display
,
{
let
cgu_name
=
CodegenUnit
::
build_cgu_name_no_mangle
(
tcx
,
cnum
,
components
,
special_suffix
);
if
tcx
.sess.opts.debugging_opts.human_readable_cgu_names
{
cgu_name
}
else
{
let
cgu_name
=
&
cgu_name
.as_str
()[
..
];
Symbol
::
intern
(
&
CodegenUnit
::
mangle_name
(
cgu_name
))
.as_interned_str
()
}
}
/// Same as `CodegenUnit::build_cgu_name()` but will never mangle the
/// resulting name.
pub
fn
build_cgu_name_no_mangle
<
I
,
C
,
S
>
(
tcx
:
TyCtxt
,
cnum
:
CrateNum
,
components
:
I
,
special_suffix
:
Option
<
S
>
)
->
InternedString
where
I
:
IntoIterator
<
Item
=
C
>
,
C
:
fmt
::
Display
,
S
:
fmt
::
Display
,
{
use
std
::
fmt
::
Write
;
let
mut
cgu_name
=
String
::
with_capacity
(
64
);
// Start out with the crate name and disambiguator
write!
(
cgu_name
,
"{}.{}"
,
tcx
.crate_name
(
cnum
),
tcx
.crate_disambiguator
(
cnum
))
.unwrap
();
// Add the components
for
component
in
components
{
write!
(
cgu_name
,
"-{}"
,
component
)
.unwrap
();
}
if
let
Some
(
special_suffix
)
=
special_suffix
{
// We add a dot in here so it cannot clash with anything in a regular
// Rust identifier
write!
(
cgu_name
,
".{}"
,
special_suffix
)
.unwrap
();
}
Symbol
::
intern
(
&
cgu_name
[
..
])
.as_interned_str
()
}
}
impl
<
'a
,
'tcx
>
HashStable
<
StableHashingContext
<
'a
>>
for
CodegenUnit
<
'tcx
>
{
...
...
@@ -314,3 +240,95 @@ pub fn extend(&mut self, stats: Stats) {
self
.fn_stats
.extend
(
stats
.fn_stats
);
}
}
pub
struct
CodegenUnitNameBuilder
<
'a
,
'gcx
:
'tcx
,
'tcx
:
'a
>
{
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
cache
:
FxHashMap
<
CrateNum
,
String
>
,
}
impl
<
'a
,
'gcx
:
'tcx
,
'tcx
:
'a
>
CodegenUnitNameBuilder
<
'a
,
'gcx
,
'tcx
>
{
pub
fn
new
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
)
->
Self
{
CodegenUnitNameBuilder
{
tcx
,
cache
:
FxHashMap
(),
}
}
/// CGU names should fulfill the following requirements:
/// - They should be able to act as a file name on any kind of file system
/// - They should not collide with other CGU names, even for different versions
/// of the same crate.
///
/// Consequently, we don't use special characters except for '.' and '-' and we
/// prefix each name with the crate-name and crate-disambiguator.
///
/// This function will build CGU names of the form:
///
/// ```
/// <crate-name>.<crate-disambiguator>(-<component>)*[.<special-suffix>]
/// ```
///
/// The '.' before `<special-suffix>` makes sure that names with a special
/// suffix can never collide with a name built out of regular Rust
/// identifiers (e.g. module paths).
pub
fn
build_cgu_name
<
I
,
C
,
S
>
(
&
mut
self
,
cnum
:
CrateNum
,
components
:
I
,
special_suffix
:
Option
<
S
>
)
->
InternedString
where
I
:
IntoIterator
<
Item
=
C
>
,
C
:
fmt
::
Display
,
S
:
fmt
::
Display
,
{
let
cgu_name
=
self
.build_cgu_name_no_mangle
(
cnum
,
components
,
special_suffix
);
if
self
.tcx.sess.opts.debugging_opts.human_readable_cgu_names
{
cgu_name
}
else
{
let
cgu_name
=
&
cgu_name
.as_str
()[
..
];
Symbol
::
intern
(
&
CodegenUnit
::
mangle_name
(
cgu_name
))
.as_interned_str
()
}
}
/// Same as `CodegenUnit::build_cgu_name()` but will never mangle the
/// resulting name.
pub
fn
build_cgu_name_no_mangle
<
I
,
C
,
S
>
(
&
mut
self
,
cnum
:
CrateNum
,
components
:
I
,
special_suffix
:
Option
<
S
>
)
->
InternedString
where
I
:
IntoIterator
<
Item
=
C
>
,
C
:
fmt
::
Display
,
S
:
fmt
::
Display
,
{
use
std
::
fmt
::
Write
;
let
mut
cgu_name
=
String
::
with_capacity
(
64
);
// Start out with the crate name and disambiguator
let
tcx
=
self
.tcx
;
let
crate_prefix
=
self
.cache
.entry
(
cnum
)
.or_insert_with
(||
{
let
crate_disambiguator
=
format!
(
"{}"
,
tcx
.crate_disambiguator
(
cnum
));
// Using a shortened disambiguator of about 40 bits
format!
(
"{}.{}"
,
tcx
.crate_name
(
cnum
),
&
crate_disambiguator
[
0
..
8
])
});
write!
(
cgu_name
,
"{}"
,
crate_prefix
)
.unwrap
();
// Add the components
for
component
in
components
{
write!
(
cgu_name
,
"-{}"
,
component
)
.unwrap
();
}
if
let
Some
(
special_suffix
)
=
special_suffix
{
// We add a dot in here so it cannot clash with anything in a regular
// Rust identifier
write!
(
cgu_name
,
".{}"
,
special_suffix
)
.unwrap
();
}
Symbol
::
intern
(
&
cgu_name
[
..
])
.as_interned_str
()
}
}
src/librustc_codegen_llvm/back/link.rs
浏览文件 @
d662083a
...
...
@@ -46,13 +46,6 @@
use
std
::
str
;
use
syntax
::
attr
;
/// The LLVM module name containing crate-metadata. This includes a `.` on
/// purpose, so it cannot clash with the name of a user-defined module.
pub
const
METADATA_MODULE_NAME
:
&
'static
str
=
"crate.metadata"
;
// same as for metadata above, but for allocator shim
pub
const
ALLOCATOR_MODULE_NAME
:
&
'static
str
=
"crate.allocator"
;
pub
use
rustc_codegen_utils
::
link
::{
find_crate_name
,
filename_for_input
,
default_output_for_target
,
invalid_output_for_target
,
build_link_meta
,
out_filename
,
check_file_is_writeable
};
...
...
src/librustc_codegen_llvm/back/lto.rs
浏览文件 @
d662083a
...
...
@@ -242,7 +242,7 @@ fn fat_lto(cgcx: &CodegenContext,
let
llvm
=
module
.llvm
()
.expect
(
"can't lto pre-codegened modules"
);
(
&
llvm
.llcx
,
llvm
.llmod
())
};
info!
(
"using {:?} as a base module"
,
module
.
llmod_id
);
info!
(
"using {:?} as a base module"
,
module
.
name
);
// The linking steps below may produce errors and diagnostics within LLVM
// which we'd like to handle and print, so set up our diagnostic handlers
...
...
@@ -257,7 +257,7 @@ fn fat_lto(cgcx: &CodegenContext,
for
module
in
modules
{
let
llvm
=
module
.llvm
()
.expect
(
"can't lto pre-codegened modules"
);
let
buffer
=
ModuleBuffer
::
new
(
llvm
.llmod
());
let
llmod_id
=
CString
::
new
(
&
module
.
llmod_id
[
..
])
.unwrap
();
let
llmod_id
=
CString
::
new
(
&
module
.
name
[
..
])
.unwrap
();
serialized_modules
.push
((
SerializedModule
::
Local
(
buffer
),
llmod_id
));
}
...
...
@@ -384,9 +384,9 @@ fn thin_lto(diag_handler: &Handler,
// the most expensive portion of this small bit of global
// analysis!
for
(
i
,
module
)
in
modules
.iter
()
.enumerate
()
{
info!
(
"local module: {} - {}"
,
i
,
module
.
llmod_id
);
info!
(
"local module: {} - {}"
,
i
,
module
.
name
);
let
llvm
=
module
.llvm
()
.expect
(
"can't lto precodegened module"
);
let
name
=
CString
::
new
(
module
.
llmod_id
.clone
())
.unwrap
();
let
name
=
CString
::
new
(
module
.
name
.clone
())
.unwrap
();
let
buffer
=
ThinBuffer
::
new
(
llvm
.llmod
());
thin_modules
.push
(
llvm
::
ThinLTOModule
{
identifier
:
name
.as_ptr
(),
...
...
@@ -395,7 +395,7 @@ fn thin_lto(diag_handler: &Handler,
});
thin_buffers
.push
(
buffer
);
module_names
.push
(
name
);
timeline
.record
(
&
module
.
llmod_id
);
timeline
.record
(
&
module
.
name
);
}
// FIXME: All upstream crates are deserialized internally in the
...
...
@@ -668,7 +668,6 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
llcx
,
tm
,
}),
llmod_id
:
self
.name
()
.to_string
(),
name
:
self
.name
()
.to_string
(),
kind
:
ModuleKind
::
Regular
,
};
...
...
src/librustc_codegen_llvm/back/write.rs
浏览文件 @
d662083a
...
...
@@ -728,7 +728,7 @@ unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
if
config
.emit_bc_compressed
{
let
dst
=
bc_out
.with_extension
(
RLIB_BYTECODE_EXTENSION
);
let
data
=
bytecode
::
encode
(
&
module
.
llmod_id
,
data
);
let
data
=
bytecode
::
encode
(
&
module
.
name
,
data
);
if
let
Err
(
e
)
=
fs
::
write
(
&
dst
,
data
)
{
diag_handler
.err
(
&
format!
(
"failed to write bytecode: {}"
,
e
));
}
...
...
@@ -1338,7 +1338,6 @@ fn execute_work_item(cgcx: &CodegenContext,
assert_eq!
(
bytecode_compressed
.is_some
(),
config
.emit_bc_compressed
);
Ok
(
WorkItemResult
::
Compiled
(
CompiledModule
{
llmod_id
:
module
.llmod_id
.clone
(),
name
:
module_name
,
kind
:
ModuleKind
::
Regular
,
pre_existing
:
true
,
...
...
src/librustc_codegen_llvm/base.rs
浏览文件 @
d662083a
...
...
@@ -36,7 +36,7 @@
use
rustc
::
hir
::
def_id
::{
CrateNum
,
DefId
,
LOCAL_CRATE
};
use
rustc
::
middle
::
lang_items
::
StartFnLangItem
;
use
rustc
::
middle
::
weak_lang_items
;
use
rustc
::
mir
::
mono
::{
Linkage
,
Visibility
,
Stats
};
use
rustc
::
mir
::
mono
::{
Linkage
,
Visibility
,
Stats
,
CodegenUnitNameBuilder
};
use
rustc
::
middle
::
cstore
::{
EncodedMetadata
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::
layout
::{
self
,
Align
,
TyLayout
,
LayoutOf
};
...
...
@@ -742,19 +742,23 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
crate_hash
=
tcx
.crate_hash
(
LOCAL_CRATE
);
let
link_meta
=
link
::
build_link_meta
(
crate_hash
);
let
cgu_name_builder
=
&
mut
CodegenUnitNameBuilder
::
new
(
tcx
);
// Codegen the metadata.
tcx
.sess
.profiler
(|
p
|
p
.start_activity
(
ProfileCategory
::
Codegen
));
let
llmod_id
=
"metadata"
;
let
metadata_llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
llmod_id
);
let
metadata_cgu_name
=
cgu_name_builder
.build_cgu_name
(
LOCAL_CRATE
,
&
[
"crate"
],
Some
(
"metadata"
))
.as_str
()
.to_string
();
let
metadata_llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
&
metadata_cgu_name
);
let
metadata
=
time
(
tcx
.sess
,
"write metadata"
,
||
{
write_metadata
(
tcx
,
&
metadata_llvm_module
,
&
link_meta
)
});
tcx
.sess
.profiler
(|
p
|
p
.end_activity
(
ProfileCategory
::
Codegen
));
let
metadata_module
=
ModuleCodegen
{
name
:
link
::
METADATA_MODULE_NAME
.to_string
(),
llmod_id
:
llmod_id
.to_string
(),
name
:
metadata_cgu_name
,
source
:
ModuleSource
::
Codegened
(
metadata_llvm_module
),
kind
:
ModuleKind
::
Metadata
,
};
...
...
@@ -833,20 +837,22 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
allocator_module
=
if
any_dynamic_crate
{
None
}
else
if
let
Some
(
kind
)
=
*
tcx
.sess.allocator_kind
.get
()
{
unsafe
{
let
llmod_id
=
"allocator"
;
let
modules
=
ModuleLlvm
::
new
(
tcx
.sess
,
llmod_id
);
time
(
tcx
.sess
,
"write allocator module"
,
||
{
let
llmod_id
=
cgu_name_builder
.build_cgu_name
(
LOCAL_CRATE
,
&
[
"crate"
],
Some
(
"allocator"
))
.as_str
()
.to_string
();
let
modules
=
ModuleLlvm
::
new
(
tcx
.sess
,
&
llmod_id
);
time
(
tcx
.sess
,
"write allocator module"
,
||
{
unsafe
{
allocator
::
codegen
(
tcx
,
&
modules
,
kind
)
});
}
});
Some
(
ModuleCodegen
{
name
:
link
::
ALLOCATOR_MODULE_NAME
.to_string
(),
llmod_id
:
llmod_id
.to_string
(),
source
:
ModuleSource
::
Codegened
(
modules
),
kind
:
ModuleKind
::
Allocator
,
})
}
Some
(
ModuleCodegen
{
name
:
llmod_id
,
source
:
ModuleSource
::
Codegened
(
modules
),
kind
:
ModuleKind
::
Allocator
,
})
}
else
{
None
};
...
...
@@ -889,21 +895,10 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// succeed it means that none of the dependencies has changed
// and we can safely re-use.
if
let
Some
(
dep_node_index
)
=
tcx
.dep_graph
.try_mark_green
(
tcx
,
dep_node
)
{
// Append ".rs" to LLVM module identifier.
//
// LLVM code generator emits a ".file filename" directive
// for ELF backends. Value of the "filename" is set as the
// LLVM module identifier. Due to a LLVM MC bug[1], LLVM
// crashes if the module identifier is same as other symbols
// such as a function name in the module.
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
let
llmod_id
=
format!
(
"{}.rs"
,
cgu
.name
());
let
module
=
ModuleCodegen
{
name
:
cgu
.name
()
.to_string
(),
source
:
ModuleSource
::
Preexisting
(
buf
),
kind
:
ModuleKind
::
Regular
,
llmod_id
,
};
tcx
.dep_graph
.mark_loaded_from_cache
(
dep_node_index
,
true
);
write
::
submit_codegened_module_to_llvm
(
tcx
,
module
,
0
);
...
...
@@ -1212,21 +1207,8 @@ fn module_codegen<'a, 'tcx>(
{
let
cgu_name
=
cgu
.name
()
.to_string
();
// Append ".rs" to LLVM module identifier.
//
// LLVM code generator emits a ".file filename" directive
// for ELF backends. Value of the "filename" is set as the
// LLVM module identifier. Due to a LLVM MC bug[1], LLVM
// crashes if the module identifier is same as other symbols
// such as a function name in the module.
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
let
llmod_id
=
format!
(
"{}-{}.rs"
,
cgu
.name
(),
tcx
.crate_disambiguator
(
LOCAL_CRATE
)
.to_fingerprint
()
.to_hex
());
// Instantiate monomorphizations without filling out definitions yet...
let
llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
&
llmod_id
);
let
llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
&
cgu_name
);
let
stats
=
{
let
cx
=
CodegenCx
::
new
(
tcx
,
cgu
,
&
llvm_module
);
let
mono_items
=
cx
.codegen_unit
...
...
@@ -1282,7 +1264,6 @@ fn module_codegen<'a, 'tcx>(
name
:
cgu_name
,
source
:
ModuleSource
::
Codegened
(
llvm_module
),
kind
:
ModuleKind
::
Regular
,
llmod_id
,
})
}
}
...
...
src/librustc_codegen_llvm/lib.rs
浏览文件 @
d662083a
...
...
@@ -269,8 +269,8 @@ struct ModuleCodegen {
/// unique amongst **all** crates. Therefore, it should contain
/// something unique to this crate (e.g., a module path) as well
/// as the crate name and disambiguator.
/// We currently generate these names via CodegenUnit::build_cgu_name().
name
:
String
,
llmod_id
:
String
,
source
:
ModuleSource
,
kind
:
ModuleKind
,
}
...
...
@@ -317,7 +317,6 @@ fn into_compiled_module(self,
};
CompiledModule
{
llmod_id
:
self
.llmod_id
,
name
:
self
.name
.clone
(),
kind
:
self
.kind
,
pre_existing
,
...
...
@@ -331,7 +330,6 @@ fn into_compiled_module(self,
#[derive(Debug)]
struct
CompiledModule
{
name
:
String
,
llmod_id
:
String
,
kind
:
ModuleKind
,
pre_existing
:
bool
,
object
:
Option
<
PathBuf
>
,
...
...
src/librustc_incremental/assert_module_sources.rs
浏览文件 @
d662083a
...
...
@@ -29,7 +29,7 @@
use
rustc
::
hir
::
def_id
::
LOCAL_CRATE
;
use
rustc
::
dep_graph
::{
DepNode
,
DepConstructor
};
use
rustc
::
mir
::
mono
::
CodegenUnit
;
use
rustc
::
mir
::
mono
::
CodegenUnit
NameBuilder
;
use
rustc
::
ty
::
TyCtxt
;
use
syntax
::
ast
;
use
rustc
::
ich
::{
ATTR_PARTITION_REUSED
,
ATTR_PARTITION_CODEGENED
};
...
...
@@ -94,10 +94,10 @@ fn check_attr(&self, attr: &ast::Attribute) {
// Remove the crate name
assert_eq!
(
cgu_path_components
.remove
(
0
),
crate_name
);
let
cgu_name
=
CodegenUnit
::
build_cgu_name
(
self
.tcx
,
LOCAL_CRATE
,
cgu_path_components
,
cgu_special_suffix
);
let
cgu_name
_builder
=
&
mut
CodegenUnitNameBuilder
::
new
(
self
.tcx
);
let
cgu_name
=
cgu_name_builder
.build_cgu_name
(
LOCAL_CRATE
,
cgu_path_components
,
cgu_special_suffix
);
debug!
(
"mapping '{}' to cgu name '{}'"
,
self
.field
(
attr
,
MODULE
),
cgu_name
);
...
...
src/librustc_mir/monomorphize/partitioning.rs
浏览文件 @
d662083a
...
...
@@ -105,9 +105,9 @@
use
monomorphize
::
collector
::
InliningMap
;
use
rustc
::
dep_graph
::
WorkProductId
;
use
rustc
::
hir
::
CodegenFnAttrFlags
;
use
rustc
::
hir
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
rustc
::
hir
::
def_id
::{
DefId
,
LOCAL_CRATE
,
CRATE_DEF_INDEX
};
use
rustc
::
hir
::
map
::
DefPathData
;
use
rustc
::
mir
::
mono
::{
Linkage
,
Visibility
};
use
rustc
::
mir
::
mono
::{
Linkage
,
Visibility
,
CodegenUnitNameBuilder
};
use
rustc
::
middle
::
exported_symbols
::
SymbolExportLevel
;
use
rustc
::
ty
::{
self
,
TyCtxt
,
InstanceDef
};
use
rustc
::
ty
::
item_path
::
characteristic_def_id_of_type
;
...
...
@@ -203,8 +203,8 @@ fn as_codegen_unit(&self) -> &CodegenUnit<'tcx> {
}
// Anything we can't find a proper codegen unit for goes into this.
fn
fallback_cgu_name
(
tcx
:
TyCtxt
)
->
InternedString
{
CodegenUnit
::
build_cgu_name
(
tcx
,
LOCAL_CRATE
,
&
[
"fallback"
],
Some
(
"cgu"
))
fn
fallback_cgu_name
(
name_builder
:
&
mut
CodegenUnitNameBuilder
)
->
InternedString
{
name_builder
.build_cgu_name
(
LOCAL_CRATE
,
&
[
"fallback"
],
Some
(
"cgu"
))
}
pub
fn
partition
<
'a
,
'tcx
,
I
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
...
...
@@ -300,6 +300,9 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
export_generics
=
tcx
.sess.opts
.share_generics
()
&&
tcx
.local_crate_exports_generics
();
let
cgu_name_builder
=
&
mut
CodegenUnitNameBuilder
::
new
(
tcx
);
let
cgu_name_cache
=
&
mut
FxHashMap
();
for
mono_item
in
mono_items
{
match
mono_item
.instantiation_mode
(
tcx
)
{
InstantiationMode
::
GloballyShared
{
..
}
=>
{}
...
...
@@ -311,8 +314,12 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mono_item
.is_generic_fn
();
let
codegen_unit_name
=
match
characteristic_def_id
{
Some
(
def_id
)
=>
compute_codegen_unit_name
(
tcx
,
def_id
,
is_volatile
),
None
=>
fallback_cgu_name
(
tcx
),
Some
(
def_id
)
=>
compute_codegen_unit_name
(
tcx
,
cgu_name_builder
,
def_id
,
is_volatile
,
cgu_name_cache
),
None
=>
fallback_cgu_name
(
cgu_name_builder
),
};
let
codegen_unit
=
codegen_units
.entry
(
codegen_unit_name
.clone
())
...
...
@@ -336,7 +343,7 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// always ensure we have at least one CGU; otherwise, if we have a
// crate with just types (for example), we could wind up with no CGU
if
codegen_units
.is_empty
()
{
let
codegen_unit_name
=
fallback_cgu_name
(
tcx
);
let
codegen_unit_name
=
fallback_cgu_name
(
cgu_name_builder
);
codegen_units
.insert
(
codegen_unit_name
.clone
(),
CodegenUnit
::
new
(
codegen_unit_name
.clone
()));
}
...
...
@@ -574,14 +581,15 @@ fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
}
}
let
cgu_name_builder
=
&
mut
CodegenUnitNameBuilder
::
new
(
tcx
);
for
(
index
,
cgu
)
in
codegen_units
.iter_mut
()
.enumerate
()
{
cgu
.set_name
(
numbered_codegen_unit_name
(
tcx
,
index
));
cgu
.set_name
(
numbered_codegen_unit_name
(
cgu_name_builder
,
index
));
}
}
fn
place_inlined_mono_items
<
'tcx
>
(
initial_partitioning
:
PreInliningPartitioning
<
'tcx
>
,
inlining_map
:
&
InliningMap
<
'tcx
>
)
->
PostInliningPartitioning
<
'tcx
>
{
inlining_map
:
&
InliningMap
<
'tcx
>
)
->
PostInliningPartitioning
<
'tcx
>
{
let
mut
new_partitioning
=
Vec
::
new
();
let
mut
mono_item_placements
=
FxHashMap
();
...
...
@@ -775,30 +783,72 @@ fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn
compute_codegen_unit_name
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
def_id
:
DefId
,
volatile
:
bool
)
->
InternedString
{
let
def_path
=
tcx
.def_path
(
def_id
);
let
components
=
def_path
.data
.iter
()
.take_while
(|
part
|
{
match
part
.data
{
DefPathData
::
Module
(
..
)
=>
true
,
_
=>
false
,
type
CguNameCache
=
FxHashMap
<
(
DefId
,
bool
),
InternedString
>
;
fn
compute_codegen_unit_name
(
tcx
:
TyCtxt
,
name_builder
:
&
mut
CodegenUnitNameBuilder
,
def_id
:
DefId
,
volatile
:
bool
,
cache
:
&
mut
CguNameCache
)
->
InternedString
{
// Find the innermost module that is not nested within a function
let
mut
current_def_id
=
def_id
;
let
mut
cgu_def_id
=
None
;
// Walk backwards from the item we want to find the module for:
loop
{
let
def_key
=
tcx
.def_key
(
current_def_id
);
match
def_key
.disambiguated_data.data
{
DefPathData
::
Module
(
..
)
=>
{
if
cgu_def_id
.is_none
()
{
cgu_def_id
=
Some
(
current_def_id
);
}
}
DefPathData
::
CrateRoot
{
..
}
=>
{
if
cgu_def_id
.is_none
()
{
// If we have not found a module yet, take the crate root.
cgu_def_id
=
Some
(
DefId
{
krate
:
def_id
.krate
,
index
:
CRATE_DEF_INDEX
,
});
}
break
}
_
=>
{
// If we encounter something that is not a module, throw away
// any module that we've found so far because we now know that
// it is nested within something else.
cgu_def_id
=
None
;
}
}
})
.map
(|
part
|
part
.data
.as_interned_str
());
let
volatile_suffix
=
if
volatile
{
Some
(
"volatile"
)
}
else
{
None
};
current_def_id
.index
=
def_key
.parent
.unwrap
();
}
let
cgu_def_id
=
cgu_def_id
.unwrap
();
cache
.entry
((
cgu_def_id
,
volatile
))
.or_insert_with
(||
{
let
def_path
=
tcx
.def_path
(
cgu_def_id
);
let
components
=
def_path
.data
.iter
()
.map
(|
part
|
part
.data
.as_interned_str
());
let
volatile_suffix
=
if
volatile
{
Some
(
"volatile"
)
}
else
{
None
};
CodegenUnit
::
build_cgu_name
(
tcx
,
def_path
.krate
,
components
,
volatile_suffix
)
name_builder
.build_cgu_name
(
def_path
.krate
,
components
,
volatile_suffix
)
})
.clone
()
}
fn
numbered_codegen_unit_name
(
tcx
:
TyCtxt
,
index
:
usize
)
->
InternedString
{
CodegenUnit
::
build_cgu_name_no_mangle
(
tcx
,
LOCAL_CRATE
,
&
[
"cgu"
],
Some
(
index
))
fn
numbered_codegen_unit_name
(
name_builder
:
&
mut
CodegenUnitNameBuilder
,
index
:
usize
)
->
InternedString
{
name_builder
.build_cgu_name_no_mangle
(
LOCAL_CRATE
,
&
[
"cgu"
],
Some
(
index
))
}
fn
debug_dump
<
'a
,
'b
,
'tcx
,
I
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
...
...
src/test/ui/lto-duplicate-symbols.stderr
浏览文件 @
d662083a
warning: Linking globals named 'foo': symbol multiply defined!
error: failed to load bc of "lto_duplicate_symbols1
0-8787f43e282added376259c1adb08b80.rs
":
error: failed to load bc of "lto_duplicate_symbols1
.3a1fbbbh-cgu.0
":
error: aborting due to previous error
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录