Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
bac57cf6
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,发现更多精彩内容 >>
提交
bac57cf6
编写于
7月 24, 2017
作者:
M
Michael Woerister
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
async-llvm(3): Make write::CodegenContext Clone and Send.
上级
29d4725b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
78 addition
and
82 deletion
+78
-82
src/librustc_trans/back/lto.rs
src/librustc_trans/back/lto.rs
+13
-13
src/librustc_trans/back/write.rs
src/librustc_trans/back/write.rs
+65
-69
未找到文件。
src/librustc_trans/back/lto.rs
浏览文件 @
bac57cf6
...
...
@@ -12,7 +12,7 @@
use
back
::
write
;
use
back
::
symbol_export
;
use
rustc
::
session
::
config
;
use
errors
::
FatalError
;
use
errors
::
{
FatalError
,
Handler
}
;
use
llvm
;
use
llvm
::
archive_ro
::
ArchiveRO
;
use
llvm
::{
ModuleRef
,
TargetMachineRef
,
True
,
False
};
...
...
@@ -41,24 +41,24 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
}
pub
fn
run
(
cgcx
:
&
CodegenContext
,
diag_handler
:
&
Handler
,
llmod
:
ModuleRef
,
tm
:
TargetMachineRef
,
config
:
&
ModuleConfig
,
temp_no_opt_bc_filename
:
&
Path
)
->
Result
<
(),
FatalError
>
{
let
handler
=
cgcx
.handler
;
if
cgcx
.opts.cg.prefer_dynamic
{
handler
.struct_err
(
"cannot prefer dynamic linking when performing LTO"
)
.note
(
"only 'staticlib', 'bin', and 'cdylib' outputs are
\
supported with LTO"
)
.emit
();
diag_
handler
.struct_err
(
"cannot prefer dynamic linking when performing LTO"
)
.note
(
"only 'staticlib', 'bin', and 'cdylib' outputs are
\
supported with LTO"
)
.emit
();
return
Err
(
FatalError
)
}
// Make sure we actually can run LTO
for
crate_type
in
cgcx
.crate_types
.iter
()
{
if
!
crate_type_allows_lto
(
*
crate_type
)
{
let
e
=
handler
.fatal
(
"lto can only be run for executables, cdylibs and
\
static library outputs"
);
let
e
=
diag_
handler
.fatal
(
"lto can only be run for executables, cdylibs and
\
static library outputs"
);
return
Err
(
e
)
}
}
...
...
@@ -116,13 +116,13 @@ pub fn run(cgcx: &CodegenContext,
if
res
.is_err
()
{
let
msg
=
format!
(
"failed to decompress bc of `{}`"
,
name
);
Err
(
handler
.fatal
(
&
msg
))
Err
(
diag_
handler
.fatal
(
&
msg
))
}
else
{
Ok
(
inflated
)
}
}
else
{
Err
(
handler
.fatal
(
&
format!
(
"Unsupported bytecode format version {}"
,
version
)))
Err
(
diag_
handler
.fatal
(
&
format!
(
"Unsupported bytecode format version {}"
,
version
)))
}
})
?
}
else
{
...
...
@@ -136,7 +136,7 @@ pub fn run(cgcx: &CodegenContext,
if
res
.is_err
()
{
let
msg
=
format!
(
"failed to decompress bc of `{}`"
,
name
);
Err
(
handler
.fatal
(
&
msg
))
Err
(
diag_
handler
.fatal
(
&
msg
))
}
else
{
Ok
(
inflated
)
}
...
...
@@ -152,7 +152,7 @@ pub fn run(cgcx: &CodegenContext,
Ok
(())
}
else
{
let
msg
=
format!
(
"failed to load bc of `{}`"
,
name
);
Err
(
write
::
llvm_err
(
handler
,
msg
))
Err
(
write
::
llvm_err
(
&
diag_
handler
,
msg
))
}
})
?
;
}
...
...
src/librustc_trans/back/write.rs
浏览文件 @
bac57cf6
...
...
@@ -282,6 +282,7 @@ fn set_flags(&mut self, sess: &Session, trans: &OngoingCrateTranslation) {
}
/// Additional resources used by optimize_and_codegen (not module specific)
#[derive(Clone)]
pub
struct
CodegenContext
<
'a
>
{
// Resouces needed when running LTO
pub
time_passes
:
bool
,
...
...
@@ -292,7 +293,7 @@ pub struct CodegenContext<'a> {
pub
crate_types
:
Vec
<
config
::
CrateType
>
,
pub
each_linked_rlib_for_lto
:
Vec
<
(
CrateNum
,
PathBuf
)
>
,
// Handler to use for diagnostics produced during codegen.
pub
handler
:
&
'a
Handl
er
,
pub
diag_emitter
:
SharedEmitt
er
,
// LLVM passes added by plugins.
pub
plugin_passes
:
Vec
<
String
>
,
// LLVM optimizations for which we want to print remarks.
...
...
@@ -303,20 +304,24 @@ pub struct CodegenContext<'a> {
// compiling incrementally
pub
incr_comp_session_dir
:
Option
<
PathBuf
>
,
// Channel back to the main control thread to send messages to
pub
tx
:
Sender
<
Message
>
,
pub
coordinator_send
:
Sender
<
Message
>
,
}
// Error messages...
pub
shared_emitter
:
SharedEmitter
,
impl
<
'a
>
CodegenContext
<
'a
>
{
fn
create_diag_handler
(
&
self
)
->
Handler
{
Handler
::
with_emitter
(
true
,
false
,
Box
::
new
(
self
.diag_emitter
.clone
()))
}
}
struct
HandlerFreeVars
<
'a
>
{
cgcx
:
&
'a
CodegenContext
<
'a
>
,
diag_handler
:
&
'a
Handler
,
}
unsafe
extern
"C"
fn
report_inline_asm
<
'a
,
'b
>
(
cgcx
:
&
'a
CodegenContext
<
'a
>
,
msg
:
&
'b
str
,
cookie
:
c_uint
)
{
cgcx
.
shared
_emitter
.inline_asm_error
(
cookie
as
u32
,
msg
.to_string
());
cgcx
.
diag
_emitter
.inline_asm_error
(
cookie
as
u32
,
msg
.to_string
());
}
unsafe
extern
"C"
fn
inline_asm_handler
(
diag
:
SMDiagnosticRef
,
...
...
@@ -331,7 +336,7 @@ struct HandlerFreeVars<'a> {
}
unsafe
extern
"C"
fn
diagnostic_handler
(
info
:
DiagnosticInfoRef
,
user
:
*
mut
c_void
)
{
let
HandlerFreeVars
{
cgcx
,
..
}
=
*
(
user
as
*
const
HandlerFreeVars
);
let
HandlerFreeVars
{
cgcx
,
diag_handler
,
..
}
=
*
(
user
as
*
const
HandlerFreeVars
);
match
llvm
::
diagnostic
::
Diagnostic
::
unpack
(
info
)
{
llvm
::
diagnostic
::
InlineAsm
(
inline
)
=>
{
...
...
@@ -347,7 +352,7 @@ struct HandlerFreeVars<'a> {
};
if
enabled
{
cgcx
.
handler
.note_without_error
(
&
format!
(
"optimization {} for {} at {}:{}:{}: {}"
,
diag_
handler
.note_without_error
(
&
format!
(
"optimization {} for {} at {}:{}:{}: {}"
,
opt
.kind
.describe
(),
opt
.pass_name
,
opt
.filename
,
...
...
@@ -363,6 +368,7 @@ struct HandlerFreeVars<'a> {
// Unsafe due to LLVM calls.
unsafe
fn
optimize_and_codegen
(
cgcx
:
&
CodegenContext
,
diag_handler
:
&
Handler
,
mtrans
:
ModuleTranslation
,
mllvm
:
ModuleLlvm
,
config
:
ModuleConfig
,
...
...
@@ -375,6 +381,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
let
fv
=
HandlerFreeVars
{
cgcx
:
cgcx
,
diag_handler
:
diag_handler
,
};
let
fv
=
&
fv
as
*
const
HandlerFreeVars
as
*
mut
c_void
;
...
...
@@ -409,7 +416,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
llvm
::
PassKind
::
Function
=>
fpm
,
llvm
::
PassKind
::
Module
=>
mpm
,
llvm
::
PassKind
::
Other
=>
{
cgcx
.
handler
.err
(
"Encountered LLVM pass kind we can't handle"
);
diag_
handler
.err
(
"Encountered LLVM pass kind we can't handle"
);
return
true
},
};
...
...
@@ -429,20 +436,20 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
for
pass
in
&
config
.passes
{
if
!
addpass
(
pass
)
{
cgcx
.
handler
.warn
(
&
format!
(
"unknown pass `{}`, ignoring"
,
diag_
handler
.warn
(
&
format!
(
"unknown pass `{}`, ignoring"
,
pass
));
}
}
for
pass
in
&
cgcx
.plugin_passes
{
if
!
addpass
(
pass
)
{
cgcx
.
handler
.err
(
&
format!
(
"a plugin asked for LLVM pass
\
diag_
handler
.err
(
&
format!
(
"a plugin asked for LLVM pass
\
`{}` but LLVM does not
\
recognize it"
,
pass
));
}
}
cgcx
.
handler
.abort_if_errors
();
diag_
handler
.abort_if_errors
();
// Finally, run the actual optimization passes
time
(
config
.time_passes
,
&
format!
(
"llvm function passes [{}]"
,
cgcx
.worker
),
||
...
...
@@ -459,6 +466,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
let
temp_no_opt_bc_filename
=
output_names
.temp_path_ext
(
"no-opt.lto.bc"
,
module_name
);
lto
::
run
(
cgcx
,
diag_handler
,
llmod
,
tm
,
&
config
,
...
...
@@ -564,7 +572,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
llmod
};
with_codegen
(
tm
,
llmod
,
config
.no_builtins
,
|
cpm
|
{
write_output_file
(
cgcx
.
handler
,
tm
,
cpm
,
llmod
,
&
path
,
write_output_file
(
diag_
handler
,
tm
,
cpm
,
llmod
,
&
path
,
llvm
::
FileType
::
AssemblyFile
)
})
?
;
if
config
.emit_obj
{
...
...
@@ -574,7 +582,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
if
write_obj
{
with_codegen
(
tm
,
llmod
,
config
.no_builtins
,
|
cpm
|
{
write_output_file
(
cgcx
.
handler
,
tm
,
cpm
,
llmod
,
&
obj_out
,
write_output_file
(
diag_
handler
,
tm
,
cpm
,
llmod
,
&
obj_out
,
llvm
::
FileType
::
ObjectFile
)
})
?
;
}
...
...
@@ -585,14 +593,14 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
if
copy_bc_to_obj
{
debug!
(
"copying bitcode {:?} to obj {:?}"
,
bc_out
,
obj_out
);
if
let
Err
(
e
)
=
link_or_copy
(
&
bc_out
,
&
obj_out
)
{
cgcx
.
handler
.err
(
&
format!
(
"failed to copy bitcode to object file: {}"
,
e
));
diag_
handler
.err
(
&
format!
(
"failed to copy bitcode to object file: {}"
,
e
));
}
}
if
rm_bc
{
debug!
(
"removing_bitcode {:?}"
,
bc_out
);
if
let
Err
(
e
)
=
fs
::
remove_file
(
&
bc_out
)
{
cgcx
.
handler
.err
(
&
format!
(
"failed to remove bitcode: {}"
,
e
));
diag_
handler
.err
(
&
format!
(
"failed to remove bitcode: {}"
,
e
));
}
}
...
...
@@ -991,11 +999,13 @@ fn build_work_item(sess: &Session,
fn
execute_work_item
(
cgcx
:
&
CodegenContext
,
work_item
:
WorkItem
)
->
Result
<
(),
FatalError
>
{
let
diag_handler
=
cgcx
.create_diag_handler
();
unsafe
{
match
work_item
.mtrans.source
{
ModuleSource
::
Translated
(
mllvm
)
=>
{
debug!
(
"llvm-optimizing {:?}"
,
work_item
.mtrans.name
);
optimize_and_codegen
(
cgcx
,
&
diag_handler
,
work_item
.mtrans
,
mllvm
,
work_item
.config
,
...
...
@@ -1017,7 +1027,7 @@ fn execute_work_item(cgcx: &CodegenContext, work_item: WorkItem)
match
link_or_copy
(
&
source_file
,
&
obj_out
)
{
Ok
(
_
)
=>
{
}
Err
(
err
)
=>
{
cgcx
.
handler
.err
(
&
format!
(
"unable to copy {} to {}: {}"
,
diag_
handler
.err
(
&
format!
(
"unable to copy {} to {}: {}"
,
source_file
.display
(),
obj_out
.display
(),
err
));
...
...
@@ -1069,6 +1079,30 @@ fn execute_work<'a>(sess: &'a Session,
let
(
shared_emitter
,
shared_emitter_main
)
=
SharedEmitter
::
new
();
let
mut
each_linked_rlib_for_lto
=
Vec
::
new
();
drop
(
link
::
each_linked_rlib
(
sess
,
&
mut
|
cnum
,
path
|
{
if
link
::
ignored_for_lto
(
sess
,
cnum
)
{
return
}
each_linked_rlib_for_lto
.push
((
cnum
,
path
.to_path_buf
()));
}));
let
cgcx
=
CodegenContext
{
crate_types
:
sess
.crate_types
.borrow
()
.clone
(),
each_linked_rlib_for_lto
:
each_linked_rlib_for_lto
,
lto
:
sess
.lto
(),
no_landing_pads
:
sess
.no_landing_pads
(),
opts
:
&
sess
.opts
,
time_passes
:
sess
.time_passes
(),
exported_symbols
:
exported_symbols
,
plugin_passes
:
sess
.plugin_llvm_passes
.borrow
()
.clone
(),
remark
:
sess
.opts.cg.remark
.clone
(),
worker
:
0
,
incr_comp_session_dir
:
sess
.incr_comp_session_dir_opt
()
.map
(|
r
|
r
.clone
()),
coordinator_send
:
tx
.clone
(),
diag_emitter
:
shared_emitter
.clone
(),
};
// This is the "main loop" of parallel work happening for parallel codegen.
// It's here that we manage parallelism, schedule work, and work with
// messages coming from clients.
...
...
@@ -1132,14 +1166,16 @@ fn execute_work<'a>(sess: &'a Session,
// parallelism slots and work left to spawn.
while
work_items
.len
()
>
0
&&
running
<
tokens
.len
()
+
1
{
let
item
=
work_items
.pop
()
.unwrap
();
let
index
=
work_items
.len
();
spawn_work
(
sess
,
exported_symbols
,
let
worker_index
=
work_items
.len
();
let
cgcx
=
CodegenContext
{
worker
:
worker_index
,
..
cgcx
.clone
()
};
spawn_work
(
cgcx
,
scope
,
tx
.clone
(),
shared_emitter
.clone
(),
item
,
index
);
item
);
running
+=
1
;
}
...
...
@@ -1178,29 +1214,10 @@ fn execute_work<'a>(sess: &'a Session,
sess
.diagnostic
()
.abort_if_errors
();
}
fn
spawn_work
<
'a
>
(
sess
:
&
'a
Session
,
exported_symbols
:
&
'a
ExportedSymbols
,
fn
spawn_work
<
'a
>
(
cgcx
:
CodegenContext
<
'a
>
,
scope
:
&
Scope
<
'a
>
,
tx
:
Sender
<
Message
>
,
emitter
:
SharedEmitter
,
work
:
WorkItem
,
idx
:
usize
)
{
let
plugin_passes
=
sess
.plugin_llvm_passes
.borrow
()
.clone
();
let
remark
=
sess
.opts.cg.remark
.clone
();
let
incr_comp_session_dir
=
sess
.incr_comp_session_dir_opt
()
.map
(|
r
|
r
.clone
());
work
:
WorkItem
)
{
let
depth
=
time_depth
();
let
lto
=
sess
.lto
();
let
crate_types
=
sess
.crate_types
.borrow
()
.clone
();
let
mut
each_linked_rlib_for_lto
=
Vec
::
new
();
drop
(
link
::
each_linked_rlib
(
sess
,
&
mut
|
cnum
,
path
|
{
if
link
::
ignored_for_lto
(
sess
,
cnum
)
{
return
}
each_linked_rlib_for_lto
.push
((
cnum
,
path
.to_path_buf
()));
}));
let
time_passes
=
sess
.time_passes
();
let
no_landing_pads
=
sess
.no_landing_pads
();
let
opts
=
&
sess
.opts
;
scope
.spawn
(
move
||
{
set_time_depth
(
depth
);
...
...
@@ -1208,41 +1225,20 @@ fn spawn_work<'a>(sess: &'a Session,
// Set up a destructor which will fire off a message that we're done as
// we exit.
struct
Bomb
{
tx
:
Sender
<
Message
>
,
coordinator_send
:
Sender
<
Message
>
,
success
:
bool
,
}
impl
Drop
for
Bomb
{
fn
drop
(
&
mut
self
)
{
drop
(
self
.
tx
.send
(
Message
::
Done
{
success
:
self
.success
}));
drop
(
self
.
coordinator_send
.send
(
Message
::
Done
{
success
:
self
.success
}));
}
}
let
mut
bomb
=
Bomb
{
tx
:
tx
.clone
(),
coordinator_send
:
cgcx
.coordinator_send
.clone
(),
success
:
false
,
};
// Set up our non-`Send` `CodegenContext` now that we're in a helper
// thread and have all our info available to us.
// let emitter = SharedEmitter { tx: tx.clone() };
let
diag_handler
=
Handler
::
with_emitter
(
true
,
false
,
Box
::
new
(
emitter
.clone
()));
let
cgcx
=
CodegenContext
{
crate_types
:
crate_types
,
each_linked_rlib_for_lto
:
each_linked_rlib_for_lto
,
lto
:
lto
,
no_landing_pads
:
no_landing_pads
,
opts
:
opts
,
time_passes
:
time_passes
,
exported_symbols
:
exported_symbols
,
handler
:
&
diag_handler
,
plugin_passes
:
plugin_passes
,
remark
:
remark
,
worker
:
idx
,
incr_comp_session_dir
:
incr_comp_session_dir
,
tx
:
tx
.clone
(),
shared_emitter
:
emitter
,
};
// Execute the work itself, and if it finishes successfully then flag
// ourselves as a success as well.
//
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录