Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
249d5aca
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
249d5aca
编写于
6月 27, 2018
作者:
I
Irina Popa
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_codegen_llvm: use safe references for Context and Module.
上级
af04e942
变更
13
展开全部
显示空白变更内容
内联
并排
Showing
13 changed file
with
549 addition
and
556 deletion
+549
-556
src/librustc_codegen_llvm/allocator.rs
src/librustc_codegen_llvm/allocator.rs
+2
-2
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/lto.rs
+166
-160
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/back/write.rs
+177
-180
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/base.rs
+26
-46
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/common.rs
+3
-3
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/context.rs
+51
-59
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
+1
-1
src/librustc_codegen_llvm/debuginfo/mod.rs
src/librustc_codegen_llvm/debuginfo/mod.rs
+6
-6
src/librustc_codegen_llvm/debuginfo/utils.rs
src/librustc_codegen_llvm/debuginfo/utils.rs
+1
-1
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/lib.rs
+29
-7
src/librustc_codegen_llvm/llvm/ffi.rs
src/librustc_codegen_llvm/llvm/ffi.rs
+82
-86
src/librustc_codegen_llvm/llvm/mod.rs
src/librustc_codegen_llvm/llvm/mod.rs
+1
-1
src/librustc_codegen_llvm/type_.rs
src/librustc_codegen_llvm/type_.rs
+4
-4
未找到文件。
src/librustc_codegen_llvm/allocator.rs
浏览文件 @
249d5aca
...
...
@@ -20,8 +20,8 @@
use
llvm
::{
self
,
False
,
True
};
pub
(
crate
)
unsafe
fn
codegen
(
tcx
:
TyCtxt
,
mods
:
&
ModuleLlvm
,
kind
:
AllocatorKind
)
{
let
llcx
=
mods
.llcx
;
let
llmod
=
mods
.llmod
;
let
llcx
=
&*
mods
.llcx
;
let
llmod
=
mods
.llmod
()
;
let
usize
=
match
&
tcx
.sess.target.target.target_pointer_width
[
..
]
{
"16"
=>
llvm
::
LLVMInt16TypeInContext
(
llcx
),
"32"
=>
llvm
::
LLVMInt32TypeInContext
(
llcx
),
...
...
src/librustc_codegen_llvm/back/lto.rs
浏览文件 @
249d5aca
...
...
@@ -14,7 +14,7 @@
use
back
::
write
;
use
errors
::{
FatalError
,
Handler
};
use
llvm
::
archive_ro
::
ArchiveRO
;
use
llvm
::{
ModuleRef
,
TargetMachineRef
,
True
,
False
};
use
llvm
::{
TargetMachineRef
,
True
,
False
};
use
llvm
;
use
rustc
::
hir
::
def_id
::
LOCAL_CRATE
;
use
rustc
::
middle
::
exported_symbols
::
SymbolExportLevel
;
...
...
@@ -73,11 +73,13 @@ pub(crate) unsafe fn optimize(&mut self,
match
*
self
{
LtoModuleCodegen
::
Fat
{
ref
mut
module
,
..
}
=>
{
let
module
=
module
.take
()
.unwrap
();
{
let
config
=
cgcx
.config
(
module
.kind
);
let
llmod
=
module
.llvm
()
.unwrap
()
.llmod
;
let
tm
=
module
.llvm
()
.unwrap
()
.tm
;
let
llmod
=
module
.llvm
()
.unwrap
()
.llmod
()
;
let
tm
=
&*
module
.llvm
()
.unwrap
()
.tm
;
run_pass_manager
(
cgcx
,
tm
,
llmod
,
config
,
false
);
timeline
.record
(
"fat-done"
);
}
Ok
(
module
)
}
LtoModuleCodegen
::
Thin
(
ref
mut
thin
)
=>
thin
.optimize
(
cgcx
,
timeline
),
...
...
@@ -223,14 +225,16 @@ fn fat_lto(cgcx: &CodegenContext,
.filter
(|
&
(
_
,
module
)|
module
.kind
==
ModuleKind
::
Regular
)
.map
(|(
i
,
module
)|
{
let
cost
=
unsafe
{
llvm
::
LLVMRustModuleCost
(
module
.llvm
()
.unwrap
()
.llmod
)
llvm
::
LLVMRustModuleCost
(
module
.llvm
()
.unwrap
()
.llmod
()
)
};
(
cost
,
i
)
})
.max
()
.expect
(
"must be codegen'ing at least one module"
);
let
module
=
modules
.remove
(
costliest_module
);
let
llmod
=
module
.llvm
()
.expect
(
"can't lto pre-codegened modules"
)
.llmod
;
let
mut
serialized_bitcode
=
Vec
::
new
();
{
let
llmod
=
module
.llvm
()
.expect
(
"can't lto pre-codegened modules"
)
.llmod
();
info!
(
"using {:?} as a base module"
,
module
.llmod_id
);
// For all other modules we codegened we'll need to link them into our own
...
...
@@ -240,7 +244,7 @@ fn fat_lto(cgcx: &CodegenContext,
// them later. Not great but hey, that's why it's "fat" LTO, right?
for
module
in
modules
{
let
llvm
=
module
.llvm
()
.expect
(
"can't lto pre-codegened modules"
);
let
buffer
=
ModuleBuffer
::
new
(
llvm
.llmod
);
let
buffer
=
ModuleBuffer
::
new
(
llvm
.llmod
()
);
let
llmod_id
=
CString
::
new
(
&
module
.llmod_id
[
..
])
.unwrap
();
serialized_modules
.push
((
SerializedModule
::
Local
(
buffer
),
llmod_id
));
}
...
...
@@ -249,7 +253,6 @@ fn fat_lto(cgcx: &CodegenContext,
// above, this is all mostly handled in C++. Like above, though, we don't
// know much about the memory management here so we err on the side of being
// save and persist everything with the original module.
let
mut
serialized_bitcode
=
Vec
::
new
();
let
mut
linker
=
Linker
::
new
(
llmod
);
for
(
bc_decoded
,
name
)
in
serialized_modules
{
info!
(
"linking {:?}"
,
name
);
...
...
@@ -283,6 +286,7 @@ fn fat_lto(cgcx: &CodegenContext,
cgcx
.save_temp_bitcode
(
&
module
,
"lto.after-nounwind"
);
}
timeline
.record
(
"passes"
);
}
Ok
(
vec!
[
LtoModuleCodegen
::
Fat
{
module
:
Some
(
module
),
...
...
@@ -293,7 +297,7 @@ fn fat_lto(cgcx: &CodegenContext,
struct
Linker
(
llvm
::
LinkerRef
);
impl
Linker
{
fn
new
(
llmod
:
ModuleRef
)
->
Linker
{
fn
new
(
llmod
:
&
llvm
::
Module
)
->
Linker
{
unsafe
{
Linker
(
llvm
::
LLVMRustLinkerNew
(
llmod
))
}
}
...
...
@@ -371,7 +375,7 @@ fn thin_lto(diag_handler: &Handler,
info!
(
"local module: {} - {}"
,
i
,
module
.llmod_id
);
let
llvm
=
module
.llvm
()
.expect
(
"can't lto precodegened module"
);
let
name
=
CString
::
new
(
module
.llmod_id
.clone
())
.unwrap
();
let
buffer
=
ThinBuffer
::
new
(
llvm
.llmod
);
let
buffer
=
ThinBuffer
::
new
(
llvm
.llmod
()
);
thin_modules
.push
(
llvm
::
ThinLTOModule
{
identifier
:
name
.as_ptr
(),
data
:
buffer
.data
()
.as_ptr
(),
...
...
@@ -449,7 +453,7 @@ fn thin_lto(diag_handler: &Handler,
fn
run_pass_manager
(
cgcx
:
&
CodegenContext
,
tm
:
TargetMachineRef
,
llmod
:
ModuleRef
,
llmod
:
&
llvm
::
Module
,
config
:
&
ModuleConfig
,
thin
:
bool
)
{
// Now we have one massive module inside of llmod. Time to run the
...
...
@@ -531,7 +535,7 @@ unsafe impl Send for ModuleBuffer {}
unsafe
impl
Sync
for
ModuleBuffer
{}
impl
ModuleBuffer
{
pub
fn
new
(
m
:
ModuleRef
)
->
ModuleBuffer
{
pub
fn
new
(
m
:
&
llvm
::
Module
)
->
ModuleBuffer
{
ModuleBuffer
(
unsafe
{
llvm
::
LLVMRustModuleBufferCreate
(
m
)
})
...
...
@@ -583,7 +587,7 @@ unsafe impl Send for ThinBuffer {}
unsafe
impl
Sync
for
ThinBuffer
{}
impl
ThinBuffer
{
pub
fn
new
(
m
:
ModuleRef
)
->
ThinBuffer
{
pub
fn
new
(
m
:
&
llvm
::
Module
)
->
ThinBuffer
{
unsafe
{
let
buffer
=
llvm
::
LLVMRustThinLTOBufferCreate
(
m
);
ThinBuffer
(
buffer
)
...
...
@@ -640,19 +644,18 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
// crates but for locally codegened modules we may be able to reuse
// that LLVM Context and Module.
let
llcx
=
llvm
::
LLVMRustContextCreate
(
cgcx
.fewer_names
);
let
llmod
=
llvm
::
LLVMRustParseBitcodeForThinLTO
(
let
llmod
_raw
=
llvm
::
LLVMRustParseBitcodeForThinLTO
(
llcx
,
self
.data
()
.as_ptr
(),
self
.data
()
.len
(),
self
.shared.module_names
[
self
.idx
]
.as_ptr
(),
);
if
llmod
.is_null
()
{
)
.ok_or_else
(||
{
let
msg
=
"failed to parse bitcode for thin LTO module"
.to_string
();
return
Err
(
write
::
llvm_err
(
&
diag_handler
,
msg
));
}
write
::
llvm_err
(
&
diag_handler
,
msg
)
}
)
?
as
*
const
_
;
let
module
=
ModuleCodegen
{
source
:
ModuleSource
::
Codegened
(
ModuleLlvm
{
llmod
,
llmod
_raw
,
llcx
,
tm
,
}),
...
...
@@ -660,6 +663,8 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
name
:
self
.name
()
.to_string
(),
kind
:
ModuleKind
::
Regular
,
};
{
let
llmod
=
module
.llvm
()
.unwrap
()
.llmod
();
cgcx
.save_temp_bitcode
(
&
module
,
"thin-lto-input"
);
// Before we do much else find the "main" `DICompileUnit` that we'll be
...
...
@@ -755,9 +760,10 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
// little differently.
info!
(
"running thin lto passes over {}"
,
module
.name
);
let
config
=
cgcx
.config
(
module
.kind
);
run_pass_manager
(
cgcx
,
tm
,
llmod
,
config
,
true
);
run_pass_manager
(
cgcx
,
module
.llvm
()
.unwrap
()
.
tm
,
llmod
,
config
,
true
);
cgcx
.save_temp_bitcode
(
&
module
,
"thin-lto-after-pm"
);
timeline
.record
(
"thin-done"
);
}
Ok
(
module
)
}
...
...
src/librustc_codegen_llvm/back/write.rs
浏览文件 @
249d5aca
...
...
@@ -26,8 +26,8 @@
use
rustc
::
util
::
nodemap
::
FxHashMap
;
use
time_graph
::{
self
,
TimeGraph
,
Timeline
};
use
llvm
;
use
llvm
::{
ModuleRef
,
TargetMachineRef
,
PassManagerRef
,
DiagnosticInfoRef
};
use
llvm
::
{
SMDiagnosticRef
,
ContextRef
}
;
use
llvm
::{
TargetMachineRef
,
PassManagerRef
,
DiagnosticInfoRef
};
use
llvm
::
SMDiagnosticRef
;
use
{
CodegenResults
,
ModuleSource
,
ModuleCodegen
,
CompiledModule
,
ModuleKind
};
use
CrateInfo
;
use
rustc
::
hir
::
def_id
::{
CrateNum
,
LOCAL_CRATE
};
...
...
@@ -96,7 +96,7 @@ pub fn write_output_file(
handler
:
&
errors
::
Handler
,
target
:
llvm
::
TargetMachineRef
,
pm
:
llvm
::
PassManagerRef
,
m
:
ModuleRef
,
m
:
&
llvm
::
Module
,
output
:
&
Path
,
file_type
:
llvm
::
FileType
)
->
Result
<
(),
FatalError
>
{
unsafe
{
...
...
@@ -130,7 +130,7 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize {
}
}
pub
fn
create_target_machine
(
sess
:
&
Session
,
find_features
:
bool
)
->
TargetMachineRef
{
pub
fn
create_target_machine
(
sess
:
&
Session
,
find_features
:
bool
)
->
&
'static
mut
llvm
::
TargetMachine
{
target_machine_factory
(
sess
,
find_features
)()
.unwrap_or_else
(|
err
|
{
llvm_err
(
sess
.diagnostic
(),
err
)
.raise
()
})
...
...
@@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi
// that `is_pie_binary` is false. When we discover LLVM target features
// `sess.crate_types` is uninitialized so we cannot access it.
pub
fn
target_machine_factory
(
sess
:
&
Session
,
find_features
:
bool
)
->
Arc
<
dyn
Fn
()
->
Result
<
TargetMachineRef
,
String
>
+
Send
+
Sync
>
->
Arc
<
dyn
Fn
()
->
Result
<
&
'static
mut
llvm
::
TargetMachine
,
String
>
+
Send
+
Sync
>
{
let
reloc_model
=
get_reloc_model
(
sess
);
...
...
@@ -199,12 +199,10 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
)
};
if
tm
.is_null
()
{
Err
(
format!
(
"Could not create LLVM TargetMachine for triple: {}"
,
triple
.to_str
()
.unwrap
()))
}
else
{
Ok
(
tm
)
}
tm
.ok_or_else
(||
{
format!
(
"Could not create LLVM TargetMachine for triple: {}"
,
triple
.to_str
()
.unwrap
())
})
})
}
...
...
@@ -343,7 +341,7 @@ pub struct CodegenContext {
regular_module_config
:
Arc
<
ModuleConfig
>
,
metadata_module_config
:
Arc
<
ModuleConfig
>
,
allocator_module_config
:
Arc
<
ModuleConfig
>
,
pub
tm_factory
:
Arc
<
dyn
Fn
()
->
Result
<
TargetMachineRef
,
String
>
+
Send
+
Sync
>
,
pub
tm_factory
:
Arc
<
dyn
Fn
()
->
Result
<
&
'static
mut
llvm
::
TargetMachine
,
String
>
+
Send
+
Sync
>
,
pub
msvc_imps_needed
:
bool
,
pub
target_pointer_width
:
String
,
debuginfo
:
config
::
DebugInfoLevel
,
...
...
@@ -392,7 +390,7 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
let
cgu
=
Some
(
&
module
.name
[
..
]);
let
path
=
self
.output_filenames
.temp_path_ext
(
&
ext
,
cgu
);
let
cstr
=
path2cstr
(
&
path
);
let
llmod
=
module
.llvm
()
.unwrap
()
.llmod
;
let
llmod
=
module
.llvm
()
.unwrap
()
.llmod
()
;
llvm
::
LLVMWriteBitcodeToFile
(
llmod
,
cstr
.as_ptr
());
}
}
...
...
@@ -400,13 +398,13 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
struct
DiagnosticHandlers
<
'a
>
{
data
:
*
mut
(
&
'a
CodegenContext
,
&
'a
Handler
),
llcx
:
ContextRef
,
llcx
:
&
'a
llvm
::
Context
,
}
impl
<
'a
>
DiagnosticHandlers
<
'a
>
{
fn
new
(
cgcx
:
&
'a
CodegenContext
,
handler
:
&
'a
Handler
,
llcx
:
ContextRef
)
->
DiagnosticHandlers
<
'a
>
{
llcx
:
&
'a
llvm
::
Context
)
->
Self
{
let
data
=
Box
::
into_raw
(
Box
::
new
((
cgcx
,
handler
)));
unsafe
{
llvm
::
LLVMRustSetInlineAsmDiagnosticHandler
(
llcx
,
inline_asm_handler
,
data
as
*
mut
_
);
...
...
@@ -495,7 +493,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
->
Result
<
(),
FatalError
>
{
let
(
llmod
,
llcx
,
tm
)
=
match
module
.source
{
ModuleSource
::
Codegened
(
ref
llvm
)
=>
(
llvm
.llmod
,
llvm
.llcx
,
llvm
.tm
),
ModuleSource
::
Codegened
(
ref
llvm
)
=>
(
llvm
.llmod
(),
&*
llvm
.llcx
,
&*
llvm
.tm
),
ModuleSource
::
Preexisting
(
_
)
=>
{
bug!
(
"optimize_and_codegen: called with ModuleSource::Preexisting"
)
}
...
...
@@ -617,8 +615,9 @@ unsafe fn codegen(cgcx: &CodegenContext,
->
Result
<
CompiledModule
,
FatalError
>
{
timeline
.record
(
"codegen"
);
{
let
(
llmod
,
llcx
,
tm
)
=
match
module
.source
{
ModuleSource
::
Codegened
(
ref
llvm
)
=>
(
llvm
.llmod
,
llvm
.llcx
,
llvm
.tm
),
ModuleSource
::
Codegened
(
ref
llvm
)
=>
(
llvm
.llmod
(),
&*
llvm
.llcx
,
&*
llvm
.tm
),
ModuleSource
::
Preexisting
(
_
)
=>
{
bug!
(
"codegen: called with ModuleSource::Preexisting"
)
}
...
...
@@ -640,7 +639,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
// escape the closure itself, and the manager should only be
// used once.
unsafe
fn
with_codegen
<
F
,
R
>
(
tm
:
TargetMachineRef
,
llmod
:
ModuleRef
,
llmod
:
&
llvm
::
Module
,
no_builtins
:
bool
,
f
:
F
)
->
R
where
F
:
FnOnce
(
PassManagerRef
)
->
R
,
...
...
@@ -763,9 +762,6 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
write_output_file
(
diag_handler
,
tm
,
cpm
,
llmod
,
&
path
,
llvm
::
FileType
::
AssemblyFile
)
})
?
;
if
config
.emit_obj
{
llvm
::
LLVMDisposeModule
(
llmod
);
}
timeline
.record
(
"asm"
);
}
...
...
@@ -803,6 +799,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
}
drop
(
handlers
);
}
Ok
(
module
.into_compiled_module
(
config
.emit_obj
,
config
.emit_bc
,
config
.emit_bc_compressed
,
...
...
@@ -828,8 +825,8 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
/// Basically all of this is us attempting to follow in the footsteps of clang
/// on iOS. See #35968 for lots more info.
unsafe
fn
embed_bitcode
(
cgcx
:
&
CodegenContext
,
llcx
:
ContextRef
,
llmod
:
ModuleRef
,
llcx
:
&
llvm
::
Context
,
llmod
:
&
llvm
::
Module
,
bitcode
:
Option
<&
[
u8
]
>
)
{
let
llconst
=
C_bytes_in_context
(
llcx
,
bitcode
.unwrap_or
(
&
[]));
let
llglobal
=
llvm
::
LLVMAddGlobal
(
...
...
@@ -2050,7 +2047,7 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path,
}
}
pub
unsafe
fn
with_llvm_pmb
(
llmod
:
ModuleRef
,
pub
unsafe
fn
with_llvm_pmb
(
llmod
:
&
llvm
::
Module
,
config
:
&
ModuleConfig
,
opt_level
:
llvm
::
CodeGenOptLevel
,
prepare_for_thin_lto
:
bool
,
...
...
@@ -2353,7 +2350,7 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool {
// when using MSVC linker. We do this only for data, as linker can fix up
// code references on its own.
// See #26591, #27438
fn
create_msvc_imps
(
cgcx
:
&
CodegenContext
,
llcx
:
ContextRef
,
llmod
:
ModuleRef
)
{
fn
create_msvc_imps
(
cgcx
:
&
CodegenContext
,
llcx
:
&
llvm
::
Context
,
llmod
:
&
llvm
::
Module
)
{
if
!
cgcx
.msvc_imps_needed
{
return
}
...
...
src/librustc_codegen_llvm/base.rs
浏览文件 @
249d5aca
...
...
@@ -30,8 +30,8 @@
use
abi
;
use
back
::
link
;
use
back
::
write
::{
self
,
OngoingCodegen
,
create_target_machine
};
use
llvm
::{
ContextRef
,
ModuleRef
,
ValueRef
,
Vector
,
get_param
};
use
back
::
write
::{
self
,
OngoingCodegen
};
use
llvm
::{
ValueRef
,
Vector
,
get_param
};
use
llvm
;
use
metadata
;
use
rustc
::
hir
::
def_id
::{
CrateNum
,
DefId
,
LOCAL_CRATE
};
...
...
@@ -59,7 +59,7 @@
use
rustc_mir
::
monomorphize
::
item
::
DefPathBasedNames
;
use
common
::{
self
,
C_struct_in_context
,
C_array
,
val_ty
};
use
consts
;
use
context
::
{
self
,
CodegenCx
}
;
use
context
::
CodegenCx
;
use
debuginfo
;
use
declare
;
use
meth
;
...
...
@@ -77,7 +77,6 @@
use
std
::
any
::
Any
;
use
std
::
ffi
::
CString
;
use
std
::
str
;
use
std
::
sync
::
Arc
;
use
std
::
time
::{
Instant
,
Duration
};
use
std
::
i32
;
...
...
@@ -609,16 +608,14 @@ fn create_entry_fn<'cx>(cx: &'cx CodegenCx,
}
fn
write_metadata
<
'a
,
'gcx
>
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'gcx
>
,
ll
mod_id
:
&
str
,
ll
vm_module
:
&
ModuleLlvm
,
link_meta
:
&
LinkMeta
)
->
(
ContextRef
,
ModuleRef
,
EncodedMetadata
)
{
->
EncodedMetadata
{
use
std
::
io
::
Write
;
use
flate2
::
Compression
;
use
flate2
::
write
::
DeflateEncoder
;
let
(
metadata_llcx
,
metadata_llmod
)
=
unsafe
{
context
::
create_context_and_module
(
tcx
.sess
,
llmod_id
)
};
let
(
metadata_llcx
,
metadata_llmod
)
=
(
&*
llvm_module
.llcx
,
llvm_module
.llmod
());
#[derive(PartialEq,
Eq,
PartialOrd,
Ord)]
enum
MetadataKind
{
...
...
@@ -641,14 +638,12 @@ enum MetadataKind {
})
.max
()
.unwrap_or
(
MetadataKind
::
None
);
if
kind
==
MetadataKind
::
None
{
return
(
metadata_llcx
,
metadata_llmod
,
EncodedMetadata
::
new
());
return
EncodedMetadata
::
new
();
}
let
metadata
=
tcx
.encode_metadata
(
link_meta
);
if
kind
==
MetadataKind
::
Uncompressed
{
return
(
metadata_llcx
,
metadata_llmod
,
metadata
)
;
return
metadata
;
}
assert
!
(
kind
==
MetadataKind
::
Compressed
);
...
...
@@ -676,7 +671,7 @@ enum MetadataKind {
let
directive
=
CString
::
new
(
directive
)
.unwrap
();
llvm
::
LLVMSetModuleInlineAsm
(
metadata_llmod
,
directive
.as_ptr
())
}
return
(
metadata_llcx
,
metadata_llmod
,
metadata
)
;
return
metadata
;
}
pub
struct
ValueIter
{
...
...
@@ -698,7 +693,7 @@ fn next(&mut self) -> Option<ValueRef> {
}
}
pub
fn
iter_globals
(
llmod
:
llvm
::
ModuleRef
)
->
ValueIter
{
pub
fn
iter_globals
(
llmod
:
&
llvm
::
Module
)
->
ValueIter
{
unsafe
{
ValueIter
{
cur
:
llvm
::
LLVMGetFirstGlobal
(
llmod
),
...
...
@@ -731,19 +726,15 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Codegen the metadata.
let
llmod_id
=
"metadata"
;
let
(
metadata_llcx
,
metadata_llmod
,
metadata
)
=
time
(
tcx
.sess
,
"write metadata"
,
||
{
write_metadata
(
tcx
,
llmod_id
,
&
link_meta
)
let
metadata_llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
llmod_id
);
let
metadata
=
time
(
tcx
.sess
,
"write metadata"
,
||
{
write_metadata
(
tcx
,
&
metadata_llvm_module
,
&
link_meta
)
});
let
metadata_module
=
ModuleCodegen
{
name
:
link
::
METADATA_MODULE_NAME
.to_string
(),
llmod_id
:
llmod_id
.to_string
(),
source
:
ModuleSource
::
Codegened
(
ModuleLlvm
{
llcx
:
metadata_llcx
,
llmod
:
metadata_llmod
,
tm
:
create_target_machine
(
tcx
.sess
,
false
),
}),
source
:
ModuleSource
::
Codegened
(
metadata_llvm_module
),
kind
:
ModuleKind
::
Metadata
,
};
...
...
@@ -803,13 +794,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
allocator_module
=
if
let
Some
(
kind
)
=
*
tcx
.sess.allocator_kind
.get
()
{
unsafe
{
let
llmod_id
=
"allocator"
;
let
(
llcx
,
llmod
)
=
context
::
create_context_and_module
(
tcx
.sess
,
llmod_id
);
let
modules
=
ModuleLlvm
{
llmod
,
llcx
,
tm
:
create_target_machine
(
tcx
.sess
,
false
),
};
let
modules
=
ModuleLlvm
::
new
(
tcx
.sess
,
llmod_id
);
time
(
tcx
.sess
,
"write allocator module"
,
||
{
allocator
::
codegen
(
tcx
,
&
modules
,
kind
)
});
...
...
@@ -1200,8 +1185,9 @@ fn module_codegen<'a, 'tcx>(
.to_fingerprint
()
.to_hex
());
// Instantiate monomorphizations without filling out definitions yet...
let
cx
=
CodegenCx
::
new
(
tcx
,
cgu
,
&
llmod_id
);
let
module
=
{
let
llvm_module
=
ModuleLlvm
::
new
(
tcx
.sess
,
&
llmod_id
);
let
stats
=
{
let
cx
=
CodegenCx
::
new
(
tcx
,
cgu
,
&
llvm_module
);
let
mono_items
=
cx
.codegen_unit
.items_in_deterministic_order
(
cx
.tcx
);
for
&
(
mono_item
,
(
linkage
,
visibility
))
in
&
mono_items
{
...
...
@@ -1248,21 +1234,15 @@ fn module_codegen<'a, 'tcx>(
debuginfo
::
finalize
(
&
cx
);
}
let
llvm_module
=
ModuleLlvm
{
llcx
:
cx
.llcx
,
llmod
:
cx
.llmod
,
tm
:
create_target_machine
(
cx
.sess
(),
false
),
cx
.stats
.into_inner
()
};
ModuleCodegen
{
(
stats
,
ModuleCodegen
{
name
:
cgu_name
,
source
:
ModuleSource
::
Codegened
(
llvm_module
),
kind
:
ModuleKind
::
Regular
,
llmod_id
,
}
};
(
cx
.into_stats
(),
module
)
})
}
}
...
...
src/librustc_codegen_llvm/common.rs
浏览文件 @
249d5aca
...
...
@@ -13,7 +13,7 @@
//! Code that is useful in various codegen modules.
use
llvm
;
use
llvm
::{
ValueRef
,
ContextRef
,
TypeKind
};
use
llvm
::{
ValueRef
,
TypeKind
};
use
llvm
::{
True
,
False
,
Bool
,
OperandBundleDef
};
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
middle
::
lang_items
::
LangItem
;
...
...
@@ -225,7 +225,7 @@ pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef {
C_struct_in_context
(
cx
.llcx
,
elts
,
packed
)
}
pub
fn
C_struct_in_context
(
llcx
:
ContextRef
,
elts
:
&
[
ValueRef
],
packed
:
bool
)
->
ValueRef
{
pub
fn
C_struct_in_context
(
llcx
:
&
llvm
::
Context
,
elts
:
&
[
ValueRef
],
packed
:
bool
)
->
ValueRef
{
unsafe
{
llvm
::
LLVMConstStructInContext
(
llcx
,
elts
.as_ptr
(),
elts
.len
()
as
c_uint
,
...
...
@@ -249,7 +249,7 @@ pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef {
C_bytes_in_context
(
cx
.llcx
,
bytes
)
}
pub
fn
C_bytes_in_context
(
llcx
:
ContextRef
,
bytes
:
&
[
u8
])
->
ValueRef
{
pub
fn
C_bytes_in_context
(
llcx
:
&
llvm
::
Context
,
bytes
:
&
[
u8
])
->
ValueRef
{
unsafe
{
let
ptr
=
bytes
.as_ptr
()
as
*
const
c_char
;
return
llvm
::
LLVMConstStringInContext
(
llcx
,
ptr
,
bytes
.len
()
as
c_uint
,
True
);
...
...
src/librustc_codegen_llvm/context.rs
浏览文件 @
249d5aca
...
...
@@ -10,7 +10,7 @@
use
common
;
use
llvm
;
use
llvm
::
{
ContextRef
,
ModuleRef
,
ValueRef
}
;
use
llvm
::
ValueRef
;
use
rustc
::
dep_graph
::
DepGraphSafe
;
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
DefId
;
...
...
@@ -42,16 +42,16 @@
use
abi
::
Abi
;
/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
/// `
ContextRef
` so that several compilation units may be optimized in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `
ContextRef
`.
/// `
llvm::Context
` so that several compilation units may be optimized in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `
llvm::Context
`.
pub
struct
CodegenCx
<
'a
,
'tcx
:
'a
>
{
pub
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
pub
check_overflow
:
bool
,
pub
use_dll_storage_attrs
:
bool
,
pub
tls_model
:
llvm
::
ThreadLocalMode
,
pub
llmod
:
ModuleRef
,
pub
llcx
:
ContextRef
,
pub
llmod
:
&
'a
llvm
::
Module
,
pub
llcx
:
&
'a
llvm
::
Context
,
pub
stats
:
RefCell
<
Stats
>
,
pub
codegen_unit
:
Arc
<
CodegenUnit
<
'tcx
>>
,
...
...
@@ -94,7 +94,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
pub
pointee_infos
:
RefCell
<
FxHashMap
<
(
Ty
<
'tcx
>
,
Size
),
Option
<
PointeeInfo
>>>
,
pub
isize_ty
:
Type
,
pub
dbg_cx
:
Option
<
debuginfo
::
CrateDebugContext
<
'tcx
>>
,
pub
dbg_cx
:
Option
<
debuginfo
::
CrateDebugContext
<
'
a
,
'
tcx
>>
,
eh_personality
:
Cell
<
Option
<
ValueRef
>>
,
eh_unwind_resume
:
Cell
<
Option
<
ValueRef
>>
,
...
...
@@ -155,8 +155,7 @@ pub fn is_pie_binary(sess: &Session) -> bool {
!
is_any_library
(
sess
)
&&
get_reloc_model
(
sess
)
==
llvm
::
RelocMode
::
PIC
}
pub
unsafe
fn
create_context_and_module
(
sess
:
&
Session
,
mod_name
:
&
str
)
->
(
ContextRef
,
ModuleRef
)
{
let
llcx
=
llvm
::
LLVMRustContextCreate
(
sess
.fewer_names
());
pub
unsafe
fn
create_module
(
sess
:
&
Session
,
llcx
:
&
'll
llvm
::
Context
,
mod_name
:
&
str
)
->
&
'll
llvm
::
Module
{
let
mod_name
=
CString
::
new
(
mod_name
)
.unwrap
();
let
llmod
=
llvm
::
LLVMModuleCreateWithNameInContext
(
mod_name
.as_ptr
(),
llcx
);
...
...
@@ -208,13 +207,13 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont
llvm
::
LLVMRustSetModulePIELevel
(
llmod
);
}
(
llcx
,
llmod
)
llmod
}
impl
<
'a
,
'tcx
>
CodegenCx
<
'a
,
'tcx
>
{
pub
fn
new
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
crate
fn
new
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
codegen_unit
:
Arc
<
CodegenUnit
<
'tcx
>>
,
ll
mod_id
:
&
str
)
ll
vm_module
:
&
'a
::
ModuleLlvm
)
->
CodegenCx
<
'a
,
'tcx
>
{
// An interesting part of Windows which MSVC forces our hand on (and
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
...
...
@@ -265,9 +264,7 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
tls_model
=
get_tls_model
(
&
tcx
.sess
);
unsafe
{
let
(
llcx
,
llmod
)
=
create_context_and_module
(
&
tcx
.sess
,
&
llmod_id
[
..
]);
let
(
llcx
,
llmod
)
=
(
&*
llvm_module
.llcx
,
llvm_module
.llmod
());
let
dbg_cx
=
if
tcx
.sess.opts.debuginfo
!=
NoDebugInfo
{
let
dctx
=
debuginfo
::
CrateDebugContext
::
new
(
llmod
);
...
...
@@ -310,11 +307,6 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
local_gen_sym_counter
:
Cell
::
new
(
0
),
}
}
}
pub
fn
into_stats
(
self
)
->
Stats
{
self
.stats
.into_inner
()
}
}
impl
<
'b
,
'tcx
>
CodegenCx
<
'b
,
'tcx
>
{
...
...
src/librustc_codegen_llvm/debuginfo/metadata.rs
浏览文件 @
249d5aca
...
...
@@ -862,7 +862,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
return
unit_metadata
;
};
fn
path_to_mdstring
(
llcx
:
llvm
::
ContextRef
,
path
:
&
Path
)
->
llvm
::
ValueRef
{
fn
path_to_mdstring
(
llcx
:
&
llvm
::
Context
,
path
:
&
Path
)
->
llvm
::
ValueRef
{
let
path_str
=
path2cstr
(
path
);
unsafe
{
llvm
::
LLVMMDStringInContext
(
llcx
,
...
...
src/librustc_codegen_llvm/debuginfo/mod.rs
浏览文件 @
249d5aca
...
...
@@ -21,7 +21,7 @@
use
self
::
source_loc
::
InternalDebugLocation
::{
self
,
UnknownLocation
};
use
llvm
;
use
llvm
::
{
ModuleRef
,
ContextRef
,
ValueRef
}
;
use
llvm
::
ValueRef
;
use
llvm
::
debuginfo
::{
DIFile
,
DIType
,
DIScope
,
DIBuilderRef
,
DISubprogram
,
DIArray
,
DIFlags
};
use
rustc
::
hir
::
CodegenFnAttrFlags
;
use
rustc
::
hir
::
def_id
::{
DefId
,
CrateNum
};
...
...
@@ -67,9 +67,9 @@
const
DW_TAG_arg_variable
:
c_uint
=
0x101
;
/// A context object for maintaining all state needed by the debuginfo module.
pub
struct
CrateDebugContext
<
'tcx
>
{
llcontext
:
ContextRef
,
llmod
:
ModuleRef
,
pub
struct
CrateDebugContext
<
'
a
,
'
tcx
>
{
llcontext
:
&
'a
llvm
::
Context
,
llmod
:
&
'a
llvm
::
Module
,
builder
:
DIBuilderRef
,
created_files
:
RefCell
<
FxHashMap
<
(
Symbol
,
Symbol
),
DIFile
>>
,
created_enum_disr_types
:
RefCell
<
FxHashMap
<
(
DefId
,
layout
::
Primitive
),
DIType
>>
,
...
...
@@ -82,8 +82,8 @@ pub struct CrateDebugContext<'tcx> {
composite_types_completed
:
RefCell
<
FxHashSet
<
DIType
>>
,
}
impl
<
'
tcx
>
CrateDebugContext
<
'tcx
>
{
pub
fn
new
(
llmod
:
ModuleRef
)
->
CrateDebugContext
<
'tcx
>
{
impl
<
'
a
,
'tcx
>
CrateDebugContext
<
'a
,
'tcx
>
{
pub
fn
new
(
llmod
:
&
'a
llvm
::
Module
)
->
Self
{
debug!
(
"CrateDebugContext::new"
);
let
builder
=
unsafe
{
llvm
::
LLVMRustDIBuilderCreate
(
llmod
)
};
// DIBuilder inherits context from the module, so we'd better use the same one
...
...
src/librustc_codegen_llvm/debuginfo/utils.rs
浏览文件 @
249d5aca
...
...
@@ -50,7 +50,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
#[inline]
pub
fn
debug_context
<
'a
,
'tcx
>
(
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
)
->
&
'a
CrateDebugContext
<
'tcx
>
{
->
&
'a
CrateDebugContext
<
'
a
,
'
tcx
>
{
cx
.dbg_cx
.as_ref
()
.unwrap
()
}
...
...
src/librustc_codegen_llvm/lib.rs
浏览文件 @
249d5aca
...
...
@@ -20,9 +20,11 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(crate_visibility_modifier)]
#![feature(custom_attribute)]
#![feature(extern_types)]
#![feature(fs_read_write)]
#![feature(in_band_lifetimes)]
#![allow(unused_attributes)]
#![feature(libc)]
#![feature(quote)]
...
...
@@ -34,6 +36,7 @@
#![feature(link_args)]
#![feature(static_nobundle)]
use
back
::
write
::
create_target_machine
;
use
rustc
::
dep_graph
::
WorkProduct
;
use
syntax_pos
::
symbol
::
Symbol
;
...
...
@@ -340,22 +343,41 @@ enum ModuleSource {
Codegened
(
ModuleLlvm
),
}
#[derive(Debug)]
struct
ModuleLlvm
{
llcx
:
llvm
::
ContextRef
,
llmod
:
llvm
::
ModuleRef
,
tm
:
llvm
::
TargetMachineRef
,
llcx
:
&
'static
mut
llvm
::
Context
,
llmod
_raw
:
*
const
llvm
::
Module
,
tm
:
&
'static
mut
llvm
::
TargetMachine
,
}
unsafe
impl
Send
for
ModuleLlvm
{
}
unsafe
impl
Sync
for
ModuleLlvm
{
}
impl
ModuleLlvm
{
fn
new
(
sess
:
&
Session
,
mod_name
:
&
str
)
->
Self
{
unsafe
{
let
llcx
=
llvm
::
LLVMRustContextCreate
(
sess
.fewer_names
());
let
llmod_raw
=
context
::
create_module
(
sess
,
llcx
,
mod_name
)
as
*
const
_
;
ModuleLlvm
{
llmod_raw
,
llcx
,
tm
:
create_target_machine
(
sess
,
false
),
}
}
}
fn
llmod
(
&
self
)
->
&
llvm
::
Module
{
unsafe
{
&*
self
.llmod_raw
}
}
}
impl
Drop
for
ModuleLlvm
{
fn
drop
(
&
mut
self
)
{
unsafe
{
llvm
::
LLVMDisposeModule
(
self
.llmod
);
llvm
::
LLVMContextDispose
(
self
.llcx
);
llvm
::
LLVMRustDisposeTargetMachine
(
self
.tm
);
llvm
::
LLVMContextDispose
(
&
mut
*
(
self
.llcx
as
*
mut
_
));
llvm
::
LLVMRustDisposeTargetMachine
(
&
mut
*
(
self
.tm
as
*
mut
_
));
}
}
}
...
...
src/librustc_codegen_llvm/llvm/ffi.rs
浏览文件 @
249d5aca
此差异已折叠。
点击以展开。
src/librustc_codegen_llvm/llvm/mod.rs
浏览文件 @
249d5aca
...
...
@@ -127,7 +127,7 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
// value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
// function.
// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
pub
fn
SetUniqueComdat
(
llmod
:
ModuleRef
,
val
:
ValueRef
)
{
pub
fn
SetUniqueComdat
(
llmod
:
&
Module
,
val
:
ValueRef
)
{
unsafe
{
LLVMRustSetComdat
(
llmod
,
val
,
LLVMGetValueName
(
val
));
}
...
...
src/librustc_codegen_llvm/type_.rs
浏览文件 @
249d5aca
...
...
@@ -11,7 +11,7 @@
#![allow(non_upper_case_globals)]
use
llvm
;
use
llvm
::{
ContextRef
,
TypeRef
,
Bool
,
False
,
True
,
TypeKind
};
use
llvm
::{
TypeRef
,
Bool
,
False
,
True
,
TypeKind
};
use
llvm
::{
Float
,
Double
,
X86_FP80
,
PPC_FP128
,
FP128
};
use
context
::
CodegenCx
;
...
...
@@ -77,7 +77,7 @@ pub fn i8(cx: &CodegenCx) -> Type {
ty!
(
llvm
::
LLVMInt8TypeInContext
(
cx
.llcx
))
}
pub
fn
i8_llcx
(
llcx
:
ContextRef
)
->
Type
{
pub
fn
i8_llcx
(
llcx
:
&
llvm
::
Context
)
->
Type
{
ty!
(
llvm
::
LLVMInt8TypeInContext
(
llcx
))
}
...
...
@@ -103,7 +103,7 @@ pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type {
}
// Creates an integer type with the given number of bits, e.g. i24
pub
fn
ix_llcx
(
llcx
:
ContextRef
,
num_bits
:
u64
)
->
Type
{
pub
fn
ix_llcx
(
llcx
:
&
llvm
::
Context
,
num_bits
:
u64
)
->
Type
{
ty!
(
llvm
::
LLVMIntTypeInContext
(
llcx
,
num_bits
as
c_uint
))
}
...
...
@@ -127,7 +127,7 @@ pub fn i8p(cx: &CodegenCx) -> Type {
Type
::
i8
(
cx
)
.ptr_to
()
}
pub
fn
i8p_llcx
(
llcx
:
ContextRef
)
->
Type
{
pub
fn
i8p_llcx
(
llcx
:
&
llvm
::
Context
)
->
Type
{
Type
::
i8_llcx
(
llcx
)
.ptr_to
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录