Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
9c1ec62d
Commit
9c1ec62d
authored
Sep 18, 2008
by
Michael Beck
Browse files
implemented constant load access for pointer arithmetic for new initializers
[r22090]
parent
a86252a0
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/opt/ldstopt.c
View file @
9c1ec62d
...
...
@@ -497,20 +497,43 @@ typedef struct path_entry {
static
ir_node
*
rec_find_compound_ent_value
(
ir_node
*
ptr
,
path_entry
*
next
)
{
path_entry
entry
,
*
p
;
ir_entity
*
ent
;
ir_entity
*
ent
,
*
field
;
ir_initializer_t
*
initializer
;
tarval
*
tv
;
ir_type
*
tp
;
entry
.
next
=
next
;
if
(
is_Sel
(
ptr
))
{
ir_entity
*
field
;
ir_type
*
tp
;
if
(
is_SymConst
(
ptr
))
{
/* found the root */
ent
=
get_SymConst_entity
(
ptr
);
initializer
=
get_entity_initializer
(
ent
);
for
(
p
=
next
;
p
!=
NULL
;
p
=
p
->
next
)
{
unsigned
n
;
if
(
initializer
->
kind
!=
IR_INITIALIZER_COMPOUND
)
return
NULL
;
n
=
get_initializer_compound_n_entries
(
initializer
);
if
(
p
->
index
>=
n
)
return
NULL
;
initializer
=
get_initializer_compound_value
(
initializer
,
p
->
index
);
}
switch
(
initializer
->
kind
)
{
case
IR_INITIALIZER_CONST
:
return
get_initializer_const_value
(
initializer
);
case
IR_INITIALIZER_TARVAL
:
case
IR_INITIALIZER_NULL
:
default:
return
NULL
;
}
}
else
if
(
is_Sel
(
ptr
))
{
entry
.
ent
=
field
=
get_Sel_entity
(
ptr
);
tp
=
get_entity_owner
(
field
);
if
(
is_Array_type
(
tp
))
{
assert
(
get_Sel_n_indexs
(
ptr
)
==
1
&&
"multi dim arrays not implemented"
);
entry
.
index
=
get_Sel_array_index_long
(
ptr
,
0
)
-
get_array_lower_bound_int
(
tp
,
0
);
entry
.
index
=
get_Sel_array_index_long
(
ptr
,
0
)
-
get_array_lower_bound_int
(
tp
,
0
);
}
else
{
int
i
,
n_members
=
get_compound_n_members
(
tp
);
for
(
i
=
0
;
i
<
n_members
;
++
i
)
{
...
...
@@ -524,33 +547,104 @@ static ir_node *rec_find_compound_ent_value(ir_node *ptr, path_entry *next) {
entry
.
index
=
i
;
}
return
rec_find_compound_ent_value
(
get_Sel_ptr
(
ptr
),
&
entry
);
}
}
else
if
(
is_Add
(
ptr
))
{
ir_node
*
l
=
get_Add_left
(
ptr
);
ir_node
*
r
=
get_Add_right
(
ptr
);
ir_mode
*
mode
;
unsigned
pos
;
/* found the end */
assert
(
is_SymConst
(
ptr
));
if
(
is_Const
(
r
))
{
ptr
=
l
;
tv
=
get_Const_tarval
(
r
);
}
else
{
ptr
=
r
;
tv
=
get_Const_tarval
(
l
);
}
ptr_arith:
mode
=
get_tarval_mode
(
tv
);
ent
=
get_SymConst_entity
(
ptr
);
initializer
=
get_entity_initializer
(
ent
);
for
(
p
=
next
;
p
!=
NULL
;
p
=
p
->
next
)
{
unsigned
n
;
/* ptr must be a Sel or a SymConst, this was checked in find_constant_entity() */
if
(
is_Sel
(
ptr
))
{
field
=
get_Sel_entity
(
ptr
);
}
else
{
field
=
get_SymConst_entity
(
ptr
);
}
if
(
initializer
->
kind
!=
IR_INITIALIZER_COMPOUND
)
/* count needed entries */
pos
=
0
;
for
(
ent
=
field
;;)
{
tp
=
get_entity_type
(
ent
);
if
(
!
is_Array_type
(
tp
))
break
;
ent
=
get_array_element_entity
(
tp
);
++
pos
;
}
/* should be at least ONE entry */
if
(
pos
==
0
)
return
NULL
;
n
=
get_initializer_compound_n_entries
(
initializer
);
if
(
p
->
index
>=
n
)
/* allocate the right number of entries */
NEW_ARR_A
(
path_entry
,
p
,
pos
);
/* fill them up */
pos
=
0
;
for
(
ent
=
field
;;)
{
unsigned
size
;
tarval
*
sz
,
*
tv_index
,
*
tlower
,
*
tupper
;
long
index
;
ir_node
*
bound
;
tp
=
get_entity_type
(
ent
);
if
(
!
is_Array_type
(
tp
))
break
;
ent
=
get_array_element_entity
(
tp
);
p
[
pos
].
ent
=
ent
;
p
[
pos
].
next
=
&
p
[
pos
+
1
];
size
=
get_type_size_bytes
(
get_entity_type
(
ent
));
sz
=
new_tarval_from_long
(
size
,
mode
);
tv_index
=
tarval_div
(
tv
,
sz
);
tv
=
tarval_mod
(
tv
,
sz
);
if
(
tv_index
==
tarval_bad
||
tv
==
tarval_bad
)
return
NULL
;
assert
(
get_array_n_dimensions
(
tp
)
==
1
&&
"multiarrays not implemented"
);
bound
=
get_array_lower_bound
(
tp
,
0
);
tlower
=
computed_value
(
bound
);
bound
=
get_array_upper_bound
(
tp
,
0
);
tupper
=
computed_value
(
bound
);
if
(
tlower
==
tarval_bad
||
tupper
==
tarval_bad
)
return
NULL
;
if
(
tarval_cmp
(
tv_index
,
tlower
)
&
pn_Cmp_Lt
)
return
NULL
;
if
(
tarval_cmp
(
tupper
,
tv_index
)
&
pn_Cmp_Lt
)
return
NULL
;
/* ok, bounds check finished */
index
=
get_tarval_long
(
tv_index
);
p
[
pos
].
index
=
index
;
++
pos
;
}
if
(
!
tarval_is_null
(
tv
))
{
/* hmm, wrong access */
return
NULL
;
initializer
=
get_initializer_compound_value
(
initializer
,
p
->
index
);
}
}
p
[
pos
-
1
].
next
=
next
;
return
rec_find_compound_ent_value
(
ptr
,
p
);
}
else
if
(
is_Sub
(
ptr
))
{
ir_node
*
l
=
get_Sub_left
(
ptr
);
ir_node
*
r
=
get_Sub_right
(
ptr
);
switch
(
initializer
->
kind
)
{
case
IR_INITIALIZER_CONST
:
return
get_initializer_const_value
(
initializer
);
case
IR_INITIALIZER_TARVAL
:
case
IR_INITIALIZER_NULL
:
default:
return
NULL
;
ptr
=
l
;
tv
=
get_Const_tarval
(
r
);
tv
=
tarval_neg
(
tv
);
goto
ptr_arith
;
}
return
NULL
;
}
static
ir_node
*
find_compound_ent_value
(
ir_node
*
ptr
)
{
...
...
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