Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
42d57399
Commit
42d57399
authored
Jan 01, 2013
by
Jan Hubicka
Committed by
Jan Hubicka
Jan 01, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* ipa-inline-analysis.c: Fix formatting.
From-SVN: r194769
parent
2a5195d9
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
220 additions
and
221 deletions
+220
-221
gcc/ChangeLog
+4
-0
gcc/ipa-inline-analysis.c
+216
-221
No files found.
gcc/ChangeLog
View file @
42d57399
2013
-
01
-
01
Jan
Hubicka
<
jh
@suse
.
cz
>
*
ipa
-
inline
-
analysis
.
c
:
Fix
formatting
.
2013
-
01
-
01
Jakub
Jelinek
<
jakub
@redhat
.
com
>
PR
tree
-
optimization
/
55831
gcc/ipa-inline-analysis.c
View file @
42d57399
/* Inlining decision heuristics.
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
, 2012, 2013
Free Software Foundation, Inc.
Contributed by Jan Hubicka
...
...
@@ -127,8 +127,7 @@ static void inline_node_duplication_hook (struct cgraph_node *,
struct
cgraph_node
*
,
void
*
);
static
void
inline_edge_removal_hook
(
struct
cgraph_edge
*
,
void
*
);
static
void
inline_edge_duplication_hook
(
struct
cgraph_edge
*
,
struct
cgraph_edge
*
,
void
*
);
struct
cgraph_edge
*
,
void
*
);
/* VECtor holding inline summaries.
In GGC memory because conditions might point to constant trees. */
...
...
@@ -200,6 +199,7 @@ false_predicate_p (struct predicate *p)
/* Return predicate that is set true when function is not inlined. */
static
inline
struct
predicate
not_inlined_predicate
(
void
)
{
...
...
@@ -336,14 +336,15 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause)
cc1
=
&
(
*
conditions
)[
c1
-
predicate_first_dynamic_condition
];
/* We have no way to represent !CHANGED and !IS_NOT_CONSTANT
and thus there is no point for looking for them. */
if
(
cc1
->
code
==
CHANGED
||
cc1
->
code
==
IS_NOT_CONSTANT
)
if
(
cc1
->
code
==
CHANGED
||
cc1
->
code
==
IS_NOT_CONSTANT
)
continue
;
for
(
c2
=
c1
+
1
;
c2
<=
NUM_CONDITIONS
;
c2
++
)
if
(
clause
&
(
1
<<
c2
))
{
condition
*
cc1
=
&
(
*
conditions
)[
c1
-
predicate_first_dynamic_condition
];
condition
*
cc2
=
&
(
*
conditions
)[
c2
-
predicate_first_dynamic_condition
];
condition
*
cc1
=
&
(
*
conditions
)[
c1
-
predicate_first_dynamic_condition
];
condition
*
cc2
=
&
(
*
conditions
)[
c2
-
predicate_first_dynamic_condition
];
if
(
cc1
->
operand_num
==
cc2
->
operand_num
&&
cc1
->
val
==
cc2
->
val
&&
cc2
->
code
!=
IS_NOT_CONSTANT
...
...
@@ -362,7 +363,7 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause)
/* Keep clauses in decreasing order. This makes equivalence testing easy. */
p
->
clause
[
i2
+
1
]
=
0
;
if
(
insert_here
>=
0
)
for
(;
i2
>
insert_here
;
i2
--
)
for
(;
i2
>
insert_here
;
i2
--
)
p
->
clause
[
i2
]
=
p
->
clause
[
i2
-
1
];
else
insert_here
=
i2
;
...
...
@@ -410,9 +411,9 @@ predicates_equal_p (struct predicate *p, struct predicate *p2)
for
(
i
=
0
;
p
->
clause
[
i
];
i
++
)
{
gcc_checking_assert
(
i
<
MAX_CLAUSES
);
gcc_checking_assert
(
p
->
clause
[
i
]
>
p
->
clause
[
i
+
1
]);
gcc_checking_assert
(
p
->
clause
[
i
]
>
p
->
clause
[
i
+
1
]);
gcc_checking_assert
(
!
p2
->
clause
[
i
]
||
p2
->
clause
[
i
]
>
p2
->
clause
[
i
+
1
]);
||
p2
->
clause
[
i
]
>
p2
->
clause
[
i
+
1
]);
if
(
p
->
clause
[
i
]
!=
p2
->
clause
[
i
])
return
false
;
}
...
...
@@ -423,10 +424,11 @@ predicates_equal_p (struct predicate *p, struct predicate *p2)
/* Return P | P2. */
static
struct
predicate
or_predicates
(
conditions
conditions
,
struct
predicate
*
p
,
struct
predicate
*
p2
)
or_predicates
(
conditions
conditions
,
struct
predicate
*
p
,
struct
predicate
*
p2
)
{
struct
predicate
out
=
true_predicate
();
int
i
,
j
;
int
i
,
j
;
/* Avoid busy work. */
if
(
false_predicate_p
(
p2
)
||
true_predicate_p
(
p
))
...
...
@@ -508,12 +510,14 @@ predicate_probability (conditions conds,
{
if
(
i2
>=
predicate_first_dynamic_condition
)
{
condition
*
c
=
&
(
*
conds
)[
i2
-
predicate_first_dynamic_condition
];
condition
*
c
=
&
(
*
conds
)[
i2
-
predicate_first_dynamic_condition
];
if
(
c
->
code
==
CHANGED
&&
(
c
->
operand_num
<
(
int
)
inline_param_summary
.
length
()))
&&
(
c
->
operand_num
<
(
int
)
inline_param_summary
.
length
()))
{
int
iprob
=
inline_param_summary
[
c
->
operand_num
].
change_prob
;
int
iprob
=
inline_param_summary
[
c
->
operand_num
].
change_prob
;
this_prob
=
MAX
(
this_prob
,
iprob
);
}
else
...
...
@@ -692,14 +696,16 @@ account_size_time (struct inline_summary *summary, int size, int time,
e
=
&
(
*
summary
->
entry
)[
0
];
gcc_assert
(
!
e
->
predicate
.
clause
[
0
]);
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
fprintf
(
dump_file
,
"
\t\t
Reached limit on number of entries, ignoring the predicate."
);
fprintf
(
dump_file
,
"
\t\t
Reached limit on number of entries, "
"ignoring the predicate."
);
}
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
)
&&
(
time
||
size
))
{
fprintf
(
dump_file
,
"
\t\t
Accounting size:%3.2f, time:%3.2f on %spredicate:"
,
((
double
)
size
)
/
INLINE_SIZE_SCALE
,
((
double
)
time
)
/
INLINE_TIM
E_SCALE
,
found
?
""
:
"new "
);
fprintf
(
dump_file
,
"
\t\t
Accounting size:%3.2f, time:%3.2f on %spredicate:"
,
((
double
)
size
)
/
INLINE_SIZ
E_SCALE
,
((
double
)
time
)
/
INLINE_TIME_SCALE
,
found
?
""
:
"new "
);
dump_predicate
(
dump_file
,
summary
->
conds
,
pred
);
}
if
(
!
found
)
...
...
@@ -728,7 +734,7 @@ edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
if
(
predicate
&&
!
true_predicate_p
(
predicate
))
{
if
(
!
es
->
predicate
)
es
->
predicate
=
(
struct
predicate
*
)
pool_alloc
(
edge_predicate_pool
);
es
->
predicate
=
(
struct
predicate
*
)
pool_alloc
(
edge_predicate_pool
);
*
es
->
predicate
=
*
predicate
;
}
else
...
...
@@ -744,8 +750,7 @@ edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
static
void
set_hint_predicate
(
struct
predicate
**
p
,
struct
predicate
new_predicate
)
{
if
(
false_predicate_p
(
&
new_predicate
)
||
true_predicate_p
(
&
new_predicate
))
if
(
false_predicate_p
(
&
new_predicate
)
||
true_predicate_p
(
&
new_predicate
))
{
if
(
*
p
)
pool_free
(
edge_predicate_pool
,
*
p
);
...
...
@@ -754,7 +759,7 @@ set_hint_predicate (struct predicate **p, struct predicate new_predicate)
else
{
if
(
!*
p
)
*
p
=
(
struct
predicate
*
)
pool_alloc
(
edge_predicate_pool
);
*
p
=
(
struct
predicate
*
)
pool_alloc
(
edge_predicate_pool
);
**
p
=
new_predicate
;
}
}
...
...
@@ -771,7 +776,8 @@ static clause_t
evaluate_conditions_for_known_args
(
struct
cgraph_node
*
node
,
bool
inline_p
,
vec
<
tree
>
known_vals
,
vec
<
ipa_agg_jump_function_p
>
known_aggs
)
vec
<
ipa_agg_jump_function_p
>
known_aggs
)
{
clause_t
clause
=
inline_p
?
0
:
1
<<
predicate_not_inlined_condition
;
struct
inline_summary
*
info
=
inline_summary
(
node
);
...
...
@@ -801,8 +807,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
if
(
c
->
code
==
CHANGED
&&
!
c
->
by_ref
&&
(
known_vals
[
c
->
operand_num
]
==
error_mark_node
))
&&
(
known_vals
[
c
->
operand_num
]
==
error_mark_node
))
continue
;
if
(
known_aggs
.
exists
())
...
...
@@ -828,8 +833,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
if
(
c
->
code
==
IS_NOT_CONSTANT
||
c
->
code
==
CHANGED
)
continue
;
res
=
fold_binary_to_constant
(
c
->
code
,
boolean_type_node
,
val
,
c
->
val
);
if
(
res
&&
integer_zerop
(
res
))
if
(
res
&&
integer_zerop
(
res
))
continue
;
clause
|=
1
<<
(
i
+
predicate_first_dynamic_condition
);
}
...
...
@@ -846,7 +850,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
vec
<
tree
>
*
known_binfos_ptr
,
vec
<
ipa_agg_jump_function_p
>
*
known_aggs_ptr
)
{
struct
cgraph_node
*
callee
=
cgraph_function_or_thunk_node
(
e
->
callee
,
NULL
);
struct
cgraph_node
*
callee
=
cgraph_function_or_thunk_node
(
e
->
callee
,
NULL
);
struct
inline_summary
*
info
=
inline_summary
(
callee
);
vec
<
tree
>
known_vals
=
vNULL
;
vec
<
ipa_agg_jump_function_p
>
known_aggs
=
vNULL
;
...
...
@@ -860,8 +865,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
if
(
ipa_node_params_vector
.
exists
()
&&
!
e
->
call_stmt_cannot_inline_p
&&
((
clause_ptr
&&
info
->
conds
)
||
known_vals_ptr
||
known_binfos_ptr
))
&&
((
clause_ptr
&&
info
->
conds
)
||
known_vals_ptr
||
known_binfos_ptr
))
{
struct
ipa_node_params
*
parms_info
;
struct
ipa_edge_args
*
args
=
IPA_EDGE_REF
(
e
);
...
...
@@ -888,7 +892,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
{
if
(
known_vals
.
exists
()
&&
TREE_CODE
(
cst
)
!=
TREE_BINFO
)
known_vals
[
i
]
=
cst
;
else
if
(
known_binfos_ptr
!=
NULL
&&
TREE_CODE
(
cst
)
==
TREE_BINFO
)
else
if
(
known_binfos_ptr
!=
NULL
&&
TREE_CODE
(
cst
)
==
TREE_BINFO
)
(
*
known_binfos_ptr
)[
i
]
=
cst
;
}
else
if
(
inline_p
&&
!
es
->
param
[
i
].
change_prob
)
...
...
@@ -940,8 +945,7 @@ inline_summary_alloc (void)
inline_edge_summary_vec
.
safe_grow_cleared
(
cgraph_edge_max_uid
+
1
);
if
(
!
edge_predicate_pool
)
edge_predicate_pool
=
create_alloc_pool
(
"edge predicates"
,
sizeof
(
struct
predicate
),
10
);
sizeof
(
struct
predicate
),
10
);
}
/* We are called multiple time for given function; clear
...
...
@@ -950,7 +954,7 @@ inline_summary_alloc (void)
static
void
reset_inline_edge_summary
(
struct
cgraph_edge
*
e
)
{
if
(
e
->
uid
<
(
int
)
inline_edge_summary_vec
.
length
())
if
(
e
->
uid
<
(
int
)
inline_edge_summary_vec
.
length
())
{
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
e
);
...
...
@@ -1005,10 +1009,11 @@ reset_inline_summary (struct cgraph_node *node)
/* Hook that is called by cgraph.c when a node is removed. */
static
void
inline_node_removal_hook
(
struct
cgraph_node
*
node
,
void
*
data
ATTRIBUTE_UNUSED
)
inline_node_removal_hook
(
struct
cgraph_node
*
node
,
void
*
data
ATTRIBUTE_UNUSED
)
{
struct
inline_summary
*
info
;
if
(
vec_safe_length
(
inline_summary_vec
)
<=
(
unsigned
)
node
->
uid
)
if
(
vec_safe_length
(
inline_summary_vec
)
<=
(
unsigned
)
node
->
uid
)
return
;
info
=
inline_summary
(
node
);
reset_inline_summary
(
node
);
...
...
@@ -1054,8 +1059,7 @@ remap_hint_predicate_after_duplication (struct predicate **p,
return
;
new_predicate
=
remap_predicate_after_duplication
(
*
p
,
possible_truths
,
info
);
possible_truths
,
info
);
/* We do not want to free previous predicate; it is used by node origin. */
*
p
=
NULL
;
set_hint_predicate
(
p
,
new_predicate
);
...
...
@@ -1065,29 +1069,28 @@ remap_hint_predicate_after_duplication (struct predicate **p,
/* Hook that is called by cgraph.c when a node is duplicated. */
static
void
inline_node_duplication_hook
(
struct
cgraph_node
*
src
,
struct
cgraph_node
*
dst
,
inline_node_duplication_hook
(
struct
cgraph_node
*
src
,
struct
cgraph_node
*
dst
,
ATTRIBUTE_UNUSED
void
*
data
)
{
struct
inline_summary
*
info
;
inline_summary_alloc
();
info
=
inline_summary
(
dst
);
memcpy
(
info
,
inline_summary
(
src
),
sizeof
(
struct
inline_summary
));
memcpy
(
info
,
inline_summary
(
src
),
sizeof
(
struct
inline_summary
));
/* TODO: as an optimization, we may avoid copying conditions
that are known to be false or true. */
info
->
conds
=
vec_safe_copy
(
info
->
conds
);
/* When there are any replacements in the function body, see if we can figure
out that something was optimized out. */
if
(
ipa_node_params_vector
.
exists
()
&&
dst
->
clone
.
tree_map
)
if
(
ipa_node_params_vector
.
exists
()
&&
dst
->
clone
.
tree_map
)
{
vec
<
size_time_entry
,
va_gc
>
*
entry
=
info
->
entry
;
/* Use SRC parm info since it may not be copied yet. */
struct
ipa_node_params
*
parms_info
=
IPA_NODE_REF
(
src
);
vec
<
tree
>
known_vals
=
vNULL
;
int
count
=
ipa_get_param_count
(
parms_info
);
int
i
,
j
;
int
i
,
j
;
clause_t
possible_truths
;
struct
predicate
true_pred
=
true_predicate
();
size_time_entry
*
e
;
...
...
@@ -1104,9 +1107,7 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
for
(
j
=
0
;
vec_safe_iterate
(
dst
->
clone
.
tree_map
,
j
,
&
r
);
j
++
)
{
if
(
r
->
old_tree
==
t
&&
r
->
replace_p
&&
!
r
->
ref_p
)
if
(
r
->
old_tree
==
t
&&
r
->
replace_p
&&
!
r
->
ref_p
)
{
known_vals
[
i
]
=
r
->
new_tree
;
break
;
...
...
@@ -1114,7 +1115,8 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
}
}
possible_truths
=
evaluate_conditions_for_known_args
(
dst
,
false
,
known_vals
,
vNULL
);
known_vals
,
vNULL
);
known_vals
.
release
();
account_size_time
(
info
,
0
,
0
,
&
true_pred
);
...
...
@@ -1181,21 +1183,17 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
edge_set_predicate
(
edge
,
&
new_predicate
);
}
remap_hint_predicate_after_duplication
(
&
info
->
loop_iterations
,
possible_truths
,
info
);
possible_truths
,
info
);
remap_hint_predicate_after_duplication
(
&
info
->
loop_stride
,
possible_truths
,
info
);
possible_truths
,
info
);
remap_hint_predicate_after_duplication
(
&
info
->
array_index
,
possible_truths
,
info
);
possible_truths
,
info
);
/* If inliner or someone after inliner will ever start producing
non-trivial clones, we will get trouble with lack of information
about updating self sizes, because size vectors already contains
sizes of the calees. */
gcc_assert
(
!
inlined_to_p
||
!
optimized_out_size
);
gcc_assert
(
!
inlined_to_p
||
!
optimized_out_size
);
}
else
{
...
...
@@ -1226,7 +1224,8 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
/* Hook that is called by cgraph.c when a node is duplicated. */
static
void
inline_edge_duplication_hook
(
struct
cgraph_edge
*
src
,
struct
cgraph_edge
*
dst
,
inline_edge_duplication_hook
(
struct
cgraph_edge
*
src
,
struct
cgraph_edge
*
dst
,
ATTRIBUTE_UNUSED
void
*
data
)
{
struct
inline_edge_summary
*
info
;
...
...
@@ -1234,8 +1233,7 @@ inline_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
inline_summary_alloc
();
info
=
inline_edge_summary
(
dst
);
srcinfo
=
inline_edge_summary
(
src
);
memcpy
(
info
,
srcinfo
,
sizeof
(
struct
inline_edge_summary
));
memcpy
(
info
,
srcinfo
,
sizeof
(
struct
inline_edge_summary
));
info
->
predicate
=
NULL
;
edge_set_predicate
(
dst
,
srcinfo
->
predicate
);
info
->
param
=
srcinfo
->
param
.
copy
();
...
...
@@ -1245,7 +1243,8 @@ inline_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
/* Keep edge cache consistent across edge removal. */
static
void
inline_edge_removal_hook
(
struct
cgraph_edge
*
edge
,
void
*
data
ATTRIBUTE_UNUSED
)
inline_edge_removal_hook
(
struct
cgraph_edge
*
edge
,
void
*
data
ATTRIBUTE_UNUSED
)
{
if
(
edge_growth_cache
.
exists
())
reset_edge_growth_cache
(
edge
);
...
...
@@ -1279,28 +1278,27 @@ free_growth_caches (void)
Indent by INDENT. */
static
void
dump_inline_edge_summary
(
FILE
*
f
,
int
indent
,
struct
cgraph_node
*
node
,
dump_inline_edge_summary
(
FILE
*
f
,
int
indent
,
struct
cgraph_node
*
node
,
struct
inline_summary
*
info
)
{
struct
cgraph_edge
*
edge
;
for
(
edge
=
node
->
callees
;
edge
;
edge
=
edge
->
next_callee
)
{
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
edge
);
struct
cgraph_node
*
callee
=
cgraph_function_or_thunk_node
(
edge
->
callee
,
NULL
);
struct
cgraph_node
*
callee
=
cgraph_function_or_thunk_node
(
edge
->
callee
,
NULL
);
int
i
;
fprintf
(
f
,
"%*s%s/%i %s
\n
%*s loop depth:%2i freq:%4i size:%2i time: %2i callee size:%2i stack:%2i"
,
indent
,
""
,
cgraph_node_name
(
callee
),
callee
->
uid
,
!
edge
->
inline_failed
?
"inlined"
:
cgraph_inline_failed_string
(
edge
->
inline_failed
),
indent
,
""
,
es
->
loop_depth
,
edge
->
frequency
,
es
->
call_stmt_size
,
es
->
call_stmt_time
,
(
int
)
inline_summary
(
callee
)
->
size
/
INLINE_SIZE_SCALE
,
(
int
)
inline_summary
(
callee
)
->
estimated_stack_size
);
fprintf
(
f
,
"%*s%s/%i %s
\n
%*s loop depth:%2i freq:%4i size:%2i"
" time: %2i callee size:%2i stack:%2i"
,
indent
,
""
,
cgraph_node_name
(
callee
),
callee
->
uid
,
!
edge
->
inline_failed
?
"inlined"
:
cgraph_inline_failed_string
(
edge
->
inline_failed
),
indent
,
""
,
es
->
loop_depth
,
edge
->
frequency
,
es
->
call_stmt_size
,
es
->
call_stmt_time
,
(
int
)
inline_summary
(
callee
)
->
size
/
INLINE_SIZE_SCALE
,
(
int
)
inline_summary
(
callee
)
->
estimated_stack_size
);
if
(
es
->
predicate
)
{
...
...
@@ -1310,7 +1308,7 @@ dump_inline_edge_summary (FILE * f, int indent, struct cgraph_node *node,
else
fprintf
(
f
,
"
\n
"
);
if
(
es
->
param
.
exists
())
for
(
i
=
0
;
i
<
(
int
)
es
->
param
.
length
();
i
++
)
for
(
i
=
0
;
i
<
(
int
)
es
->
param
.
length
();
i
++
)
{
int
prob
=
es
->
param
[
i
].
change_prob
;
...
...
@@ -1325,11 +1323,11 @@ dump_inline_edge_summary (FILE * f, int indent, struct cgraph_node *node,
{
fprintf
(
f
,
"%*sStack frame offset %i, callee self size %i,"
" callee size %i
\n
"
,
indent
+
2
,
""
,
(
int
)
inline_summary
(
callee
)
->
stack_frame_offset
,
(
int
)
inline_summary
(
callee
)
->
estimated_self_stack_size
,
(
int
)
inline_summary
(
callee
)
->
estimated_stack_size
);
dump_inline_edge_summary
(
f
,
indent
+
2
,
callee
,
info
);
indent
+
2
,
""
,
(
int
)
inline_summary
(
callee
)
->
stack_frame_offset
,
(
int
)
inline_summary
(
callee
)
->
estimated_self_stack_size
,
(
int
)
inline_summary
(
callee
)
->
estimated_stack_size
);
dump_inline_edge_summary
(
f
,
indent
+
2
,
callee
,
info
);
}
}
for
(
edge
=
node
->
indirect_calls
;
edge
;
edge
=
edge
->
next_callee
)
...
...
@@ -1339,9 +1337,7 @@ dump_inline_edge_summary (FILE * f, int indent, struct cgraph_node *node,
" time: %2i"
,
indent
,
""
,
es
->
loop_depth
,
edge
->
frequency
,
es
->
call_stmt_size
,
es
->
call_stmt_time
);
edge
->
frequency
,
es
->
call_stmt_size
,
es
->
call_stmt_time
);
if
(
es
->
predicate
)
{
fprintf
(
f
,
"predicate: "
);
...
...
@@ -1354,7 +1350,7 @@ dump_inline_edge_summary (FILE * f, int indent, struct cgraph_node *node,
void
dump_inline_summary
(
FILE
*
f
,
struct
cgraph_node
*
node
)
dump_inline_summary
(
FILE
*
f
,
struct
cgraph_node
*
node
)
{
if
(
node
->
analyzed
)
{
...
...
@@ -1367,22 +1363,17 @@ dump_inline_summary (FILE * f, struct cgraph_node *node)
fprintf
(
f
,
" always_inline"
);
if
(
s
->
inlinable
)
fprintf
(
f
,
" inlinable"
);
fprintf
(
f
,
"
\n
self time: %i
\n
"
,
s
->
self_time
);
fprintf
(
f
,
"
\n
self time: %i
\n
"
,
s
->
self_time
);
fprintf
(
f
,
" global time: %i
\n
"
,
s
->
time
);
fprintf
(
f
,
" self size: %i
\n
"
,
s
->
self_size
);
fprintf
(
f
,
" self size: %i
\n
"
,
s
->
self_size
);
fprintf
(
f
,
" global size: %i
\n
"
,
s
->
size
);
fprintf
(
f
,
" self stack: %i
\n
"
,
(
int
)
s
->
estimated_self_stack_size
);
fprintf
(
f
,
" global stack: %i
\n
"
,
(
int
)
s
->
estimated_stack_size
);
fprintf
(
f
,
" global stack: %i
\n
"
,
(
int
)
s
->
estimated_stack_size
);
if
(
s
->
growth
)
fprintf
(
f
,
" estimated growth:%i
\n
"
,
(
int
)
s
->
growth
);
fprintf
(
f
,
" estimated growth:%i
\n
"
,
(
int
)
s
->
growth
);
if
(
s
->
scc_no
)
fprintf
(
f
,
" In SCC: %i
\n
"
,
(
int
)
s
->
scc_no
);
fprintf
(
f
,
" In SCC: %i
\n
"
,
(
int
)
s
->
scc_no
);
for
(
i
=
0
;
vec_safe_iterate
(
s
->
entry
,
i
,
&
e
);
i
++
)
{
fprintf
(
f
,
" size:%f, time:%f, predicate:"
,
...
...
@@ -1616,7 +1607,7 @@ eliminated_by_inlining_prob (gimple stmt)
/* Reads of parameters passed by reference
expected to be free (i.e. optimized out after inlining). */
if
(
TREE_CODE
(
inner_rhs
)
==
MEM_REF
if
(
TREE_CODE
(
inner_rhs
)
==
MEM_REF
&&
unmodified_parm
(
stmt
,
TREE_OPERAND
(
inner_rhs
,
0
)))
rhs_free
=
true
;
...
...
@@ -1657,12 +1648,13 @@ eliminated_by_inlining_prob (gimple stmt)
to return value. */
if
(
TREE_CODE
(
inner_lhs
)
==
PARM_DECL
||
TREE_CODE
(
inner_lhs
)
==
RESULT_DECL
||
(
TREE_CODE
(
inner_lhs
)
==
MEM_REF
||
(
TREE_CODE
(
inner_lhs
)
==
MEM_REF
&&
(
unmodified_parm
(
stmt
,
TREE_OPERAND
(
inner_lhs
,
0
))
||
(
TREE_CODE
(
TREE_OPERAND
(
inner_lhs
,
0
))
==
SSA_NAME
&&
SSA_NAME_VAR
(
TREE_OPERAND
(
inner_lhs
,
0
))
&&
TREE_CODE
(
SSA_NAME_VAR
(
TREE_OPERAND
(
inner_lhs
,
0
)))
==
RESULT_DECL
))))
(
inner_lhs
,
0
)))
==
RESULT_DECL
))))
lhs_free
=
true
;
if
(
lhs_free
&&
(
is_gimple_reg
(
rhs
)
||
is_gimple_min_invariant
(
rhs
)))
...
...
@@ -1696,8 +1688,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
tree
op2
;
last
=
last_stmt
(
bb
);
if
(
!
last
||
gimple_code
(
last
)
!=
GIMPLE_COND
)
if
(
!
last
||
gimple_code
(
last
)
!=
GIMPLE_COND
)
return
;
if
(
!
is_gimple_ip_invariant
(
gimple_cond_rhs
(
last
)))
return
;
...
...
@@ -1719,7 +1710,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
?
code
:
inverted_code
,
gimple_cond_rhs
(
last
));
e
->
aux
=
pool_alloc
(
edge_predicate_pool
);
*
(
struct
predicate
*
)
e
->
aux
=
p
;
*
(
struct
predicate
*
)
e
->
aux
=
p
;
}
}
...
...
@@ -1743,15 +1734,15 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
||
gimple_call_num_args
(
set_stmt
)
!=
1
)
return
;
op2
=
gimple_call_arg
(
set_stmt
,
0
);
if
(
!
unmodified_parm_or_parm_agg_item
(
info
,
set_stmt
,
op2
,
&
index
,
&
aggpos
))
if
(
!
unmodified_parm_or_parm_agg_item
(
info
,
set_stmt
,
op2
,
&
index
,
&
aggpos
))
return
;
FOR_EACH_EDGE
(
e
,
ei
,
bb
->
succs
)
if
(
e
->
flags
&
EDGE_FALSE_VALUE
)
FOR_EACH_EDGE
(
e
,
ei
,
bb
->
succs
)
if
(
e
->
flags
&
EDGE_FALSE_VALUE
)
{
struct
predicate
p
=
add_condition
(
summary
,
index
,
&
aggpos
,
IS_NOT_CONSTANT
,
NULL_TREE
);
e
->
aux
=
pool_alloc
(
edge_predicate_pool
);
*
(
struct
predicate
*
)
e
->
aux
=
p
;
*
(
struct
predicate
*
)
e
->
aux
=
p
;
}
}
...
...
@@ -1774,8 +1765,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
size_t
case_idx
;
last
=
last_stmt
(
bb
);
if
(
!
last
||
gimple_code
(
last
)
!=
GIMPLE_SWITCH
)
if
(
!
last
||
gimple_code
(
last
)
!=
GIMPLE_SWITCH
)
return
;
op
=
gimple_switch_index
(
last
);
if
(
!
unmodified_parm_or_parm_agg_item
(
info
,
last
,
op
,
&
index
,
&
aggpos
))
...
...
@@ -1784,9 +1774,9 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
FOR_EACH_EDGE
(
e
,
ei
,
bb
->
succs
)
{
e
->
aux
=
pool_alloc
(
edge_predicate_pool
);
*
(
struct
predicate
*
)
e
->
aux
=
false_predicate
();
*
(
struct
predicate
*
)
e
->
aux
=
false_predicate
();
}
n
=
gimple_switch_num_labels
(
last
);
n
=
gimple_switch_num_labels
(
last
);
for
(
case_idx
=
0
;
case_idx
<
n
;
++
case_idx
)
{
tree
cl
=
gimple_switch_label
(
last
,
case_idx
);
...
...
@@ -1811,8 +1801,8 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
p2
=
add_condition
(
summary
,
index
,
&
aggpos
,
LE_EXPR
,
max
);
p
=
and_predicates
(
summary
->
conds
,
&
p1
,
&
p2
);
}
*
(
struct
predicate
*
)
e
->
aux
=
or_predicates
(
summary
->
conds
,
&
p
,
(
struct
predicate
*
)
e
->
aux
);
*
(
struct
predicate
*
)
e
->
aux
=
or_predicates
(
summary
->
conds
,
&
p
,
(
struct
predicate
*
)
e
->
aux
);
}
}
...
...
@@ -1838,7 +1828,7 @@ compute_bb_predicates (struct cgraph_node *node,
/* Entry block is always executable. */
ENTRY_BLOCK_PTR_FOR_FUNCTION
(
my_function
)
->
aux
=
pool_alloc
(
edge_predicate_pool
);
*
(
struct
predicate
*
)
ENTRY_BLOCK_PTR_FOR_FUNCTION
(
my_function
)
->
aux
*
(
struct
predicate
*
)
ENTRY_BLOCK_PTR_FOR_FUNCTION
(
my_function
)
->
aux
=
true_predicate
();
/* A simple dataflow propagation of predicates forward in the CFG.
...
...
@@ -1856,11 +1846,11 @@ compute_bb_predicates (struct cgraph_node *node,
if
(
e
->
src
->
aux
)
{
struct
predicate
this_bb_predicate
=
*
(
struct
predicate
*
)
e
->
src
->
aux
;
=
*
(
struct
predicate
*
)
e
->
src
->
aux
;
if
(
e
->
aux
)
this_bb_predicate
=
and_predicates
(
summary
->
conds
,
&
this_bb_predicate
,
(
struct
predicate
*
)
e
->
aux
);
(
struct
predicate
*
)
e
->
aux
);
p
=
or_predicates
(
summary
->
conds
,
&
p
,
&
this_bb_predicate
);
if
(
true_predicate_p
(
&
p
))
break
;
...
...
@@ -1874,12 +1864,12 @@ compute_bb_predicates (struct cgraph_node *node,
{
done
=
false
;
bb
->
aux
=
pool_alloc
(
edge_predicate_pool
);
*
((
struct
predicate
*
)
bb
->
aux
)
=
p
;
*
((
struct
predicate
*
)
bb
->
aux
)
=
p
;
}
else
if
(
!
predicates_equal_p
(
&
p
,
(
struct
predicate
*
)
bb
->
aux
))
else
if
(
!
predicates_equal_p
(
&
p
,
(
struct
predicate
*
)
bb
->
aux
))
{
done
=
false
;
*
((
struct
predicate
*
)
bb
->
aux
)
=
p
;
*
((
struct
predicate
*
)
bb
->
aux
)
=
p
;
}
}
}
...
...
@@ -1906,15 +1896,13 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
expr
=
TREE_OPERAND
(
expr
,
0
);
parm
=
unmodified_parm
(
NULL
,
expr
);
if
(
parm
&&
(
index
=
ipa_get_param_decl_index
(
info
,
parm
))
>=
0
)
if
(
parm
&&
(
index
=
ipa_get_param_decl_index
(
info
,
parm
))
>=
0
)
return
add_condition
(
summary
,
index
,
NULL
,
CHANGED
,
NULL_TREE
);
if
(
is_gimple_min_invariant
(
expr
))
return
false_predicate
();
if
(
TREE_CODE
(
expr
)
==
SSA_NAME
)
return
nonconstant_names
[
SSA_NAME_VERSION
(
expr
)];
if
(
BINARY_CLASS_P
(
expr
)
||
COMPARISON_CLASS_P
(
expr
))
if
(
BINARY_CLASS_P
(
expr
)
||
COMPARISON_CLASS_P
(
expr
))
{
struct
predicate
p1
=
will_be_nonconstant_expr_predicate
(
info
,
summary
,
TREE_OPERAND
(
expr
,
0
),
...
...
@@ -2018,7 +2006,8 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
}
if
(
is_load
)
op_non_const
=
add_condition
(
summary
,
base_index
,
&
aggpos
,
CHANGED
,
NULL
);
op_non_const
=
add_condition
(
summary
,
base_index
,
&
aggpos
,
CHANGED
,
NULL
);
else
op_non_const
=
false_predicate
();
FOR_EACH_SSA_TREE_OPERAND
(
use
,
stmt
,
iter
,
SSA_OP_USE
)
...
...
@@ -2026,8 +2015,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
tree
parm
=
unmodified_parm
(
stmt
,
use
);
int
index
;
if
(
parm
&&
(
index
=
ipa_get_param_decl_index
(
info
,
parm
))
>=
0
)
if
(
parm
&&
(
index
=
ipa_get_param_decl_index
(
info
,
parm
))
>=
0
)
{
if
(
index
!=
base_index
)
p
=
add_condition
(
summary
,
index
,
NULL
,
CHANGED
,
NULL_TREE
);
...
...
@@ -2055,15 +2043,16 @@ struct record_modified_bb_info
set except for info->stmt. */
static
bool
record_modified
(
ao_ref
*
ao
ATTRIBUTE_UNUSED
,
tree
vdef
,
void
*
data
)
record_modified
(
ao_ref
*
ao
ATTRIBUTE_UNUSED
,
tree
vdef
,
void
*
data
)
{
struct
record_modified_bb_info
*
info
=
(
struct
record_modified_bb_info
*
)
data
;
struct
record_modified_bb_info
*
info
=
(
struct
record_modified_bb_info
*
)
data
;
if
(
SSA_NAME_DEF_STMT
(
vdef
)
==
info
->
stmt
)
return
false
;
bitmap_set_bit
(
info
->
bb_set
,
SSA_NAME_IS_DEFAULT_DEF
(
vdef
)
?
ENTRY_BLOCK_PTR
->
index
:
gimple_bb
(
SSA_NAME_DEF_STMT
(
vdef
))
->
index
);
?
ENTRY_BLOCK_PTR
->
index
:
gimple_bb
(
SSA_NAME_DEF_STMT
(
vdef
))
->
index
);
return
false
;
}
...
...
@@ -2081,6 +2070,7 @@ param_change_prob (gimple stmt, int i)
basic_block
bb
=
gimple_bb
(
stmt
);
tree
base
;
/* Global invariants neve change. */
if
(
is_gimple_min_invariant
(
op
))
return
0
;
/* We would have to do non-trivial analysis to really work out what
...
...
@@ -2251,18 +2241,17 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
static
struct
predicate
array_index_predicate
(
struct
inline_summary
*
info
,
vec
<
predicate_t
>
nonconstant_names
,
tree
op
)
vec
<
predicate_t
>
nonconstant_names
,
tree
op
)
{
struct
predicate
p
=
false_predicate
();
while
(
handled_component_p
(
op
))
{
if
(
TREE_CODE
(
op
)
==
ARRAY_REF
||
TREE_CODE
(
op
)
==
ARRAY_RANGE_REF
)
if
(
TREE_CODE
(
op
)
==
ARRAY_REF
||
TREE_CODE
(
op
)
==
ARRAY_RANGE_REF
)
{
if
(
TREE_CODE
(
TREE_OPERAND
(
op
,
1
))
==
SSA_NAME
)
p
=
or_predicates
(
info
->
conds
,
&
p
,
&
nonconstant_names
[
SSA_NAME_VERSION
(
TREE_OPERAND
(
op
,
1
))]);
&
nonconstant_names
[
SSA_NAME_VERSION
(
TREE_OPERAND
(
op
,
1
))]);
}
op
=
TREE_OPERAND
(
op
,
0
);
}
...
...
@@ -2304,7 +2293,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
if
(
ipa_node_params_vector
.
exists
())
{
parms_info
=
IPA_NODE_REF
(
node
);
nonconstant_names
.
safe_grow_cleared
(
SSANAMES
(
my_function
)
->
length
());
nonconstant_names
.
safe_grow_cleared
(
SSANAMES
(
my_function
)
->
length
());
}
}
...
...
@@ -2335,7 +2325,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
if
(
parms_info
)
{
if
(
bb
->
aux
)
bb_predicate
=
*
(
struct
predicate
*
)
bb
->
aux
;
bb_predicate
=
*
(
struct
predicate
*
)
bb
->
aux
;
else
bb_predicate
=
false_predicate
();
}
...
...
@@ -2384,24 +2374,31 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
fprintf
(
dump_file
,
" "
);
print_gimple_stmt
(
dump_file
,
stmt
,
0
,
0
);
fprintf
(
dump_file
,
"
\t\t
freq:%3.2f size:%3i time:%3i
\n
"
,
((
double
)
freq
)
/
CGRAPH_FREQ_BASE
,
this_size
,
this_time
);
((
double
)
freq
)
/
CGRAPH_FREQ_BASE
,
this_size
,
this_time
);
}
if
(
gimple_assign_load_p
(
stmt
)
&&
nonconstant_names
.
exists
())
{
struct
predicate
this_array_index
;
this_array_index
=
array_index_predicate
(
info
,
nonconstant_names
,
this_array_index
=
array_index_predicate
(
info
,
nonconstant_names
,
gimple_assign_rhs1
(
stmt
));
if
(
!
false_predicate_p
(
&
this_array_index
))
array_index
=
and_predicates
(
info
->
conds
,
&
array_index
,
&
this_array_index
);
array_index
=
and_predicates
(
info
->
conds
,
&
array_index
,
&
this_array_index
);
}
if
(
gimple_store_p
(
stmt
)
&&
nonconstant_names
.
exists
())
{
struct
predicate
this_array_index
;
this_array_index
=
array_index_predicate
(
info
,
nonconstant_names
,
this_array_index
=
array_index_predicate
(
info
,
nonconstant_names
,
gimple_get_lhs
(
stmt
));
if
(
!
false_predicate_p
(
&
this_array_index
))
array_index
=
and_predicates
(
info
->
conds
,
&
array_index
,
&
this_array_index
);
array_index
=
and_predicates
(
info
->
conds
,
&
array_index
,
&
this_array_index
);
}
...
...
@@ -2458,7 +2455,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
prob
=
eliminated_by_inlining_prob
(
stmt
);
if
(
prob
==
1
&&
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
fprintf
(
dump_file
,
"
\t\t
50%% will be eliminated by inlining
\n
"
);
fprintf
(
dump_file
,
"
\t\t
50%% will be eliminated by inlining
\n
"
);
if
(
prob
==
2
&&
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
fprintf
(
dump_file
,
"
\t\t
Will be eliminated by inlining
\n
"
);
...
...
@@ -2521,7 +2519,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
unsigned
int
j
,
i
;
struct
tree_niter_desc
niter_desc
;
basic_block
*
body
=
get_loop_body
(
loop
);
bb_predicate
=
*
(
struct
predicate
*
)
loop
->
header
->
aux
;
bb_predicate
=
*
(
struct
predicate
*
)
loop
->
header
->
aux
;
exits
=
get_loop_exit_edges
(
loop
);
FOR_EACH_VEC_ELT
(
exits
,
j
,
ex
)
...
...
@@ -2530,24 +2528,28 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
{
predicate
will_be_nonconstant
=
will_be_nonconstant_expr_predicate
(
parms_info
,
info
,
niter_desc
.
niter
,
nonconstant_names
);
niter_desc
.
niter
,
nonconstant_names
);
if
(
!
true_predicate_p
(
&
will_be_nonconstant
))
will_be_nonconstant
=
and_predicates
(
info
->
conds
,
&
bb_predicate
,
&
will_be_nonconstant
);
if
(
!
true_predicate_p
(
&
will_be_nonconstant
)
&&
!
false_predicate_p
(
&
will_be_nonconstant
))
/* This is slightly inprecise. We may want to represent each loop with
independent predicate. */
loop_iterations
=
and_predicates
(
info
->
conds
,
&
loop_iterations
,
&
will_be_nonconstant
);
/* This is slightly inprecise. We may want to represent each
loop with independent predicate. */
loop_iterations
=
and_predicates
(
info
->
conds
,
&
loop_iterations
,
&
will_be_nonconstant
);
}
exits
.
release
();
for
(
i
=
0
;
i
<
loop
->
num_nodes
;
i
++
)
{
gimple_stmt_iterator
gsi
;
bb_predicate
=
*
(
struct
predicate
*
)
body
[
i
]
->
aux
;
for
(
gsi
=
gsi_start_bb
(
body
[
i
]);
!
gsi_end_p
(
gsi
);
gsi_next
(
&
gsi
))
bb_predicate
=
*
(
struct
predicate
*
)
body
[
i
]
->
aux
;
for
(
gsi
=
gsi_start_bb
(
body
[
i
]);
!
gsi_end_p
(
gsi
);
gsi_next
(
&
gsi
))
{
gimple
stmt
=
gsi_stmt
(
gsi
);
affine_iv
iv
;
...
...
@@ -2558,27 +2560,33 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
{
predicate
will_be_nonconstant
;
if
(
!
simple_iv
(
loop
,
loop_containing_stmt
(
stmt
),
use
,
&
iv
,
true
)
if
(
!
simple_iv
(
loop
,
loop_containing_stmt
(
stmt
),
use
,
&
iv
,
true
)
||
is_gimple_min_invariant
(
iv
.
step
))
continue
;
will_be_nonconstant
=
will_be_nonconstant_expr_predicate
(
parms_info
,
info
,
iv
.
step
,
nonconstant_names
);
iv
.
step
,
nonconstant_names
);
if
(
!
true_predicate_p
(
&
will_be_nonconstant
))
will_be_nonconstant
=
and_predicates
(
info
->
conds
,
will_be_nonconstant
=
and_predicates
(
info
->
conds
,
&
bb_predicate
,
&
will_be_nonconstant
);
if
(
!
true_predicate_p
(
&
will_be_nonconstant
)
&&
!
false_predicate_p
(
&
will_be_nonconstant
))
/* This is slightly inprecise. We may want to represent each loop with
independent predicate. */
loop_stride
=
and_predicates
(
info
->
conds
,
&
loop_stride
,
&
will_be_nonconstant
);
/* This is slightly inprecise. We may want to represent
each loop with independent predicate. */
loop_stride
=
and_predicates
(
info
->
conds
,
&
loop_stride
,
&
will_be_nonconstant
);
}
}
}
free
(
body
);
}
set_hint_predicate
(
&
inline_summary
(
node
)
->
loop_iterations
,
loop_iterations
);
set_hint_predicate
(
&
inline_summary
(
node
)
->
loop_iterations
,
loop_iterations
);
set_hint_predicate
(
&
inline_summary
(
node
)
->
loop_stride
,
loop_stride
);
scev_finalize
();
}
...
...
@@ -2691,8 +2699,7 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
info
->
estimated_stack_size
=
info
->
estimated_self_stack_size
;
#ifdef ENABLE_CHECKING
inline_update_overall_summary
(
node
);
gcc_assert
(
info
->
time
==
info
->
self_time
&&
info
->
size
==
info
->
self_size
);
gcc_assert
(
info
->
time
==
info
->
self_time
&&
info
->
size
==
info
->
self_size
);
#endif
pop_cfun
();
...
...
@@ -2716,7 +2723,7 @@ struct gimple_opt_pass pass_inline_parameters =
"inline_param"
,
/* name */
OPTGROUP_INLINE
,
/* optinfo_flags */
NULL
,
/* gate */
compute_inline_parameters_for_current
,
/* execute */
compute_inline_parameters_for_current
,
/* execute */
NULL
,
/* sub */
NULL
,
/* next */
0
,
/* static_pass_number */
...
...
@@ -2776,7 +2783,6 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *time,
vec
<
tree
>
known_binfos
,
vec
<
ipa_agg_jump_function_p
>
known_aggs
,
inline_hints
*
hints
)
{
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
e
);
int
call_size
=
es
->
call_stmt_size
;
...
...
@@ -2784,8 +2790,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *time,
if
(
!
e
->
callee
&&
estimate_edge_devirt_benefit
(
e
,
&
call_size
,
&
call_time
,
known_vals
,
known_binfos
,
known_aggs
)
&&
hints
&&
cgraph_maybe_hot_edge_p
(
e
))
&&
hints
&&
cgraph_maybe_hot_edge_p
(
e
))
*
hints
|=
INLINE_HINT_indirect_call
;
*
size
+=
call_size
*
INLINE_SIZE_SCALE
;
*
time
+=
call_time
*
prob
/
REG_BR_PROB_BASE
...
...
@@ -2812,26 +2817,29 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, int *time,
for
(
e
=
node
->
callees
;
e
;
e
=
e
->
next_callee
)
{
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
e
);
if
(
!
es
->
predicate
||
evaluate_predicate
(
es
->
predicate
,
possible_truths
))
if
(
!
es
->
predicate
||
evaluate_predicate
(
es
->
predicate
,
possible_truths
))
{
if
(
e
->
inline_failed
)
{
/* Predicates of calls shall not use NOT_CHANGED codes,
sowe do not need to compute probabilities. */
estimate_edge_size_and_time
(
e
,
size
,
time
,
REG_BR_PROB_BASE
,
known_vals
,
known_binfos
,
known_aggs
,
hints
);
known_vals
,
known_binfos
,
known_aggs
,
hints
);
}
else
estimate_calls_size_and_time
(
e
->
callee
,
size
,
time
,
hints
,
possible_truths
,
known_vals
,
known_binfos
,
known_aggs
);
known_vals
,
known_binfos
,
known_aggs
);
}
}
for
(
e
=
node
->
indirect_calls
;
e
;
e
=
e
->
next_callee
)
{
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
e
);
if
(
!
es
->
predicate
||
evaluate_predicate
(
es
->
predicate
,
possible_truths
))
if
(
!
es
->
predicate
||
evaluate_predicate
(
es
->
predicate
,
possible_truths
))
estimate_edge_size_and_time
(
e
,
size
,
time
,
REG_BR_PROB_BASE
,
known_vals
,
known_binfos
,
known_aggs
,
hints
);
...
...
@@ -2861,18 +2869,15 @@ estimate_node_size_and_time (struct cgraph_node *node,
inline_hints
hints
=
0
;
int
i
;
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
{
bool
found
=
false
;
fprintf
(
dump_file
,
" Estimating body: %s/%i
\n
"
" Known to be false: "
,
cgraph_node_name
(
node
),
node
->
uid
);
" Known to be false: "
,
cgraph_node_name
(
node
),
node
->
uid
);
for
(
i
=
predicate_not_inlined_condition
;
i
<
(
predicate_first_dynamic_condition
+
(
int
)
vec_safe_length
(
info
->
conds
));
i
++
)
+
(
int
)
vec_safe_length
(
info
->
conds
));
i
++
)
if
(
!
(
possible_truths
&
(
1
<<
i
)))
{
if
(
found
)
...
...
@@ -2898,7 +2903,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
inline_param_summary
);
gcc_checking_assert
(
prob
>=
0
);
gcc_checking_assert
(
prob
<=
REG_BR_PROB_BASE
);
time
+=
((
gcov_type
)
e
->
time
*
prob
)
/
REG_BR_PROB_BASE
;
time
+=
((
gcov_type
)
e
->
time
*
prob
)
/
REG_BR_PROB_BASE
;
}
if
(
time
>
MAX_TIME
*
INLINE_TIME_SCALE
)
time
=
MAX_TIME
*
INLINE_TIME_SCALE
;
...
...
@@ -2910,13 +2915,13 @@ estimate_node_size_and_time (struct cgraph_node *node,
if
(
info
->
loop_iterations
&&
!
evaluate_predicate
(
info
->
loop_iterations
,
possible_truths
))
hints
|=
INLINE_HINT_loop_iterations
;
hints
|=
INLINE_HINT_loop_iterations
;
if
(
info
->
loop_stride
&&
!
evaluate_predicate
(
info
->
loop_stride
,
possible_truths
))
hints
|=
INLINE_HINT_loop_stride
;
hints
|=
INLINE_HINT_loop_stride
;
if
(
info
->
array_index
&&
!
evaluate_predicate
(
info
->
array_index
,
possible_truths
))
hints
|=
INLINE_HINT_array_index
;
hints
|=
INLINE_HINT_array_index
;
if
(
info
->
scc_no
)
hints
|=
INLINE_HINT_in_scc
;
if
(
DECL_DECLARED_INLINE_P
(
node
->
symbol
.
decl
))
...
...
@@ -2929,9 +2934,8 @@ estimate_node_size_and_time (struct cgraph_node *node,
time
=
RDIV
(
time
,
INLINE_TIME_SCALE
);
size
=
RDIV
(
size
,
INLINE_SIZE_SCALE
);
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
fprintf
(
dump_file
,
"
\n
size:%i time:%i
\n
"
,
(
int
)
size
,
(
int
)
time
);
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
fprintf
(
dump_file
,
"
\n
size:%i time:%i
\n
"
,
(
int
)
size
,
(
int
)
time
);
if
(
ret_time
)
*
ret_time
=
time
;
if
(
ret_size
)
...
...
@@ -2982,8 +2986,7 @@ remap_predicate (struct inline_summary *info,
struct
predicate
*
p
,
vec
<
int
>
operand_map
,
vec
<
int
>
offset_map
,
clause_t
possible_truths
,
struct
predicate
*
toplev_predicate
)
clause_t
possible_truths
,
struct
predicate
*
toplev_predicate
)
{
int
i
;
struct
predicate
out
=
true_predicate
();
...
...
@@ -2999,7 +3002,7 @@ remap_predicate (struct inline_summary *info,
gcc_assert
(
i
<
MAX_CLAUSES
);
for
(
cond
=
0
;
cond
<
NUM_CONDITIONS
;
cond
++
)
for
(
cond
=
0
;
cond
<
NUM_CONDITIONS
;
cond
++
)
/* Do we have condition we can't disprove? */
if
(
clause
&
possible_truths
&
(
1
<<
cond
))
{
...
...
@@ -3011,11 +3014,12 @@ remap_predicate (struct inline_summary *info,
struct
condition
*
c
;
c
=
&
(
*
callee_info
->
conds
)[
cond
-
predicate_first_dynamic_condition
];
-
predicate_first_dynamic_condition
];
/* See if we can remap condition operand to caller's operand.
Otherwise give up. */
if
(
!
operand_map
.
exists
()
||
(
int
)
operand_map
.
length
()
<=
c
->
operand_num
||
(
int
)
operand_map
.
length
()
<=
c
->
operand_num
||
operand_map
[
c
->
operand_num
]
==
-
1
/* TODO: For non-aggregate conditions, adding an offset is
basically an arithmetic jump function processing which
...
...
@@ -3035,8 +3039,7 @@ remap_predicate (struct inline_summary *info,
offset_delta
=
0
;
}
gcc_assert
(
!
c
->
agg_contents
||
c
->
by_ref
||
offset_delta
==
0
);
||
c
->
by_ref
||
offset_delta
==
0
);
ap
.
offset
=
c
->
offset
+
offset_delta
;
ap
.
agg_contents
=
c
->
agg_contents
;
ap
.
by_ref
=
c
->
by_ref
;
...
...
@@ -3065,8 +3068,7 @@ remap_predicate (struct inline_summary *info,
Compute peak stack usage. */
static
void
inline_update_callee_summaries
(
struct
cgraph_node
*
node
,
int
depth
)
inline_update_callee_summaries
(
struct
cgraph_node
*
node
,
int
depth
)
{
struct
cgraph_edge
*
e
;
struct
inline_summary
*
callee_info
=
inline_summary
(
node
);
...
...
@@ -3078,8 +3080,7 @@ inline_update_callee_summaries (struct cgraph_node *node,
+
caller_info
->
estimated_self_stack_size
;
peak
=
callee_info
->
stack_frame_offset
+
callee_info
->
estimated_self_stack_size
;
if
(
inline_summary
(
node
->
global
.
inlined_to
)
->
estimated_stack_size
<
peak
)
if
(
inline_summary
(
node
->
global
.
inlined_to
)
->
estimated_stack_size
<
peak
)
inline_summary
(
node
->
global
.
inlined_to
)
->
estimated_stack_size
=
peak
;
cgraph_propagate_frequency
(
node
);
for
(
e
=
node
->
callees
;
e
;
e
=
e
->
next_callee
)
...
...
@@ -3163,8 +3164,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
{
p
=
remap_predicate
(
info
,
callee_info
,
es
->
predicate
,
operand_map
,
offset_map
,
possible_truths
,
toplev_predicate
);
possible_truths
,
toplev_predicate
);
edge_set_predicate
(
e
,
&
p
);
/* TODO: We should remove the edge for code that will be
optimized out, but we need to keep verifiers and tree-inline
...
...
@@ -3227,17 +3227,13 @@ remap_hint_predicate (struct inline_summary *info,
p
=
remap_predicate
(
info
,
callee_info
,
*
hint
,
operand_map
,
offset_map
,
possible_truths
,
toplev_predicate
);
if
(
!
false_predicate_p
(
&
p
)
&&
!
true_predicate_p
(
&
p
))
possible_truths
,
toplev_predicate
);
if
(
!
false_predicate_p
(
&
p
)
&&
!
true_predicate_p
(
&
p
))
{
if
(
!*
hint
)
set_hint_predicate
(
hint
,
p
);
else
**
hint
=
and_predicates
(
info
->
conds
,
*
hint
,
&
p
);
**
hint
=
and_predicates
(
info
->
conds
,
*
hint
,
&
p
);
}
}
...
...
@@ -3312,19 +3308,19 @@ inline_merge_summary (struct cgraph_edge *edge)
&
toplev_predicate
);
if
(
!
false_predicate_p
(
&
p
))
{
gcov_type
add_time
=
((
gcov_type
)
e
->
time
*
edge
->
frequency
gcov_type
add_time
=
((
gcov_type
)
e
->
time
*
edge
->
frequency
+
CGRAPH_FREQ_BASE
/
2
)
/
CGRAPH_FREQ_BASE
;
int
prob
=
predicate_probability
(
callee_info
->
conds
,
&
e
->
predicate
,
clause
,
es
->
param
);
add_time
=
((
gcov_type
)
add_time
*
prob
)
/
REG_BR_PROB_BASE
;
add_time
=
((
gcov_type
)
add_time
*
prob
)
/
REG_BR_PROB_BASE
;
if
(
add_time
>
MAX_TIME
*
INLINE_TIME_SCALE
)
add_time
=
MAX_TIME
*
INLINE_TIME_SCALE
;
if
(
prob
!=
REG_BR_PROB_BASE
&&
dump_file
&&
(
dump_flags
&
TDF_DETAILS
))
{
fprintf
(
dump_file
,
"
\t\t
Scaling time by probability:%f
\n
"
,
(
double
)
prob
/
REG_BR_PROB_BASE
);
(
double
)
prob
/
REG_BR_PROB_BASE
);
}
account_size_time
(
info
,
e
->
size
,
add_time
,
&
p
);
}
...
...
@@ -3333,16 +3329,13 @@ inline_merge_summary (struct cgraph_edge *edge)
offset_map
,
clause
,
&
toplev_predicate
);
remap_hint_predicate
(
info
,
callee_info
,
&
callee_info
->
loop_iterations
,
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
remap_hint_predicate
(
info
,
callee_info
,
&
callee_info
->
loop_stride
,
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
remap_hint_predicate
(
info
,
callee_info
,
&
callee_info
->
array_index
,
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
operand_map
,
offset_map
,
clause
,
&
toplev_predicate
);
inline_update_callee_summaries
(
edge
->
callee
,
inline_edge_summary
(
edge
)
->
loop_depth
);
...
...
@@ -3374,7 +3367,7 @@ inline_update_overall_summary (struct cgraph_node *node)
info
->
time
=
MAX_TIME
*
INLINE_TIME_SCALE
;
}
estimate_calls_size_and_time
(
node
,
&
info
->
size
,
&
info
->
time
,
NULL
,
~
(
clause_t
)(
1
<<
predicate_false_condition
),
~
(
clause_t
)
(
1
<<
predicate_false_condition
),
vNULL
,
vNULL
,
vNULL
);
info
->
time
=
(
info
->
time
+
INLINE_TIME_SCALE
/
2
)
/
INLINE_TIME_SCALE
;
info
->
size
=
(
info
->
size
+
INLINE_SIZE_SCALE
/
2
)
/
INLINE_SIZE_SCALE
;
...
...
@@ -3386,8 +3379,7 @@ simple_edge_hints (struct cgraph_edge *edge)
{
int
hints
=
0
;
struct
cgraph_node
*
to
=
(
edge
->
caller
->
global
.
inlined_to
?
edge
->
caller
->
global
.
inlined_to
:
edge
->
caller
);
?
edge
->
caller
->
global
.
inlined_to
:
edge
->
caller
);
if
(
inline_summary
(
to
)
->
scc_no
&&
inline_summary
(
to
)
->
scc_no
==
inline_summary
(
edge
->
callee
)
->
scc_no
&&
!
cgraph_edge_recursive_p
(
edge
))
...
...
@@ -3437,7 +3429,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
/* When caching, update the cache entry. */
if
(
edge_growth_cache
.
exists
())
{
if
((
int
)
edge_growth_cache
.
length
()
<=
edge
->
uid
)
if
((
int
)
edge_growth_cache
.
length
()
<=
edge
->
uid
)
edge_growth_cache
.
safe_grow_cleared
(
cgraph_edge_max_uid
);
edge_growth_cache
[
edge
->
uid
].
time
=
time
+
(
time
>=
0
);
...
...
@@ -3537,7 +3529,8 @@ estimate_time_after_inlining (struct cgraph_node *node,
struct
inline_edge_summary
*
es
=
inline_edge_summary
(
edge
);
if
(
!
es
->
predicate
||
!
false_predicate_p
(
es
->
predicate
))
{
gcov_type
time
=
inline_summary
(
node
)
->
time
+
estimate_edge_time
(
edge
);
gcov_type
time
=
inline_summary
(
node
)
->
time
+
estimate_edge_time
(
edge
);
if
(
time
<
0
)
time
=
0
;
if
(
time
>
MAX_TIME
)
...
...
@@ -3600,7 +3593,7 @@ do_estimate_growth_1 (struct cgraph_node *node, void *data)
int
do_estimate_growth
(
struct
cgraph_node
*
node
)
{
struct
growth_data
d
=
{
0
,
false
};
struct
growth_data
d
=
{
0
,
false
};
struct
inline_summary
*
info
=
inline_summary
(
node
);
cgraph_for_node_and_aliases
(
node
,
do_estimate_growth_1
,
&
d
,
true
);
...
...
@@ -3629,7 +3622,7 @@ do_estimate_growth (struct cgraph_node *node)
if
(
node_growth_cache
.
exists
())
{
if
((
int
)
node_growth_cache
.
length
()
<=
node
->
uid
)
if
((
int
)
node_growth_cache
.
length
()
<=
node
->
uid
)
node_growth_cache
.
safe_grow_cleared
(
cgraph_max_uid
);
node_growth_cache
[
node
->
uid
]
=
d
.
growth
+
(
d
.
growth
>=
0
);
}
...
...
@@ -3741,8 +3734,7 @@ read_inline_edge_summary (struct lto_input_block *ib, struct cgraph_edge *e)
{
es
->
param
.
safe_grow_cleared
(
length
);
for
(
i
=
0
;
i
<
length
;
i
++
)
es
->
param
[
i
].
change_prob
=
streamer_read_uhwi
(
ib
);
es
->
param
[
i
].
change_prob
=
streamer_read_uhwi
(
ib
);
}
}
...
...
@@ -3906,7 +3898,7 @@ write_inline_edge_summary (struct output_block *ob, struct cgraph_edge *e)
streamer_write_uhwi
(
ob
,
es
->
loop_depth
);
write_predicate
(
ob
,
es
->
predicate
);
streamer_write_uhwi
(
ob
,
es
->
param
.
length
());
for
(
i
=
0
;
i
<
(
int
)
es
->
param
.
length
();
i
++
)
for
(
i
=
0
;
i
<
(
int
)
es
->
param
.
length
();
i
++
)
streamer_write_uhwi
(
ob
,
es
->
param
[
i
].
change_prob
);
}
...
...
@@ -3946,7 +3938,10 @@ inline_write_summary (void)
size_time_entry
*
e
;
struct
condition
*
c
;
streamer_write_uhwi
(
ob
,
lto_symtab_encoder_encode
(
encoder
,
(
symtab_node
)
node
));
streamer_write_uhwi
(
ob
,
lto_symtab_encoder_encode
(
encoder
,
(
symtab_node
)
node
));
streamer_write_hwi
(
ob
,
info
->
estimated_self_stack_size
);
streamer_write_hwi
(
ob
,
info
->
self_size
);
streamer_write_hwi
(
ob
,
info
->
self_time
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment