Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
654e029b
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
654e029b
编写于
8月 14, 2009
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6862956: PhaseIdealLoop should have a CFG verification mode
Reviewed-by: kvn, twisti
上级
f0c9f327
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
247 addition
and
128 deletion
+247
-128
src/share/vm/opto/compile.cpp
src/share/vm/opto/compile.cpp
+17
-4
src/share/vm/opto/domgraph.cpp
src/share/vm/opto/domgraph.cpp
+3
-3
src/share/vm/opto/loopnode.cpp
src/share/vm/opto/loopnode.cpp
+139
-84
src/share/vm/opto/loopnode.hpp
src/share/vm/opto/loopnode.hpp
+53
-5
src/share/vm/opto/phase.cpp
src/share/vm/opto/phase.cpp
+33
-31
src/share/vm/opto/phase.hpp
src/share/vm/opto/phase.hpp
+2
-1
未找到文件。
src/share/vm/opto/compile.cpp
浏览文件 @
654e029b
...
@@ -1545,7 +1545,7 @@ void Compile::Optimize() {
...
@@ -1545,7 +1545,7 @@ void Compile::Optimize() {
if
((
loop_opts_cnt
>
0
)
&&
(
has_loops
()
||
has_split_ifs
()))
{
if
((
loop_opts_cnt
>
0
)
&&
(
has_loops
()
||
has_split_ifs
()))
{
{
{
TracePhase
t2
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
TracePhase
t2
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
PhaseIdealLoop
ideal_loop
(
igvn
,
NULL
,
true
);
PhaseIdealLoop
ideal_loop
(
igvn
,
true
);
loop_opts_cnt
--
;
loop_opts_cnt
--
;
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 1"
,
2
);
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 1"
,
2
);
if
(
failing
())
return
;
if
(
failing
())
return
;
...
@@ -1553,7 +1553,7 @@ void Compile::Optimize() {
...
@@ -1553,7 +1553,7 @@ void Compile::Optimize() {
// Loop opts pass if partial peeling occurred in previous pass
// Loop opts pass if partial peeling occurred in previous pass
if
(
PartialPeelLoop
&&
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
if
(
PartialPeelLoop
&&
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
TracePhase
t3
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
TracePhase
t3
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
PhaseIdealLoop
ideal_loop
(
igvn
,
NULL
,
false
);
PhaseIdealLoop
ideal_loop
(
igvn
,
false
);
loop_opts_cnt
--
;
loop_opts_cnt
--
;
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 2"
,
2
);
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 2"
,
2
);
if
(
failing
())
return
;
if
(
failing
())
return
;
...
@@ -1561,10 +1561,15 @@ void Compile::Optimize() {
...
@@ -1561,10 +1561,15 @@ void Compile::Optimize() {
// Loop opts pass for loop-unrolling before CCP
// Loop opts pass for loop-unrolling before CCP
if
(
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
if
(
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
TracePhase
t4
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
TracePhase
t4
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
PhaseIdealLoop
ideal_loop
(
igvn
,
NULL
,
false
);
PhaseIdealLoop
ideal_loop
(
igvn
,
false
);
loop_opts_cnt
--
;
loop_opts_cnt
--
;
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 3"
,
2
);
if
(
major_progress
())
print_method
(
"PhaseIdealLoop 3"
,
2
);
}
}
if
(
!
failing
())
{
// Verify that last round of loop opts produced a valid graph
NOT_PRODUCT
(
TracePhase
t2
(
"idealLoopVerify"
,
&
_t_idealLoopVerify
,
TimeCompiler
);
)
PhaseIdealLoop
::
verify
(
igvn
);
}
}
}
if
(
failing
())
return
;
if
(
failing
())
return
;
...
@@ -1597,12 +1602,20 @@ void Compile::Optimize() {
...
@@ -1597,12 +1602,20 @@ void Compile::Optimize() {
while
(
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
while
(
major_progress
()
&&
(
loop_opts_cnt
>
0
))
{
TracePhase
t2
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
TracePhase
t2
(
"idealLoop"
,
&
_t_idealLoop
,
true
);
assert
(
cnt
++
<
40
,
"infinite cycle in loop optimization"
);
assert
(
cnt
++
<
40
,
"infinite cycle in loop optimization"
);
PhaseIdealLoop
ideal_loop
(
igvn
,
NULL
,
true
);
PhaseIdealLoop
ideal_loop
(
igvn
,
true
);
loop_opts_cnt
--
;
loop_opts_cnt
--
;
if
(
major_progress
())
print_method
(
"PhaseIdealLoop iterations"
,
2
);
if
(
major_progress
())
print_method
(
"PhaseIdealLoop iterations"
,
2
);
if
(
failing
())
return
;
if
(
failing
())
return
;
}
}
}
}
{
// Verify that all previous optimizations produced a valid graph
// at least to this point, even if no loop optimizations were done.
NOT_PRODUCT
(
TracePhase
t2
(
"idealLoopVerify"
,
&
_t_idealLoopVerify
,
TimeCompiler
);
)
PhaseIdealLoop
::
verify
(
igvn
);
}
{
{
NOT_PRODUCT
(
TracePhase
t2
(
"macroExpand"
,
&
_t_macroExpand
,
TimeCompiler
);
)
NOT_PRODUCT
(
TracePhase
t2
(
"macroExpand"
,
&
_t_macroExpand
,
TimeCompiler
);
)
PhaseMacroExpand
mex
(
igvn
);
PhaseMacroExpand
mex
(
igvn
);
...
...
src/share/vm/opto/domgraph.cpp
浏览文件 @
654e029b
/*
/*
* Copyright 1997-200
5
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-200
9
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -396,7 +396,7 @@ struct NTarjan {
...
@@ -396,7 +396,7 @@ struct NTarjan {
// nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
// nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
// it needs a count of the CFG nodes for the mapping table. This is the
// it needs a count of the CFG nodes for the mapping table. This is the
// Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
// Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
void
PhaseIdealLoop
::
Dominators
(
)
{
void
PhaseIdealLoop
::
Dominators
()
{
ResourceMark
rm
;
ResourceMark
rm
;
// Setup mappings from my Graph to Tarjan's stuff and back
// Setup mappings from my Graph to Tarjan's stuff and back
// Note: Tarjan uses 1-based arrays
// Note: Tarjan uses 1-based arrays
...
@@ -454,7 +454,7 @@ void PhaseIdealLoop::Dominators( ) {
...
@@ -454,7 +454,7 @@ void PhaseIdealLoop::Dominators( ) {
// flow into the main graph (and hence into ROOT) but are not reachable
// flow into the main graph (and hence into ROOT) but are not reachable
// from above. Such code is dead, but requires a global pass to detect
// from above. Such code is dead, but requires a global pass to detect
// it; this global pass was the 'build_loop_tree' pass run just prior.
// it; this global pass was the 'build_loop_tree' pass run just prior.
if
(
whead
->
is_Region
()
)
{
if
(
!
_verify_only
&&
whead
->
is_Region
()
)
{
for
(
uint
i
=
1
;
i
<
whead
->
req
();
i
++
)
{
for
(
uint
i
=
1
;
i
<
whead
->
req
();
i
++
)
{
if
(
!
has_node
(
whead
->
in
(
i
)))
{
if
(
!
has_node
(
whead
->
in
(
i
)))
{
// Kill dead input path
// Kill dead input path
...
...
src/share/vm/opto/loopnode.cpp
浏览文件 @
654e029b
...
@@ -1420,13 +1420,12 @@ static void log_loop_tree(IdealLoopTree* root, IdealLoopTree* loop, CompileLog*
...
@@ -1420,13 +1420,12 @@ static void log_loop_tree(IdealLoopTree* root, IdealLoopTree* loop, CompileLog*
}
}
//=============================================================================
//=============================================================================
//----------------------------
--PhaseIdealLoop--
-------------------------------
//----------------------------
build_and_optimize
-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
PhaseIdealLoop
::
PhaseIdealLoop
(
PhaseIterGVN
&
igvn
,
const
PhaseIdealLoop
*
verify_me
,
bool
do_split_ifs
)
void
PhaseIdealLoop
::
build_and_optimize
(
bool
do_split_ifs
)
{
:
PhaseTransform
(
Ideal_Loop
),
int
old_progress
=
C
->
major_progress
();
_igvn
(
igvn
),
_dom_lca_tags
(
C
->
comp_arena
())
{
// Reset major-progress flag for the driver's heuristics
// Reset major-progress flag for the driver's heuristics
C
->
clear_major_progress
();
C
->
clear_major_progress
();
...
@@ -1465,18 +1464,20 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
...
@@ -1465,18 +1464,20 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
}
}
// No loops after all
// No loops after all
if
(
!
_ltree_root
->
_child
)
C
->
set_has_loops
(
false
);
if
(
!
_ltree_root
->
_child
&&
!
_verify_only
)
C
->
set_has_loops
(
false
);
// There should always be an outer loop containing the Root and Return nodes.
// There should always be an outer loop containing the Root and Return nodes.
// If not, we have a degenerate empty program. Bail out in this case.
// If not, we have a degenerate empty program. Bail out in this case.
if
(
!
has_node
(
C
->
root
()))
{
if
(
!
has_node
(
C
->
root
()))
{
C
->
clear_major_progress
();
if
(
!
_verify_only
)
{
C
->
record_method_not_compilable
(
"empty program detected during loop optimization"
);
C
->
clear_major_progress
();
C
->
record_method_not_compilable
(
"empty program detected during loop optimization"
);
}
return
;
return
;
}
}
// Nothing to do, so get out
// Nothing to do, so get out
if
(
!
C
->
has_loops
()
&&
!
do_split_ifs
&&
!
verify_me
)
{
if
(
!
C
->
has_loops
()
&&
!
do_split_ifs
&&
!
_verify_me
&&
!
_verify_only
)
{
_igvn
.
optimize
();
// Cleanup NeverBranches
_igvn
.
optimize
();
// Cleanup NeverBranches
return
;
return
;
}
}
...
@@ -1486,7 +1487,7 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
...
@@ -1486,7 +1487,7 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
// Split shared headers and insert loop landing pads.
// Split shared headers and insert loop landing pads.
// Do not bother doing this on the Root loop of course.
// Do not bother doing this on the Root loop of course.
if
(
!
verify_me
&&
_ltree_root
->
_child
)
{
if
(
!
_verify_me
&&
!
_verify_only
&&
_ltree_root
->
_child
)
{
if
(
_ltree_root
->
_child
->
beautify_loops
(
this
)
)
{
if
(
_ltree_root
->
_child
->
beautify_loops
(
this
)
)
{
// Re-build loop tree!
// Re-build loop tree!
_ltree_root
->
_child
=
NULL
;
_ltree_root
->
_child
=
NULL
;
...
@@ -1515,23 +1516,25 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
...
@@ -1515,23 +1516,25 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
Dominators
();
Dominators
();
// As a side effect, Dominators removed any unreachable CFG paths
if
(
!
_verify_only
)
{
// into RegionNodes. It doesn't do this test against Root, so
// As a side effect, Dominators removed any unreachable CFG paths
// we do it here.
// into RegionNodes. It doesn't do this test against Root, so
for
(
uint
i
=
1
;
i
<
C
->
root
()
->
req
();
i
++
)
{
// we do it here.
if
(
!
_nodes
[
C
->
root
()
->
in
(
i
)
->
_idx
]
)
{
// Dead path into Root?
for
(
uint
i
=
1
;
i
<
C
->
root
()
->
req
();
i
++
)
{
_igvn
.
hash_delete
(
C
->
root
());
if
(
!
_nodes
[
C
->
root
()
->
in
(
i
)
->
_idx
]
)
{
// Dead path into Root?
C
->
root
()
->
del_req
(
i
);
_igvn
.
hash_delete
(
C
->
root
());
_igvn
.
_worklist
.
push
(
C
->
root
());
C
->
root
()
->
del_req
(
i
);
i
--
;
// Rerun same iteration on compressed edges
_igvn
.
_worklist
.
push
(
C
->
root
());
i
--
;
// Rerun same iteration on compressed edges
}
}
}
}
// Given dominators, try to find inner loops with calls that must
// Given dominators, try to find inner loops with calls that must
// always be executed (call dominates loop tail). These loops do
// always be executed (call dominates loop tail). These loops do
// not need a separate safepoint.
// not need a separate safepoint.
Node_List
cisstack
(
a
);
Node_List
cisstack
(
a
);
_ltree_root
->
check_safepts
(
visited
,
cisstack
);
_ltree_root
->
check_safepts
(
visited
,
cisstack
);
}
// Walk the DATA nodes and place into loops. Find earliest control
// Walk the DATA nodes and place into loops. Find earliest control
// node. For CFG nodes, the _nodes array starts out and remains
// node. For CFG nodes, the _nodes array starts out and remains
...
@@ -1548,11 +1551,11 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
...
@@ -1548,11 +1551,11 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
// it will be processed among C->top() inputs
// it will be processed among C->top() inputs
worklist
.
push
(
C
->
top
()
);
worklist
.
push
(
C
->
top
()
);
visited
.
set
(
C
->
top
()
->
_idx
);
// Set C->top() as visited now
visited
.
set
(
C
->
top
()
->
_idx
);
// Set C->top() as visited now
build_loop_early
(
visited
,
worklist
,
nstack
,
verify_me
);
build_loop_early
(
visited
,
worklist
,
nstack
);
// Given early legal placement, try finding counted loops. This placement
// Given early legal placement, try finding counted loops. This placement
// is good enough to discover most loop invariants.
// is good enough to discover most loop invariants.
if
(
!
verify_me
)
if
(
!
_verify_me
&&
!
_verify_only
)
_ltree_root
->
counted_loop
(
this
);
_ltree_root
->
counted_loop
(
this
);
// Find latest loop placement. Find ideal loop placement.
// Find latest loop placement. Find ideal loop placement.
...
@@ -1562,16 +1565,25 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
...
@@ -1562,16 +1565,25 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify
worklist
.
push
(
C
->
root
()
);
worklist
.
push
(
C
->
root
()
);
NOT_PRODUCT
(
C
->
verify_graph_edges
();
)
NOT_PRODUCT
(
C
->
verify_graph_edges
();
)
worklist
.
push
(
C
->
top
()
);
worklist
.
push
(
C
->
top
()
);
build_loop_late
(
visited
,
worklist
,
nstack
,
verify_me
);
build_loop_late
(
visited
,
worklist
,
nstack
);
if
(
_verify_only
)
{
// restore major progress flag
for
(
int
i
=
0
;
i
<
old_progress
;
i
++
)
C
->
set_major_progress
();
assert
(
C
->
unique
()
==
unique
,
"verification mode made Nodes? ? ?"
);
assert
(
_igvn
.
_worklist
.
size
()
==
0
,
"shouldn't push anything"
);
return
;
}
// clear out the dead code
// clear out the dead code
while
(
_deadlist
.
size
())
{
while
(
_deadlist
.
size
())
{
igvn
.
remove_globally_dead_node
(
_deadlist
.
pop
());
_
igvn
.
remove_globally_dead_node
(
_deadlist
.
pop
());
}
}
#ifndef PRODUCT
#ifndef PRODUCT
C
->
verify_graph_edges
();
C
->
verify_graph_edges
();
if
(
verify_me
)
{
// Nested verify pass?
if
(
_
verify_me
)
{
// Nested verify pass?
// Check to see if the verify mode is broken
// Check to see if the verify mode is broken
assert
(
C
->
unique
()
==
unique
,
"non-optimize mode made Nodes? ? ?"
);
assert
(
C
->
unique
()
==
unique
,
"non-optimize mode made Nodes? ? ?"
);
return
;
return
;
...
@@ -1678,7 +1690,7 @@ static int fail; // debug only, so its multi-thread dont care
...
@@ -1678,7 +1690,7 @@ static int fail; // debug only, so its multi-thread dont care
void
PhaseIdealLoop
::
verify
()
const
{
void
PhaseIdealLoop
::
verify
()
const
{
int
old_progress
=
C
->
major_progress
();
int
old_progress
=
C
->
major_progress
();
ResourceMark
rm
;
ResourceMark
rm
;
PhaseIdealLoop
loop_verify
(
_igvn
,
this
,
false
);
PhaseIdealLoop
loop_verify
(
_igvn
,
this
);
VectorSet
visited
(
Thread
::
current
()
->
resource_area
());
VectorSet
visited
(
Thread
::
current
()
->
resource_area
());
fail
=
0
;
fail
=
0
;
...
@@ -2138,54 +2150,58 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
...
@@ -2138,54 +2150,58 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
// optimizing an infinite loop?
// optimizing an infinite loop?
l
=
_ltree_root
;
// Oops, found infinite loop
l
=
_ltree_root
;
// Oops, found infinite loop
// Insert the NeverBranch between 'm' and it's control user.
if
(
!
_verify_only
)
{
NeverBranchNode
*
iff
=
new
(
C
,
1
)
NeverBranchNode
(
m
);
// Insert the NeverBranch between 'm' and it's control user.
_igvn
.
register_new_node_with_optimizer
(
iff
);
NeverBranchNode
*
iff
=
new
(
C
,
1
)
NeverBranchNode
(
m
);
set_loop
(
iff
,
l
);
_igvn
.
register_new_node_with_optimizer
(
iff
);
Node
*
if_t
=
new
(
C
,
1
)
CProjNode
(
iff
,
0
);
set_loop
(
iff
,
l
);
_igvn
.
register_new_node_with_optimizer
(
if_t
);
Node
*
if_t
=
new
(
C
,
1
)
CProjNode
(
iff
,
0
);
set_loop
(
if_t
,
l
);
_igvn
.
register_new_node_with_optimizer
(
if_t
);
set_loop
(
if_t
,
l
);
Node
*
cfg
=
NULL
;
// Find the One True Control User of m
for
(
DUIterator_Fast
jmax
,
j
=
m
->
fast_outs
(
jmax
);
j
<
jmax
;
j
++
)
{
Node
*
cfg
=
NULL
;
// Find the One True Control User of m
Node
*
x
=
m
->
fast_out
(
j
);
for
(
DUIterator_Fast
jmax
,
j
=
m
->
fast_outs
(
jmax
);
j
<
jmax
;
j
++
)
{
if
(
x
->
is_CFG
()
&&
x
!=
m
&&
x
!=
iff
)
Node
*
x
=
m
->
fast_out
(
j
);
{
cfg
=
x
;
break
;
}
if
(
x
->
is_CFG
()
&&
x
!=
m
&&
x
!=
iff
)
{
cfg
=
x
;
break
;
}
}
assert
(
cfg
!=
NULL
,
"must find the control user of m"
);
uint
k
=
0
;
// Probably cfg->in(0)
while
(
cfg
->
in
(
k
)
!=
m
)
k
++
;
// But check incase cfg is a Region
cfg
->
set_req
(
k
,
if_t
);
// Now point to NeverBranch
// Now create the never-taken loop exit
Node
*
if_f
=
new
(
C
,
1
)
CProjNode
(
iff
,
1
);
_igvn
.
register_new_node_with_optimizer
(
if_f
);
set_loop
(
if_f
,
l
);
// Find frame ptr for Halt. Relies on the optimizer
// V-N'ing. Easier and quicker than searching through
// the program structure.
Node
*
frame
=
new
(
C
,
1
)
ParmNode
(
C
->
start
(),
TypeFunc
::
FramePtr
);
_igvn
.
register_new_node_with_optimizer
(
frame
);
// Halt & Catch Fire
Node
*
halt
=
new
(
C
,
TypeFunc
::
Parms
)
HaltNode
(
if_f
,
frame
);
_igvn
.
register_new_node_with_optimizer
(
halt
);
set_loop
(
halt
,
l
);
C
->
root
()
->
add_req
(
halt
);
}
}
assert
(
cfg
!=
NULL
,
"must find the control user of m"
);
uint
k
=
0
;
// Probably cfg->in(0)
while
(
cfg
->
in
(
k
)
!=
m
)
k
++
;
// But check incase cfg is a Region
cfg
->
set_req
(
k
,
if_t
);
// Now point to NeverBranch
// Now create the never-taken loop exit
Node
*
if_f
=
new
(
C
,
1
)
CProjNode
(
iff
,
1
);
_igvn
.
register_new_node_with_optimizer
(
if_f
);
set_loop
(
if_f
,
l
);
// Find frame ptr for Halt. Relies on the optimizer
// V-N'ing. Easier and quicker than searching through
// the program structure.
Node
*
frame
=
new
(
C
,
1
)
ParmNode
(
C
->
start
(),
TypeFunc
::
FramePtr
);
_igvn
.
register_new_node_with_optimizer
(
frame
);
// Halt & Catch Fire
Node
*
halt
=
new
(
C
,
TypeFunc
::
Parms
)
HaltNode
(
if_f
,
frame
);
_igvn
.
register_new_node_with_optimizer
(
halt
);
set_loop
(
halt
,
l
);
C
->
root
()
->
add_req
(
halt
);
set_loop
(
C
->
root
(),
_ltree_root
);
set_loop
(
C
->
root
(),
_ltree_root
);
}
}
}
}
// Weeny check for irreducible. This child was already visited (this
// Weeny check for irreducible. This child was already visited (this
// IS the post-work phase). Is this child's loop header post-visited
// IS the post-work phase). Is this child's loop header post-visited
// as well? If so, then I found another entry into the loop.
// as well? If so, then I found another entry into the loop.
while
(
is_postvisited
(
l
->
_head
)
)
{
if
(
!
_verify_only
)
{
// found irreducible
while
(
is_postvisited
(
l
->
_head
)
)
{
l
->
_irreducible
=
1
;
// = true
// found irreducible
l
=
l
->
_parent
;
l
->
_irreducible
=
1
;
// = true
_has_irreducible_loops
=
true
;
l
=
l
->
_parent
;
// Check for bad CFG here to prevent crash, and bailout of compile
_has_irreducible_loops
=
true
;
if
(
l
==
NULL
)
{
// Check for bad CFG here to prevent crash, and bailout of compile
C
->
record_method_not_compilable
(
"unhandled CFG detected during loop optimization"
);
if
(
l
==
NULL
)
{
return
pre_order
;
C
->
record_method_not_compilable
(
"unhandled CFG detected during loop optimization"
);
return
pre_order
;
}
}
}
}
}
...
@@ -2253,7 +2269,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
...
@@ -2253,7 +2269,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// First pass computes the earliest controlling node possible. This is the
// First pass computes the earliest controlling node possible. This is the
// controlling input with the deepest dominating depth.
// controlling input with the deepest dominating depth.
void
PhaseIdealLoop
::
build_loop_early
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
,
const
PhaseIdealLoop
*
verify_me
)
{
void
PhaseIdealLoop
::
build_loop_early
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
)
{
while
(
worklist
.
size
()
!=
0
)
{
while
(
worklist
.
size
()
!=
0
)
{
// Use local variables nstack_top_n & nstack_top_i to cache values
// Use local variables nstack_top_n & nstack_top_i to cache values
// on nstack's top.
// on nstack's top.
...
@@ -2285,7 +2301,7 @@ void PhaseIdealLoop::build_loop_early( VectorSet &visited, Node_List &worklist,
...
@@ -2285,7 +2301,7 @@ void PhaseIdealLoop::build_loop_early( VectorSet &visited, Node_List &worklist,
// (the old code here would yank a 2nd safepoint after seeing a
// (the old code here would yank a 2nd safepoint after seeing a
// first one, even though the 1st did not dominate in the loop body
// first one, even though the 1st did not dominate in the loop body
// and thus could be avoided indefinitely)
// and thus could be avoided indefinitely)
if
(
!
verify_me
&&
ilt
->
_has_sfpt
&&
n
->
Opcode
()
==
Op_SafePoint
&&
if
(
!
_verify_only
&&
!
_
verify_me
&&
ilt
->
_has_sfpt
&&
n
->
Opcode
()
==
Op_SafePoint
&&
is_deleteable_safept
(
n
))
{
is_deleteable_safept
(
n
))
{
Node
*
in
=
n
->
in
(
TypeFunc
::
Control
);
Node
*
in
=
n
->
in
(
TypeFunc
::
Control
);
lazy_replace
(
n
,
in
);
// Pull safepoint now
lazy_replace
(
n
,
in
);
// Pull safepoint now
...
@@ -2408,12 +2424,31 @@ Node *PhaseIdealLoop::compute_idom( Node *region ) const {
...
@@ -2408,12 +2424,31 @@ Node *PhaseIdealLoop::compute_idom( Node *region ) const {
return
LCA
;
return
LCA
;
}
}
//------------------------------get_late_ctrl----------------------------------
bool
PhaseIdealLoop
::
verify_dominance
(
Node
*
n
,
Node
*
use
,
Node
*
LCA
,
Node
*
early
)
{
// Compute latest legal control.
bool
had_error
=
false
;
Node
*
PhaseIdealLoop
::
get_late_ctrl
(
Node
*
n
,
Node
*
early
)
{
#ifdef ASSERT
assert
(
early
!=
NULL
,
"early control should not be NULL"
);
if
(
early
!=
C
->
root
())
{
// Make sure that there's a dominance path from use to LCA
Node
*
d
=
use
;
while
(
d
!=
LCA
)
{
d
=
idom
(
d
);
if
(
d
==
C
->
root
())
{
tty
->
print_cr
(
"*** Use %d isn't dominated by def %s"
,
use
->
_idx
,
n
->
_idx
);
n
->
dump
();
use
->
dump
();
had_error
=
true
;
break
;
}
}
}
#endif
return
had_error
;
}
Node
*
PhaseIdealLoop
::
compute_lca_of_uses
(
Node
*
n
,
Node
*
early
,
bool
verify
)
{
// Compute LCA over list of uses
// Compute LCA over list of uses
bool
had_error
=
false
;
Node
*
LCA
=
NULL
;
Node
*
LCA
=
NULL
;
for
(
DUIterator_Fast
imax
,
i
=
n
->
fast_outs
(
imax
);
i
<
imax
&&
LCA
!=
early
;
i
++
)
{
for
(
DUIterator_Fast
imax
,
i
=
n
->
fast_outs
(
imax
);
i
<
imax
&&
LCA
!=
early
;
i
++
)
{
Node
*
c
=
n
->
fast_out
(
i
);
Node
*
c
=
n
->
fast_out
(
i
);
...
@@ -2423,15 +2458,34 @@ Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
...
@@ -2423,15 +2458,34 @@ Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
for
(
uint
j
=
1
;
j
<
c
->
req
();
j
++
)
{
// For all inputs
for
(
uint
j
=
1
;
j
<
c
->
req
();
j
++
)
{
// For all inputs
if
(
c
->
in
(
j
)
==
n
)
{
// Found matching input?
if
(
c
->
in
(
j
)
==
n
)
{
// Found matching input?
Node
*
use
=
c
->
in
(
0
)
->
in
(
j
);
Node
*
use
=
c
->
in
(
0
)
->
in
(
j
);
if
(
_verify_only
&&
use
->
is_top
())
continue
;
LCA
=
dom_lca_for_get_late_ctrl
(
LCA
,
use
,
n
);
LCA
=
dom_lca_for_get_late_ctrl
(
LCA
,
use
,
n
);
if
(
verify
)
had_error
=
verify_dominance
(
n
,
use
,
LCA
,
early
)
||
had_error
;
}
}
}
}
}
else
{
}
else
{
// For CFG data-users, use is in the block just prior
// For CFG data-users, use is in the block just prior
Node
*
use
=
has_ctrl
(
c
)
?
get_ctrl
(
c
)
:
c
->
in
(
0
);
Node
*
use
=
has_ctrl
(
c
)
?
get_ctrl
(
c
)
:
c
->
in
(
0
);
LCA
=
dom_lca_for_get_late_ctrl
(
LCA
,
use
,
n
);
LCA
=
dom_lca_for_get_late_ctrl
(
LCA
,
use
,
n
);
if
(
verify
)
had_error
=
verify_dominance
(
n
,
use
,
LCA
,
early
)
||
had_error
;
}
}
}
}
assert
(
!
had_error
,
"bad dominance"
);
return
LCA
;
}
//------------------------------get_late_ctrl----------------------------------
// Compute latest legal control.
Node
*
PhaseIdealLoop
::
get_late_ctrl
(
Node
*
n
,
Node
*
early
)
{
assert
(
early
!=
NULL
,
"early control should not be NULL"
);
Node
*
LCA
=
compute_lca_of_uses
(
n
,
early
);
#ifdef ASSERT
if
(
LCA
==
C
->
root
()
&&
LCA
!=
early
)
{
// def doesn't dominate uses so print some useful debugging output
compute_lca_of_uses
(
n
,
early
,
true
);
}
#endif
// if this is a load, check for anti-dependent stores
// if this is a load, check for anti-dependent stores
// We use a conservative algorithm to identify potential interfering
// We use a conservative algorithm to identify potential interfering
...
@@ -2576,7 +2630,7 @@ void PhaseIdealLoop::clear_dom_lca_tags() {
...
@@ -2576,7 +2630,7 @@ void PhaseIdealLoop::clear_dom_lca_tags() {
//------------------------------build_loop_late--------------------------------
//------------------------------build_loop_late--------------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Second pass finds latest legal placement, and ideal loop placement.
// Second pass finds latest legal placement, and ideal loop placement.
void
PhaseIdealLoop
::
build_loop_late
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
,
const
PhaseIdealLoop
*
verify_me
)
{
void
PhaseIdealLoop
::
build_loop_late
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
)
{
while
(
worklist
.
size
()
!=
0
)
{
while
(
worklist
.
size
()
!=
0
)
{
Node
*
n
=
worklist
.
pop
();
Node
*
n
=
worklist
.
pop
();
// Only visit once
// Only visit once
...
@@ -2612,7 +2666,7 @@ void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, N
...
@@ -2612,7 +2666,7 @@ void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, N
}
}
}
else
{
}
else
{
// All of n's children have been processed, complete post-processing.
// All of n's children have been processed, complete post-processing.
build_loop_late_post
(
n
,
verify_me
);
build_loop_late_post
(
n
);
if
(
nstack
.
is_empty
())
{
if
(
nstack
.
is_empty
())
{
// Finished all nodes on stack.
// Finished all nodes on stack.
// Process next node on the worklist.
// Process next node on the worklist.
...
@@ -2631,9 +2685,9 @@ void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, N
...
@@ -2631,9 +2685,9 @@ void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, N
//------------------------------build_loop_late_post---------------------------
//------------------------------build_loop_late_post---------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Second pass finds latest legal placement, and ideal loop placement.
// Second pass finds latest legal placement, and ideal loop placement.
void
PhaseIdealLoop
::
build_loop_late_post
(
Node
*
n
,
const
PhaseIdealLoop
*
verify_me
)
{
void
PhaseIdealLoop
::
build_loop_late_post
(
Node
*
n
)
{
if
(
n
->
req
()
==
2
&&
n
->
Opcode
()
==
Op_ConvI2L
&&
!
C
->
major_progress
())
{
if
(
n
->
req
()
==
2
&&
n
->
Opcode
()
==
Op_ConvI2L
&&
!
C
->
major_progress
()
&&
!
_verify_only
)
{
_igvn
.
_worklist
.
push
(
n
);
// Maybe we'll normalize it, if no more loops.
_igvn
.
_worklist
.
push
(
n
);
// Maybe we'll normalize it, if no more loops.
}
}
...
@@ -2714,6 +2768,7 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify
...
@@ -2714,6 +2768,7 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify
if
(
get_loop
(
legal
)
->
_nest
<
get_loop
(
least
)
->
_nest
)
if
(
get_loop
(
legal
)
->
_nest
<
get_loop
(
least
)
->
_nest
)
least
=
legal
;
least
=
legal
;
}
}
assert
(
early
==
legal
||
legal
!=
C
->
root
(),
"bad dominance of inputs"
);
// Try not to place code on a loop entry projection
// Try not to place code on a loop entry projection
// which can inhibit range check elimination.
// which can inhibit range check elimination.
...
@@ -2731,8 +2786,8 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify
...
@@ -2731,8 +2786,8 @@ void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify
#ifdef ASSERT
#ifdef ASSERT
// If verifying, verify that 'verify_me' has a legal location
// If verifying, verify that 'verify_me' has a legal location
// and choose it as our location.
// and choose it as our location.
if
(
verify_me
)
{
if
(
_
verify_me
)
{
Node
*
v_ctrl
=
verify_me
->
get_ctrl_no_update
(
n
);
Node
*
v_ctrl
=
_
verify_me
->
get_ctrl_no_update
(
n
);
Node
*
legal
=
LCA
;
Node
*
legal
=
LCA
;
while
(
early
!=
legal
)
{
// While not at earliest legal
while
(
early
!=
legal
)
{
// While not at earliest legal
if
(
legal
==
v_ctrl
)
break
;
// Check for prior good location
if
(
legal
==
v_ctrl
)
break
;
// Check for prior good location
...
...
src/share/vm/opto/loopnode.hpp
浏览文件 @
654e029b
/*
/*
* Copyright 1998-200
8
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-200
9
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -442,6 +442,9 @@ class PhaseIdealLoop : public PhaseTransform {
...
@@ -442,6 +442,9 @@ class PhaseIdealLoop : public PhaseTransform {
uint
*
_preorders
;
uint
*
_preorders
;
uint
_max_preorder
;
uint
_max_preorder
;
const
PhaseIdealLoop
*
_verify_me
;
bool
_verify_only
;
// Allocate _preorders[] array
// Allocate _preorders[] array
void
allocate_preorders
()
{
void
allocate_preorders
()
{
_max_preorder
=
C
->
unique
()
+
8
;
_max_preorder
=
C
->
unique
()
+
8
;
...
@@ -497,6 +500,12 @@ class PhaseIdealLoop : public PhaseTransform {
...
@@ -497,6 +500,12 @@ class PhaseIdealLoop : public PhaseTransform {
Node_Array
_dom_lca_tags
;
Node_Array
_dom_lca_tags
;
void
init_dom_lca_tags
();
void
init_dom_lca_tags
();
void
clear_dom_lca_tags
();
void
clear_dom_lca_tags
();
// Helper for debugging bad dominance relationships
bool
verify_dominance
(
Node
*
n
,
Node
*
use
,
Node
*
LCA
,
Node
*
early
);
Node
*
compute_lca_of_uses
(
Node
*
n
,
Node
*
early
,
bool
verify
=
false
);
// Inline wrapper for frequent cases:
// Inline wrapper for frequent cases:
// 1) only one use
// 1) only one use
// 2) a use is the same as the current LCA passed as 'n1'
// 2) a use is the same as the current LCA passed as 'n1'
...
@@ -511,6 +520,7 @@ class PhaseIdealLoop : public PhaseTransform {
...
@@ -511,6 +520,7 @@ class PhaseIdealLoop : public PhaseTransform {
return
find_non_split_ctrl
(
n
);
return
find_non_split_ctrl
(
n
);
}
}
Node
*
dom_lca_for_get_late_ctrl_internal
(
Node
*
lca
,
Node
*
n
,
Node
*
tag
);
Node
*
dom_lca_for_get_late_ctrl_internal
(
Node
*
lca
,
Node
*
n
,
Node
*
tag
);
// true if CFG node d dominates CFG node n
// true if CFG node d dominates CFG node n
bool
is_dominator
(
Node
*
d
,
Node
*
n
);
bool
is_dominator
(
Node
*
d
,
Node
*
n
);
...
@@ -621,9 +631,9 @@ private:
...
@@ -621,9 +631,9 @@ private:
IdealLoopTree
*
sort
(
IdealLoopTree
*
loop
,
IdealLoopTree
*
innermost
);
IdealLoopTree
*
sort
(
IdealLoopTree
*
loop
,
IdealLoopTree
*
innermost
);
// Place Data nodes in some loop nest
// Place Data nodes in some loop nest
void
build_loop_early
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
,
const
PhaseIdealLoop
*
verify_me
);
void
build_loop_early
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
);
void
build_loop_late
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
,
const
PhaseIdealLoop
*
verify_me
);
void
build_loop_late
(
VectorSet
&
visited
,
Node_List
&
worklist
,
Node_Stack
&
nstack
);
void
build_loop_late_post
(
Node
*
n
,
const
PhaseIdealLoop
*
verify_me
);
void
build_loop_late_post
(
Node
*
n
);
// Array of immediate dominance info for each CFG node indexed by node idx
// Array of immediate dominance info for each CFG node indexed by node idx
private:
private:
...
@@ -662,6 +672,19 @@ private:
...
@@ -662,6 +672,19 @@ private:
// Is safept not required by an outer loop?
// Is safept not required by an outer loop?
bool
is_deleteable_safept
(
Node
*
sfpt
);
bool
is_deleteable_safept
(
Node
*
sfpt
);
// Perform verification that the graph is valid.
PhaseIdealLoop
(
PhaseIterGVN
&
igvn
)
:
PhaseTransform
(
Ideal_Loop
),
_igvn
(
igvn
),
_dom_lca_tags
(
C
->
comp_arena
()),
_verify_me
(
NULL
),
_verify_only
(
true
)
{
build_and_optimize
(
false
);
}
// build the loop tree and perform any requested optimizations
void
build_and_optimize
(
bool
do_split_if
);
public:
public:
// Dominators for the sea of nodes
// Dominators for the sea of nodes
void
Dominators
();
void
Dominators
();
...
@@ -671,7 +694,32 @@ public:
...
@@ -671,7 +694,32 @@ public:
Node
*
dom_lca_internal
(
Node
*
n1
,
Node
*
n2
)
const
;
Node
*
dom_lca_internal
(
Node
*
n1
,
Node
*
n2
)
const
;
// Compute the Ideal Node to Loop mapping
// Compute the Ideal Node to Loop mapping
PhaseIdealLoop
(
PhaseIterGVN
&
igvn
,
const
PhaseIdealLoop
*
verify_me
,
bool
do_split_ifs
);
PhaseIdealLoop
(
PhaseIterGVN
&
igvn
,
bool
do_split_ifs
)
:
PhaseTransform
(
Ideal_Loop
),
_igvn
(
igvn
),
_dom_lca_tags
(
C
->
comp_arena
()),
_verify_me
(
NULL
),
_verify_only
(
false
)
{
build_and_optimize
(
do_split_ifs
);
}
// Verify that verify_me made the same decisions as a fresh run.
PhaseIdealLoop
(
PhaseIterGVN
&
igvn
,
const
PhaseIdealLoop
*
verify_me
)
:
PhaseTransform
(
Ideal_Loop
),
_igvn
(
igvn
),
_dom_lca_tags
(
C
->
comp_arena
()),
_verify_me
(
verify_me
),
_verify_only
(
false
)
{
build_and_optimize
(
false
);
}
// Build and verify the loop tree without modifying the graph. This
// is useful to verify that all inputs properly dominate their uses.
static
void
verify
(
PhaseIterGVN
&
igvn
)
{
#ifdef ASSERT
PhaseIdealLoop
v
(
igvn
);
#endif
}
// True if the method has at least 1 irreducible loop
// True if the method has at least 1 irreducible loop
bool
_has_irreducible_loops
;
bool
_has_irreducible_loops
;
...
...
src/share/vm/opto/phase.cpp
浏览文件 @
654e029b
/*
/*
* Copyright 1997-200
8
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-200
9
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -53,6 +53,7 @@ elapsedTimer Phase::_t_codeGeneration;
...
@@ -53,6 +53,7 @@ elapsedTimer Phase::_t_codeGeneration;
elapsedTimer
Phase
::
_t_registerMethod
;
elapsedTimer
Phase
::
_t_registerMethod
;
elapsedTimer
Phase
::
_t_temporaryTimer1
;
elapsedTimer
Phase
::
_t_temporaryTimer1
;
elapsedTimer
Phase
::
_t_temporaryTimer2
;
elapsedTimer
Phase
::
_t_temporaryTimer2
;
elapsedTimer
Phase
::
_t_idealLoopVerify
;
// Subtimers for _t_optimizer
// Subtimers for _t_optimizer
elapsedTimer
Phase
::
_t_iterGVN
;
elapsedTimer
Phase
::
_t_iterGVN
;
...
@@ -88,51 +89,52 @@ void Phase::print_timers() {
...
@@ -88,51 +89,52 @@ void Phase::print_timers() {
tty
->
print_cr
(
"Accumulated compiler times:"
);
tty
->
print_cr
(
"Accumulated compiler times:"
);
tty
->
print_cr
(
"---------------------------"
);
tty
->
print_cr
(
"---------------------------"
);
tty
->
print_cr
(
" Total compilation: %3.3f sec."
,
Phase
::
_t_totalCompilation
.
seconds
());
tty
->
print_cr
(
" Total compilation: %3.3f sec."
,
Phase
::
_t_totalCompilation
.
seconds
());
tty
->
print
(
" method compilation : %3.3f sec"
,
Phase
::
_t_methodCompilation
.
seconds
());
tty
->
print
(
" method compilation
: %3.3f sec"
,
Phase
::
_t_methodCompilation
.
seconds
());
tty
->
print
(
"/%d bytes"
,
_total_bytes_compiled
);
tty
->
print
(
"/%d bytes"
,
_total_bytes_compiled
);
tty
->
print_cr
(
" (%3.0f bytes per sec) "
,
Phase
::
_total_bytes_compiled
/
Phase
::
_t_methodCompilation
.
seconds
());
tty
->
print_cr
(
" (%3.0f bytes per sec) "
,
Phase
::
_total_bytes_compiled
/
Phase
::
_t_methodCompilation
.
seconds
());
tty
->
print_cr
(
" stub compilation : %3.3f sec."
,
Phase
::
_t_stubCompilation
.
seconds
());
tty
->
print_cr
(
" stub compilation
: %3.3f sec."
,
Phase
::
_t_stubCompilation
.
seconds
());
tty
->
print_cr
(
" Phases:"
);
tty
->
print_cr
(
" Phases:"
);
tty
->
print_cr
(
" parse : %3.3f sec"
,
Phase
::
_t_parser
.
seconds
());
tty
->
print_cr
(
" parse
: %3.3f sec"
,
Phase
::
_t_parser
.
seconds
());
if
(
DoEscapeAnalysis
)
{
if
(
DoEscapeAnalysis
)
{
tty
->
print_cr
(
" escape analysis : %3.3f sec"
,
Phase
::
_t_escapeAnalysis
.
seconds
());
tty
->
print_cr
(
" escape analysis
: %3.3f sec"
,
Phase
::
_t_escapeAnalysis
.
seconds
());
}
}
tty
->
print_cr
(
" optimizer : %3.3f sec"
,
Phase
::
_t_optimizer
.
seconds
());
tty
->
print_cr
(
" optimizer
: %3.3f sec"
,
Phase
::
_t_optimizer
.
seconds
());
if
(
Verbose
||
WizardMode
)
{
if
(
Verbose
||
WizardMode
)
{
tty
->
print_cr
(
" iterGVN : %3.3f sec"
,
Phase
::
_t_iterGVN
.
seconds
());
tty
->
print_cr
(
" iterGVN : %3.3f sec"
,
Phase
::
_t_iterGVN
.
seconds
());
tty
->
print_cr
(
" idealLoop : %3.3f sec"
,
Phase
::
_t_idealLoop
.
seconds
());
tty
->
print_cr
(
" idealLoop : %3.3f sec"
,
Phase
::
_t_idealLoop
.
seconds
());
tty
->
print_cr
(
" ccp : %3.3f sec"
,
Phase
::
_t_ccp
.
seconds
());
tty
->
print_cr
(
" idealLoopVerify: %3.3f sec"
,
Phase
::
_t_idealLoopVerify
.
seconds
());
tty
->
print_cr
(
" iterGVN2 : %3.3f sec"
,
Phase
::
_t_iterGVN2
.
seconds
());
tty
->
print_cr
(
" ccp : %3.3f sec"
,
Phase
::
_t_ccp
.
seconds
());
tty
->
print_cr
(
" graphReshape : %3.3f sec"
,
Phase
::
_t_graphReshaping
.
seconds
());
tty
->
print_cr
(
" iterGVN2 : %3.3f sec"
,
Phase
::
_t_iterGVN2
.
seconds
());
tty
->
print_cr
(
" graphReshape : %3.3f sec"
,
Phase
::
_t_graphReshaping
.
seconds
());
double
optimizer_subtotal
=
Phase
::
_t_iterGVN
.
seconds
()
+
double
optimizer_subtotal
=
Phase
::
_t_iterGVN
.
seconds
()
+
Phase
::
_t_idealLoop
.
seconds
()
+
Phase
::
_t_ccp
.
seconds
()
+
Phase
::
_t_idealLoop
.
seconds
()
+
Phase
::
_t_ccp
.
seconds
()
+
Phase
::
_t_graphReshaping
.
seconds
();
Phase
::
_t_graphReshaping
.
seconds
();
double
percent_of_optimizer
=
((
optimizer_subtotal
==
0.0
)
?
0.0
:
(
optimizer_subtotal
/
Phase
::
_t_optimizer
.
seconds
()
*
100.0
));
double
percent_of_optimizer
=
((
optimizer_subtotal
==
0.0
)
?
0.0
:
(
optimizer_subtotal
/
Phase
::
_t_optimizer
.
seconds
()
*
100.0
));
tty
->
print_cr
(
" subtotal : %3.3f sec, %3.2f %%"
,
optimizer_subtotal
,
percent_of_optimizer
);
tty
->
print_cr
(
" subtotal
: %3.3f sec, %3.2f %%"
,
optimizer_subtotal
,
percent_of_optimizer
);
}
}
tty
->
print_cr
(
" matcher : %3.3f sec"
,
Phase
::
_t_matcher
.
seconds
());
tty
->
print_cr
(
" matcher
: %3.3f sec"
,
Phase
::
_t_matcher
.
seconds
());
tty
->
print_cr
(
" scheduler : %3.3f sec"
,
Phase
::
_t_scheduler
.
seconds
());
tty
->
print_cr
(
" scheduler
: %3.3f sec"
,
Phase
::
_t_scheduler
.
seconds
());
tty
->
print_cr
(
" regalloc : %3.3f sec"
,
Phase
::
_t_registerAllocation
.
seconds
());
tty
->
print_cr
(
" regalloc
: %3.3f sec"
,
Phase
::
_t_registerAllocation
.
seconds
());
if
(
Verbose
||
WizardMode
)
{
if
(
Verbose
||
WizardMode
)
{
tty
->
print_cr
(
" ctorChaitin : %3.3f sec"
,
Phase
::
_t_ctorChaitin
.
seconds
());
tty
->
print_cr
(
" ctorChaitin
: %3.3f sec"
,
Phase
::
_t_ctorChaitin
.
seconds
());
tty
->
print_cr
(
" buildIFG : %3.3f sec"
,
Phase
::
_t_buildIFGphysical
.
seconds
());
tty
->
print_cr
(
" buildIFG
: %3.3f sec"
,
Phase
::
_t_buildIFGphysical
.
seconds
());
tty
->
print_cr
(
" computeLive : %3.3f sec"
,
Phase
::
_t_computeLive
.
seconds
());
tty
->
print_cr
(
" computeLive
: %3.3f sec"
,
Phase
::
_t_computeLive
.
seconds
());
tty
->
print_cr
(
" regAllocSplit: %3.3f sec"
,
Phase
::
_t_regAllocSplit
.
seconds
());
tty
->
print_cr
(
" regAllocSplit
: %3.3f sec"
,
Phase
::
_t_regAllocSplit
.
seconds
());
tty
->
print_cr
(
" postAllocCopyRemoval: %3.3f sec"
,
Phase
::
_t_postAllocCopyRemoval
.
seconds
());
tty
->
print_cr
(
" postAllocCopyRemoval: %3.3f sec"
,
Phase
::
_t_postAllocCopyRemoval
.
seconds
());
tty
->
print_cr
(
" fixupSpills : %3.3f sec"
,
Phase
::
_t_fixupSpills
.
seconds
());
tty
->
print_cr
(
" fixupSpills
: %3.3f sec"
,
Phase
::
_t_fixupSpills
.
seconds
());
double
regalloc_subtotal
=
Phase
::
_t_ctorChaitin
.
seconds
()
+
double
regalloc_subtotal
=
Phase
::
_t_ctorChaitin
.
seconds
()
+
Phase
::
_t_buildIFGphysical
.
seconds
()
+
Phase
::
_t_computeLive
.
seconds
()
+
Phase
::
_t_buildIFGphysical
.
seconds
()
+
Phase
::
_t_computeLive
.
seconds
()
+
Phase
::
_t_regAllocSplit
.
seconds
()
+
Phase
::
_t_fixupSpills
.
seconds
()
+
Phase
::
_t_regAllocSplit
.
seconds
()
+
Phase
::
_t_fixupSpills
.
seconds
()
+
Phase
::
_t_postAllocCopyRemoval
.
seconds
();
Phase
::
_t_postAllocCopyRemoval
.
seconds
();
double
percent_of_regalloc
=
((
regalloc_subtotal
==
0.0
)
?
0.0
:
(
regalloc_subtotal
/
Phase
::
_t_registerAllocation
.
seconds
()
*
100.0
));
double
percent_of_regalloc
=
((
regalloc_subtotal
==
0.0
)
?
0.0
:
(
regalloc_subtotal
/
Phase
::
_t_registerAllocation
.
seconds
()
*
100.0
));
tty
->
print_cr
(
" subtotal : %3.3f sec, %3.2f %%"
,
regalloc_subtotal
,
percent_of_regalloc
);
tty
->
print_cr
(
" subtotal
: %3.3f sec, %3.2f %%"
,
regalloc_subtotal
,
percent_of_regalloc
);
}
}
tty
->
print_cr
(
" macroExpand : %3.3f sec"
,
Phase
::
_t_macroExpand
.
seconds
());
tty
->
print_cr
(
" macroExpand
: %3.3f sec"
,
Phase
::
_t_macroExpand
.
seconds
());
tty
->
print_cr
(
" blockOrdering: %3.3f sec"
,
Phase
::
_t_blockOrdering
.
seconds
());
tty
->
print_cr
(
" blockOrdering
: %3.3f sec"
,
Phase
::
_t_blockOrdering
.
seconds
());
tty
->
print_cr
(
" peephole : %3.3f sec"
,
Phase
::
_t_peephole
.
seconds
());
tty
->
print_cr
(
" peephole
: %3.3f sec"
,
Phase
::
_t_peephole
.
seconds
());
tty
->
print_cr
(
" codeGen : %3.3f sec"
,
Phase
::
_t_codeGeneration
.
seconds
());
tty
->
print_cr
(
" codeGen
: %3.3f sec"
,
Phase
::
_t_codeGeneration
.
seconds
());
tty
->
print_cr
(
" install_code : %3.3f sec"
,
Phase
::
_t_registerMethod
.
seconds
());
tty
->
print_cr
(
" install_code
: %3.3f sec"
,
Phase
::
_t_registerMethod
.
seconds
());
tty
->
print_cr
(
" ------------ : ----------"
);
tty
->
print_cr
(
" ------------
--
: ----------"
);
double
phase_subtotal
=
Phase
::
_t_parser
.
seconds
()
+
double
phase_subtotal
=
Phase
::
_t_parser
.
seconds
()
+
(
DoEscapeAnalysis
?
Phase
::
_t_escapeAnalysis
.
seconds
()
:
0.0
)
+
(
DoEscapeAnalysis
?
Phase
::
_t_escapeAnalysis
.
seconds
()
:
0.0
)
+
Phase
::
_t_optimizer
.
seconds
()
+
Phase
::
_t_graphReshaping
.
seconds
()
+
Phase
::
_t_optimizer
.
seconds
()
+
Phase
::
_t_graphReshaping
.
seconds
()
+
...
@@ -143,7 +145,7 @@ void Phase::print_timers() {
...
@@ -143,7 +145,7 @@ void Phase::print_timers() {
double
percent_of_method_compile
=
((
phase_subtotal
==
0.0
)
?
0.0
:
phase_subtotal
/
Phase
::
_t_methodCompilation
.
seconds
())
*
100.0
;
double
percent_of_method_compile
=
((
phase_subtotal
==
0.0
)
?
0.0
:
phase_subtotal
/
Phase
::
_t_methodCompilation
.
seconds
())
*
100.0
;
// counters inside Compile::CodeGen include time for adapters and stubs
// counters inside Compile::CodeGen include time for adapters and stubs
// so phase-total can be greater than 100%
// so phase-total can be greater than 100%
tty
->
print_cr
(
" total : %3.3f sec, %3.2f %%"
,
phase_subtotal
,
percent_of_method_compile
);
tty
->
print_cr
(
" total
: %3.3f sec, %3.2f %%"
,
phase_subtotal
,
percent_of_method_compile
);
assert
(
percent_of_method_compile
>
expected_method_compile_coverage
||
assert
(
percent_of_method_compile
>
expected_method_compile_coverage
||
phase_subtotal
<
minimum_meaningful_method_compile
,
phase_subtotal
<
minimum_meaningful_method_compile
,
...
@@ -157,8 +159,8 @@ void Phase::print_timers() {
...
@@ -157,8 +159,8 @@ void Phase::print_timers() {
tty
->
cr
();
tty
->
cr
();
tty
->
print_cr
(
" temporaryTimer2: %3.3f sec"
,
Phase
::
_t_temporaryTimer2
.
seconds
());
tty
->
print_cr
(
" temporaryTimer2: %3.3f sec"
,
Phase
::
_t_temporaryTimer2
.
seconds
());
}
}
tty
->
print_cr
(
" output : %3.3f sec"
,
Phase
::
_t_output
.
seconds
());
tty
->
print_cr
(
" output
: %3.3f sec"
,
Phase
::
_t_output
.
seconds
());
tty
->
print_cr
(
" isched : %3.3f sec"
,
Phase
::
_t_instrSched
.
seconds
());
tty
->
print_cr
(
" isched
: %3.3f sec"
,
Phase
::
_t_instrSched
.
seconds
());
tty
->
print_cr
(
" bldOopMaps: %3.3f sec"
,
Phase
::
_t_buildOopMaps
.
seconds
());
tty
->
print_cr
(
" bldOopMaps
: %3.3f sec"
,
Phase
::
_t_buildOopMaps
.
seconds
());
}
}
#endif
#endif
src/share/vm/opto/phase.hpp
浏览文件 @
654e029b
/*
/*
* Copyright 1997-200
8
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-200
9
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -83,6 +83,7 @@ protected:
...
@@ -83,6 +83,7 @@ protected:
static
elapsedTimer
_t_registerMethod
;
static
elapsedTimer
_t_registerMethod
;
static
elapsedTimer
_t_temporaryTimer1
;
static
elapsedTimer
_t_temporaryTimer1
;
static
elapsedTimer
_t_temporaryTimer2
;
static
elapsedTimer
_t_temporaryTimer2
;
static
elapsedTimer
_t_idealLoopVerify
;
// Subtimers for _t_optimizer
// Subtimers for _t_optimizer
static
elapsedTimer
_t_iterGVN
;
static
elapsedTimer
_t_iterGVN
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录