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
e2102efc
Commit
e2102efc
authored
Jul 27, 2010
by
Xinliang David Li
Committed by
Xinliang David Li
Jul 27, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Multiple exit loop handling in ivopts. Regression tested on x86-64/linux
From-SVN: r162585
parent
01d2a0c1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
27 deletions
+82
-27
gcc/ChangeLog
+9
-0
gcc/tree-ssa-loop-ivopts.c
+73
-27
No files found.
gcc/ChangeLog
View file @
e2102efc
2010-07-27 Xinliang David Li <davidxl@google.com>
* tree-ssa-loop-ivopts.c (niter_for_exit): New parameter.
(niter_for_single_dom_exit): Passes additional parameter.
(iv_period): Fix comments.
(may_eliminate_iv): Handles multiple exit loops properly.
(free_tree_niter_desc): New function.
(free_loop_data): Frees up loop iteration descriptors.
2010-07-27 Jakub Jelinek <jakub@redhat.com>
PR target/44542
...
...
gcc/tree-ssa-loop-ivopts.c
View file @
e2102efc
...
...
@@ -718,9 +718,10 @@ contains_abnormal_ssa_name_p (tree expr)
EXIT of DATA->current_loop, or NULL if something goes wrong. */
static
tree
niter_for_exit
(
struct
ivopts_data
*
data
,
edge
exit
)
niter_for_exit
(
struct
ivopts_data
*
data
,
edge
exit
,
struct
tree_niter_desc
**
desc_p
)
{
struct
tree_niter_desc
desc
;
struct
tree_niter_desc
*
desc
=
NULL
;
tree
niter
;
void
**
slot
;
...
...
@@ -739,19 +740,24 @@ niter_for_exit (struct ivopts_data *data, edge exit)
being zero). Also, we cannot safely work with ssa names that
appear in phi nodes on abnormal edges, so that we do not create
overlapping life ranges for them (PR 27283). */
desc
=
XNEW
(
struct
tree_niter_desc
);
if
(
number_of_iterations_exit
(
data
->
current_loop
,
exit
,
&
desc
,
true
)
&&
integer_zerop
(
desc
.
may_be_zero
)
&&
!
contains_abnormal_ssa_name_p
(
desc
.
niter
))
niter
=
desc
.
niter
;
exit
,
desc
,
true
)
&&
integer_zerop
(
desc
->
may_be_zero
)
&&
!
contains_abnormal_ssa_name_p
(
desc
->
niter
))
niter
=
desc
->
niter
;
else
niter
=
NULL_TREE
;
*
pointer_map_insert
(
data
->
niters
,
exit
)
=
niter
;
desc
->
niter
=
niter
;
slot
=
pointer_map_insert
(
data
->
niters
,
exit
);
*
slot
=
desc
;
}
else
niter
=
(
tree
)
*
slot
;
niter
=
(
(
struct
tree_niter_desc
*
)
*
slot
)
->
niter
;
if
(
desc_p
)
*
desc_p
=
(
struct
tree_niter_desc
*
)
*
slot
;
return
niter
;
}
...
...
@@ -767,7 +773,7 @@ niter_for_single_dom_exit (struct ivopts_data *data)
if
(
!
exit
)
return
NULL
;
return
niter_for_exit
(
data
,
exit
);
return
niter_for_exit
(
data
,
exit
,
NULL
);
}
/* Initializes data structures used by the iv optimization pass, stored
...
...
@@ -4005,15 +4011,20 @@ iv_period (struct iv *iv)
gcc_assert
(
step
&&
TREE_CODE
(
step
)
==
INTEGER_CST
);
/* Period of the iv is gcd (step, type range). Since type range is power
of two, it suffices to determine the maximum power of two that divides
step. */
pow2div
=
num_ending_zeros
(
step
);
type
=
unsigned_type_for
(
TREE_TYPE
(
step
));
/* Period of the iv is lcm (step, type_range)/step -1,
i.e., N*type_range/step - 1. Since type range is power
of two, N == (step >> num_of_ending_zeros_binary (step),
so the final result is
(type_range >> num_of_ending_zeros_binary (step)) - 1
*/
pow2div
=
num_ending_zeros
(
step
);
period
=
build_low_bits_mask
(
type
,
(
TYPE_PRECISION
(
type
)
-
tree_low_cst
(
pow2div
,
1
)));
(
TYPE_PRECISION
(
type
)
-
tree_low_cst
(
pow2div
,
1
)));
return
period
;
}
...
...
@@ -4047,6 +4058,7 @@ may_eliminate_iv (struct ivopts_data *data,
tree
nit
,
period
;
struct
loop
*
loop
=
data
->
current_loop
;
aff_tree
bnd
;
struct
tree_niter_desc
*
desc
=
NULL
;
if
(
TREE_CODE
(
cand
->
iv
->
step
)
!=
INTEGER_CST
)
return
false
;
...
...
@@ -4065,7 +4077,7 @@ may_eliminate_iv (struct ivopts_data *data,
if
(
flow_bb_inside_loop_p
(
loop
,
exit
->
dest
))
return
false
;
nit
=
niter_for_exit
(
data
,
exit
);
nit
=
niter_for_exit
(
data
,
exit
,
&
desc
);
if
(
!
nit
)
return
false
;
...
...
@@ -4077,27 +4089,46 @@ may_eliminate_iv (struct ivopts_data *data,
/* If the number of iterations is constant, compare against it directly. */
if
(
TREE_CODE
(
nit
)
==
INTEGER_CST
)
{
if
(
!
tree_int_cst_lt
(
nit
,
period
))
return
false
;
/* See cand_value_at. */
if
(
stmt_after_increment
(
loop
,
cand
,
use
->
stmt
))
{
if
(
!
tree_int_cst_lt
(
nit
,
period
))
return
false
;
}
else
{
if
(
tree_int_cst_lt
(
period
,
nit
))
return
false
;
}
}
/* If not, and if this is the only possible exit of the loop, see whether
we can get a conservative estimate on the number of iterations of the
entire loop and compare against that instead. */
else
if
(
loop_only_exit_p
(
loop
,
exit
))
else
{
double_int
period_value
,
max_niter
;
if
(
!
estimated_loop_iterations
(
loop
,
true
,
&
max_niter
))
return
false
;
max_niter
=
desc
->
max
;
if
(
stmt_after_increment
(
loop
,
cand
,
use
->
stmt
))
max_niter
=
double_int_add
(
max_niter
,
double_int_one
);
period_value
=
tree_to_double_int
(
period
);
if
(
double_int_ucmp
(
max_niter
,
period_value
)
>=
0
)
return
false
;
if
(
double_int_ucmp
(
max_niter
,
period_value
)
>
0
)
{
/* See if we can take advantage of infered loop bound information. */
if
(
loop_only_exit_p
(
loop
,
exit
))
{
if
(
!
estimated_loop_iterations
(
loop
,
true
,
&
max_niter
))
return
false
;
/* The loop bound is already adjusted by adding 1. */
if
(
double_int_ucmp
(
max_niter
,
period_value
)
>
0
)
return
false
;
}
else
return
false
;
}
}
/* Otherwise, punt. */
else
return
false
;
cand_value_at
(
loop
,
cand
,
use
->
stmt
,
nit
,
&
bnd
);
*
bound
=
aff_combination_to_tree
(
&
bnd
);
...
...
@@ -4108,6 +4139,7 @@ may_eliminate_iv (struct ivopts_data *data,
return
true
;
}
/* Determines cost of basing replacement of USE on CAND in a condition. */
static
bool
...
...
@@ -5779,6 +5811,19 @@ remove_unused_ivs (struct ivopts_data *data)
BITMAP_FREE
(
toremove
);
}
/* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
for pointer_map_traverse. */
static
bool
free_tree_niter_desc
(
const
void
*
key
ATTRIBUTE_UNUSED
,
void
**
value
,
void
*
data
ATTRIBUTE_UNUSED
)
{
struct
tree_niter_desc
*
const
niter
=
(
struct
tree_niter_desc
*
)
*
value
;
free
(
niter
);
return
true
;
}
/* Frees data allocated by the optimization of a single loop. */
static
void
...
...
@@ -5790,6 +5835,7 @@ free_loop_data (struct ivopts_data *data)
if
(
data
->
niters
)
{
pointer_map_traverse
(
data
->
niters
,
free_tree_niter_desc
,
NULL
);
pointer_map_destroy
(
data
->
niters
);
data
->
niters
=
NULL
;
}
...
...
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