Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ef9ae858
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
ef9ae858
编写于
2月 03, 2017
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
make dirty process O(dirty)
The old algorithm was O(graph)
上级
d848f1d7
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
66 addition
and
50 deletion
+66
-50
src/librustc_incremental/persist/data.rs
src/librustc_incremental/persist/data.rs
+8
-9
src/librustc_incremental/persist/load.rs
src/librustc_incremental/persist/load.rs
+53
-39
src/librustc_incremental/persist/save.rs
src/librustc_incremental/persist/save.rs
+5
-2
未找到文件。
src/librustc_incremental/persist/data.rs
浏览文件 @
ef9ae858
...
...
@@ -21,7 +21,7 @@
/// Data for use when recompiling the **current crate**.
#[derive(Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
SerializedDepGraph
{
pub
edges
:
Vec
<
SerializedEdge
>
,
pub
edges
:
Vec
<
SerializedEdge
Set
>
,
/// These are hashes of two things:
/// - the HIR nodes in this crate
...
...
@@ -45,14 +45,13 @@ pub struct SerializedDepGraph {
pub
hashes
:
Vec
<
SerializedHash
>
,
}
/// Represents a "reduced" dependency edge. Unlike the full dep-graph,
/// the dep-graph we serialize contains only edges `S -> T` where the
/// source `S` is something hashable (a HIR node or foreign metadata)
/// and the target `T` is something significant, like a work-product.
/// Normally, significant nodes are only those that have saved data on
/// disk, but in unit-testing the set of significant nodes can be
/// increased.
pub
type
SerializedEdge
=
(
DepNode
<
DefPathIndex
>
,
DepNode
<
DefPathIndex
>
);
/// Represents a set of "reduced" dependency edge. We group the
/// outgoing edges from a single source together.
#[derive(Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
SerializedEdgeSet
{
pub
source
:
DepNode
<
DefPathIndex
>
,
pub
targets
:
Vec
<
DepNode
<
DefPathIndex
>>
}
#[derive(Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
SerializedHash
{
...
...
src/librustc_incremental/persist/load.rs
浏览文件 @
ef9ae858
...
...
@@ -152,6 +152,11 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
directory
=
DefIdDirectory
::
decode
(
&
mut
dep_graph_decoder
)
?
;
let
serialized_dep_graph
=
SerializedDepGraph
::
decode
(
&
mut
dep_graph_decoder
)
?
;
let
edge_map
:
FxHashMap
<
_
,
_
>
=
serialized_dep_graph
.edges
.into_iter
()
.map
(|
s
|
(
s
.source
,
s
.targets
))
.collect
();
// Retrace the paths in the directory to find their current location (if any).
let
retraced
=
directory
.retrace
(
tcx
);
...
...
@@ -166,46 +171,48 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
incremental_hashes_map
,
&
serialized_dep_graph
.hashes
,
&
retraced
);
let
dirty_raw_nodes
=
transitive_dirty_nodes
(
&
serialized_dep_graph
.edges
,
dirty_raw_nodes
);
let
dirty_raw_nodes
=
transitive_dirty_nodes
(
&
edge_map
,
dirty_raw_nodes
);
// Recreate the edges in the graph that are still clean.
let
mut
clean_work_products
=
FxHashSet
();
let
mut
dirty_work_products
=
FxHashSet
();
// incomplete; just used to suppress debug output
for
edge
in
&
serialized_dep_graph
.edges
{
// If the target is dirty, skip the edge. If this is an edge
// that targets a work-product, we can print the blame
// information now.
if
let
Some
(
blame
)
=
dirty_raw_nodes
.get
(
&
edge
.1
)
{
if
let
DepNode
::
WorkProduct
(
ref
wp
)
=
edge
.1
{
if
tcx
.sess.opts.debugging_opts.incremental_info
{
if
dirty_work_products
.insert
(
wp
.clone
())
{
// It'd be nice to pretty-print these paths better than just
// using the `Debug` impls, but wev.
println!
(
"incremental: module {:?} is dirty because {:?}
\
changed or was removed"
,
wp
,
blame
.map_def
(|
&
index
|
{
Some
(
directory
.def_path_string
(
tcx
,
index
))
})
.unwrap
());
for
(
source
,
targets
)
in
&
edge_map
{
for
target
in
targets
{
// If the target is dirty, skip the edge. If this is an edge
// that targets a work-product, we can print the blame
// information now.
if
let
Some
(
blame
)
=
dirty_raw_nodes
.get
(
target
)
{
if
let
DepNode
::
WorkProduct
(
ref
wp
)
=
*
target
{
if
tcx
.sess.opts.debugging_opts.incremental_info
{
if
dirty_work_products
.insert
(
wp
.clone
())
{
// It'd be nice to pretty-print these paths better than just
// using the `Debug` impls, but wev.
println!
(
"incremental: module {:?} is dirty because {:?}
\
changed or was removed"
,
wp
,
blame
.map_def
(|
&
index
|
{
Some
(
directory
.def_path_string
(
tcx
,
index
))
})
.unwrap
());
}
}
}
continue
;
}
continue
;
}
// If the source is dirty, the target will be dirty.
assert
!
(
!
dirty_raw_nodes
.contains_key
(
&
edge
.0
));
// Retrace the source -> target edges to def-ids and then
// create an edge in the graph. Retracing may yield none if
// some of the data happens to have been removed; this ought
// to be impossible unless it is dirty, so we can unwrap.
let
source_node
=
retraced
.map
(
&
edge
.0
)
.unwrap
();
let
target_node
=
retraced
.map
(
&
edge
.1
)
.unwrap
();
let
_
task
=
tcx
.dep_graph
.in_task
(
target_node
);
tcx
.dep_graph
.read
(
source_node
);
if
let
DepNode
::
WorkProduct
(
ref
wp
)
=
edge
.1
{
clean_work_products
.insert
(
wp
.clone
());
// If the source is dirty, the target will be dirty.
assert
!
(
!
dirty_raw_nodes
.contains_key
(
source
));
// Retrace the source -> target edges to def-ids and then
// create an edge in the graph. Retracing may yield none if
// some of the data happens to have been removed; this ought
// to be impossible unless it is dirty, so we can unwrap.
let
source_node
=
retraced
.map
(
source
)
.unwrap
();
let
target_node
=
retraced
.map
(
target
)
.unwrap
();
let
_
task
=
tcx
.dep_graph
.in_task
(
target_node
);
tcx
.dep_graph
.read
(
source_node
);
if
let
DepNode
::
WorkProduct
(
ref
wp
)
=
*
target
{
clean_work_products
.insert
(
wp
.clone
());
}
}
}
...
...
@@ -268,16 +275,23 @@ fn initial_dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
dirty_nodes
}
fn
transitive_dirty_nodes
(
edge
s
:
&
[
SerializedEdge
]
,
fn
transitive_dirty_nodes
(
edge
_map
:
&
FxHashMap
<
DepNode
<
DefPathIndex
>
,
Vec
<
DepNode
<
DefPathIndex
>>>
,
mut
dirty_nodes
:
DirtyNodes
)
->
DirtyNodes
{
let
mut
len
=
0
;
while
len
!=
dirty_nodes
.len
()
{
len
=
dirty_nodes
.len
();
for
edge
in
edges
{
if
let
Some
(
n
)
=
dirty_nodes
.get
(
&
edge
.0
)
.cloned
()
{
dirty_nodes
.insert
(
edge
.1
.clone
(),
n
);
let
mut
stack
:
Vec
<
(
DepNode
<
DefPathIndex
>
,
DepNode
<
DefPathIndex
>
)
>
=
vec!
[];
stack
.extend
(
dirty_nodes
.iter
()
.map
(|(
s
,
b
)|
(
s
.clone
(),
b
.clone
())));
while
let
Some
((
source
,
blame
))
=
stack
.pop
()
{
// we know the source is dirty (because of the node `blame`)...
assert
!
(
dirty_nodes
.contains_key
(
&
source
));
// ...so we dirty all the targets (with the same blame)
if
let
Some
(
targets
)
=
edge_map
.get
(
&
source
)
{
for
target
in
targets
{
if
!
dirty_nodes
.contains_key
(
target
)
{
dirty_nodes
.insert
(
target
.clone
(),
blame
.clone
());
stack
.push
((
target
.clone
(),
blame
.clone
()));
}
}
}
}
...
...
src/librustc_incremental/persist/save.rs
浏览文件 @
ef9ae858
...
...
@@ -178,7 +178,7 @@ pub fn encode_dep_graph(preds: &Predecessors,
// Create a flat list of (Input, WorkProduct) edges for
// serialization.
let
mut
edges
=
vec!
[]
;
let
mut
edges
=
FxHashMap
()
;
for
edge
in
preds
.reduced_graph
.all_edges
()
{
let
source
=
*
preds
.reduced_graph
.node_data
(
edge
.source
());
let
target
=
*
preds
.reduced_graph
.node_data
(
edge
.target
());
...
...
@@ -194,7 +194,7 @@ pub fn encode_dep_graph(preds: &Predecessors,
debug!
(
"serialize edge: {:?} -> {:?}"
,
source
,
target
);
let
source
=
builder
.map
(
source
);
let
target
=
builder
.map
(
target
);
edges
.
push
((
source
,
target
)
);
edges
.
entry
(
source
)
.or_insert
(
vec!
[])
.push
(
target
);
}
if
tcx
.sess.opts.debugging_opts.incremental_dump_hash
{
...
...
@@ -204,6 +204,9 @@ pub fn encode_dep_graph(preds: &Predecessors,
}
// Create the serialized dep-graph.
let
edges
=
edges
.into_iter
()
.map
(|(
k
,
v
)|
SerializedEdgeSet
{
source
:
k
,
targets
:
v
})
.collect
();
let
graph
=
SerializedDepGraph
{
edges
:
edges
,
hashes
:
preds
.hashes
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录