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
5052f2d2
Commit
5052f2d2
authored
Dec 10, 2001
by
Götz Lindenmaier
Browse files
Added support for constant entities. A new example program illustrates
their use. Extended dumper routines to dump constant values. [r287]
parent
b4eb108c
Changes
19
Hide whitespace changes
Inline
Side-by-side
Changes
View file @
5052f2d2
10.12.2001 Goetz
Added support for constant entities. A new example program illustrates
their use. Extended dumper routines to dump constant values.
30.11.2001 Goetz
Extendend "comfortable" construction interface by some methods
serving as simple shortcuts.
...
...
ir/common/common.h
View file @
5052f2d2
...
...
@@ -47,7 +47,7 @@
/* If this and DEBUG_libfirm are defined irdump uses the nodeid numbers as
labels for the vcg nodes. This makes the vcg graph better readable.
Sometimes it's useful to see the pointer values, though. */
#define NODEID_AS_LABEL
1
#define NODEID_AS_LABEL
0
/* a list of firm kinds */
typedef
enum
{
...
...
ir/ir/irdump.c
View file @
5052f2d2
...
...
@@ -53,6 +53,8 @@
#define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
#define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
#define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
#define ENT_VALUE_EDGE_ATTR "label: \"value "
#define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
#define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
...
...
@@ -67,10 +69,16 @@ static FILE *F;
/* A compiler option to turn off edge labels */
int
edge_label
=
1
;
/* A compiler option to turn off dumping values of constant entities */
int
const_entities
=
1
;
/* A global variable to record output of the Bad node. */
int
Bad_dumped
;
void
dump_ir_blocks_nodes
(
ir_node
*
n
,
void
*
env
);
void
dump_whole_node
(
ir_node
*
n
,
void
*
env
);
/*******************************************************************/
/* routines to dump information about a single node */
/*******************************************************************/
...
...
@@ -472,6 +480,9 @@ void dump_node2type_edges (ir_node *n, void *env)
assert
(
n
);
switch
(
get_irn_opcode
(
n
))
{
case
iro_Const
:
/* @@@ some consts have an entity */
break
;
case
iro_SymConst
:
if
(
(
get_SymConst_kind
(
n
)
==
type_tag
)
||
(
get_SymConst_kind
(
n
)
==
size
))
{
...
...
@@ -511,6 +522,15 @@ void dump_node2type_edges (ir_node *n, void *env)
}
void
dump_const_expression
(
ir_node
*
value
)
{
ir_graph
*
rem
=
current_ir_graph
;
current_ir_graph
=
get_const_code_irg
();
irg_walk
(
value
,
dump_ir_blocks_nodes
,
NULL
,
get_nodes_Block
(
value
));
set_irg_visited
(
current_ir_graph
,
get_irg_visited
(
current_ir_graph
)
-
1
);
current_ir_graph
=
rem
;
}
/* dumps a type or entity and it's edges. */
void
dump_type_info
(
type_or_ent
*
tore
,
void
*
env
)
{
...
...
@@ -525,18 +545,55 @@ dump_type_info (type_or_ent *tore, void *env) {
case
k_entity
:
{
entity
*
ent
=
(
entity
*
)
tore
;
ir_node
*
value
;
/* The node */
xfprintf
(
F
,
"
\"
ent %I
\"
"
ENTITY_NODE_ATTR
,
get_entity_ident
(
ent
));
if
(
dynamic_allocated
==
get_entity_allocation
(
ent
))
xfprintf
(
F
,
" info1:
\"
dynamic allocated
\
"
}
\
n
"
);
xfprintf
(
F
,
" info1:
\"
dynamic allocated
\n
"
);
else
xfprintf
(
F
,
" info1:
\"
static allocated
\"
}
\n
"
);
xfprintf
(
F
,
"nearedge: { sourcename:
\"
%p
\"
targetname:
\"
%p
\"
"
ENT_OWN_EDGE_ATTR
"}
\n
"
,
tore
,
get_entity_owner
(
ent
));
xfprintf
(
F
,
" info1:
\"
static allocated
\n
"
);
switch
(
get_entity_visibility
(
ent
))
{
case
local
:
fprintf
(
F
,
"local
\n
"
);
break
;
case
external_visible
:
fprintf
(
F
,
"external_visible
\n
"
);
break
;
case
external_allocated
:
fprintf
(
F
,
"external_allocate
\n
d"
);
break
;
}
switch
(
get_entity_variability
(
ent
))
{
case
uninitialized
:
fprintf
(
F
,
"uninitialized"
);
break
;
case
initialized
:
fprintf
(
F
,
"initialized"
);
break
;
case
part_constant
:
fprintf
(
F
,
"part_constant"
);
break
;
case
constant
:
fprintf
(
F
,
"constant"
);
break
;
}
xfprintf
(
F
,
"
\"
}
\n
"
);
/* The Edges */
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
%p
\"
"
ENT_OWN_EDGE_ATTR
"}
\n
"
,
ent
,
get_entity_owner
(
ent
));
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
%p
\"
"
ENT_TYPE_EDGE_ATTR
"}
\n
"
,
tore
,
get_entity_type
(
ent
));
ENT_TYPE_EDGE_ATTR
"}
\n
"
,
ent
,
get_entity_type
(
ent
));
for
(
i
=
0
;
i
<
get_entity_n_overwrites
(
ent
);
i
++
)
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
%p
\"
"
ENT_OVERWRITES_EDGE_ATTR
"}
\n
"
,
tore
,
get_entity_overwrites
(
ent
,
i
));
ENT_OVERWRITES_EDGE_ATTR
"}
\n
"
,
ent
,
get_entity_overwrites
(
ent
,
i
));
/* attached subgraphs */
if
(
const_entities
&&
(
get_entity_variability
(
ent
)
!=
uninitialized
))
{
if
(
is_atomic_entity
(
ent
))
{
value
=
get_atomic_ent_value
(
ent
);
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
"
,
ent
);
PRINT_NODEID
(
value
);
fprintf
(
F
,
"
\"
"
ENT_VALUE_EDGE_ATTR
"
\"
}
\n
"
);
dump_const_expression
(
value
);
}
if
(
is_compound_entity
(
ent
))
{
for
(
i
=
0
;
i
<
get_compound_ent_n_values
(
ent
);
i
++
)
{
value
=
get_compound_ent_value
(
ent
,
i
);
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
"
,
ent
);
PRINT_NODEID
(
value
);
fprintf
(
F
,
"
\"
"
ENT_VALUE_EDGE_ATTR
" %d
\"
}
\n
"
,
i
);
dump_const_expression
(
value
);
xfprintf
(
F
,
"edge: { sourcename:
\"
%p
\"
targetname:
\"
%p
\"
"
ENT_CORR_EDGE_ATTR
"}
\n
"
,
ent
,
get_compound_ent_value_member
(
ent
,
i
),
i
);
}
}
}
}
break
;
case
k_type
:
{
...
...
@@ -902,6 +959,11 @@ dump_type_graph (ir_graph *irg)
/* walk over the blocks in the graph */
type_walk_irg
(
irg
,
dump_type_info
,
NULL
,
NULL
);
/* The walker for the const code can be called several times for the
same (sub) experssion. So that no nodes are dumped several times
we decrease the visited flag of the corresponding graph after each
walk. So now increase it finally. */
inc_irg_visited
(
get_const_code_irg
());
vcg_close
();
current_ir_graph
=
rem
;
...
...
@@ -917,6 +979,7 @@ dump_all_types (void)
{
vcg_open_name
(
"All_types"
);
type_walk
(
dump_type_info
,
NULL
,
NULL
);
inc_irg_visited
(
get_const_code_irg
());
vcg_close
();
}
...
...
@@ -938,6 +1001,7 @@ dump_ir_graph_w_types (ir_graph *irg)
irg_walk
(
irg
->
end
,
dump_whole_node
,
NULL
,
NULL
);
/* dump type info */
type_walk_irg
(
irg
,
dump_type_info
,
NULL
,
NULL
);
inc_irg_visited
(
get_const_code_irg
());
/* dump edges from graph to type info */
irg_walk
(
irg
->
end
,
dump_node2type_edges
,
NULL
,
NULL
);
...
...
@@ -958,6 +1022,7 @@ dump_ir_block_graph_w_types (ir_graph *irg)
dump_ir_block_graph_2
(
irg
);
/* dump type info */
type_walk_irg
(
irg
,
dump_type_info
,
NULL
,
NULL
);
inc_irg_visited
(
get_const_code_irg
());
/* dump edges from graph to type info */
irg_walk
(
irg
->
end
,
dump_node2type_edges
,
NULL
,
NULL
);
...
...
@@ -986,3 +1051,7 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
void
turn_of_edge_labels
()
{
edge_label
=
0
;
}
void
dump_constant_entity_values
()
{
const_entities
=
0
;
}
ir/ir/irdump.h
View file @
5052f2d2
...
...
@@ -238,4 +238,23 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*));
void
turn_of_edge_labels
();
/****m* irdump/dump_constant_entity_values
*
* NAME
* dump_constant_entity_values
* SYNOPSIS
* void dump_constant_entity_values()
* FUNCTION
* Turns off dumping the values of constant entities. Maked type graphs
* better readable.
* INPUTS
* No inputs
* RESULT
* SEE ALSO
*
***
*/
void
dump_constant_entity_values
();
# endif
/* _IRDUMP_H_ */
ir/ir/irgraph.c
View file @
5052f2d2
...
...
@@ -115,6 +115,50 @@ new_ir_graph (entity *ent, int n_loc)
return
res
;
}
/* Make a rudimentary ir graph for the constant code.
Must look like a correct irg, spare everything else. */
ir_graph
*
new_const_code_irg
()
{
ir_graph
*
res
;
ir_node
*
projX
;
res
=
(
ir_graph
*
)
malloc
(
sizeof
(
ir_graph
));
current_ir_graph
=
res
;
res
->
n_loc
=
1
;
/* Only the memory. */
res
->
visited
=
0
;
/* visited flag, for the ir walker */
res
->
block_visited
=
0
;
/* visited flag, for the 'block'-walker */
#if USE_EXPICIT_PHI_IN_STACK
res
->
Phi_in_stack
=
NULL
;
#endif
res
->
obst
=
(
struct
obstack
*
)
xmalloc
(
sizeof
(
struct
obstack
));
obstack_init
(
res
->
obst
);
res
->
value_table
=
new_identities
();
/* value table for global value
numbering for optimizing use in
iropt.c */
res
->
ent
=
NULL
;
res
->
frame_type
=
NULL
;
res
->
start_block
=
new_immBlock
();
res
->
end_block
=
new_immBlock
();
res
->
end
=
new_End
();
mature_block
(
get_cur_block
());
res
->
bad
=
new_ir_node
(
res
,
res
->
start_block
,
op_Bad
,
mode_T
,
0
,
NULL
);
res
->
start
=
new_Start
();
/* Proj results of start node */
projX
=
new_Proj
(
res
->
start
,
mode_X
,
pns_initial_exec
);
set_store
(
new_Proj
(
res
->
start
,
mode_M
,
pns_global_store
));
add_in_edge
(
res
->
start_block
,
projX
);
mature_block
(
res
->
current_block
);
add_in_edge
(
new_immBlock
(),
projX
);
mature_block
(
get_cur_block
());
/* Set the visited flag high enough that the block will never be visited. */
set_irn_visited
(
get_cur_block
(),
-
1
);
set_Block_block_visited
(
get_cur_block
(),
-
1
);
set_Block_block_visited
(
res
->
start_block
,
-
1
);
return
res
;
}
/* Frees the passed irgraph.
Deallocates all nodes in this graph and the ir_graph structure.
Sets the field irgraph in the corresponding entity to NULL.
...
...
ir/ir/irgraph_t.h
View file @
5052f2d2
...
...
@@ -49,4 +49,10 @@ struct ir_graph {
unsigned
long
block_visited
;
/* same as visited, for a
complete block */
};
/* Make a rudimentary ir graph for the constant code.
Must look like a correct irg, spare everything else. */
ir_graph
*
new_const_code_irg
();
# endif
/* _IRGRAPH_T_H_ */
ir/ir/irnode.h
View file @
5052f2d2
...
...
@@ -491,6 +491,8 @@ ir_node *get_fragile_op_mem(ir_node *node);
get_irn_node_nr(X))
#define DDMSG3(X) printf("%s(l.%i) %s: %p\n", __FUNCTION__, __LINE__, \
print_firm_kind(X), (X))
#define DDMSG4(X) printf("%s(l.%i) %s %s: %p\n", __FUNCTION__, __LINE__, \
get_type_tpop_name(X), get_type_name(X), (X))
#endif
...
...
ir/ir/irprog.c
View file @
5052f2d2
...
...
@@ -13,6 +13,7 @@
#endif
# include "irprog_t.h"
# include "irgraph_t.h"
# include "array.h"
# include "obst.h"
# include "typegmod.h"
...
...
@@ -42,6 +43,8 @@ ir_prog *new_ir_prog (void) {
strlen
(
GLOBAL_TYPE_NAME
)));
add_irp_type
((
type
*
)
res
->
glob_type
);
res
->
const_code_irg
=
new_const_code_irg
();
#ifdef DEBUG_libfirm
res
->
max_node_nr
=
1
;
#endif
...
...
@@ -142,3 +145,8 @@ int get_irp_new_node_nr() {
return
irp
->
max_node_nr
-
1
;
}
#endif
ir_graph
*
get_const_code_irg
()
{
return
irp
->
const_code_irg
;
}
ir/ir/irprog.h
View file @
5052f2d2
...
...
@@ -91,4 +91,17 @@ int get_irp_new_node_nr();
#endif
/*****/
/***p* irprog/get_const_code_irg
*
* NAME
* get_const_code_irg - Returns an irgraph that only contains constant
* expressions for constant entities.
* SYNOPSIS
* ir_graph *get_const_code_irg();
* NOTE
* Do not use any access function for this graph, do not generate code
* for this graph.
*/
ir_graph
*
get_const_code_irg
();
#endif
/* ifndef _IRPROG_H_ */
ir/ir/irprog_t.h
View file @
5052f2d2
...
...
@@ -14,8 +14,13 @@ struct ir_prog {
type
*
glob_type
;
/* global type. Must be a class as it can
have fields and procedures. */
type
**
types
;
/* all types in the ir */
ir_graph
*
const_code_irg
;
/* This ir graph gives the proper environment
to allocate nodes the represent values
of constant entities. It is not meant as
a procedure. */
/*struct obstack *obst; * @@@ Should we place all types and
entities on an obstack, too? */
#ifdef DEBUG_libfirm
long
max_node_nr
;
/* to generate unique numbers for nodes. */
#endif
...
...
ir/tr/entity.c
View file @
5052f2d2
...
...
@@ -17,6 +17,9 @@
# include "mangle.h"
# include "typegmod_t.h"
# include "array.h"
/* All this is needed to build the constant node for methods: */
# include "irprog.h"
# include "ircons.h"
/*******************************************************************/
/** general **/
...
...
@@ -54,6 +57,7 @@ entity *
new_entity
(
type
*
owner
,
ident
*
name
,
type
*
type
)
{
entity
*
res
;
ir_graph
*
rem
;
res
=
(
entity
*
)
malloc
(
sizeof
(
entity
));
res
->
kind
=
k_entity
;
...
...
@@ -63,6 +67,15 @@ new_entity (type *owner, ident *name, type *type)
res
->
type
=
type
;
res
->
allocation
=
dynamic_allocated
;
res
->
visibility
=
local
;
if
(
is_method_type
(
type
))
{
res
->
variability
=
constant
;
rem
=
current_ir_graph
;
current_ir_graph
=
get_const_code_irg
();
res
->
value
=
new_Const
(
mode_p
,
tarval_p_from_entity
(
res
));
current_ir_graph
=
rem
;
}
else
{
res
->
variability
=
uninitialized
;
}
res
->
ld_name
=
NULL
;
res
->
overwrites
=
NEW_ARR_F
(
entity
*
,
1
);
...
...
@@ -197,6 +210,80 @@ set_entity_visibility (entity *ent, ent_visibility vis) {
ent
->
visibility
=
vis
;
}
inline
ent_variability
get_entity_variability
(
entity
*
ent
)
{
return
ent
->
variability
;
}
inline
void
set_entity_variability
(
entity
*
ent
,
ent_variability
var
){
if
(
var
==
part_constant
)
assert
(
is_class_type
(
ent
->
type
)
||
is_struct_type
(
ent
->
type
));
if
((
is_compound_type
(
ent
->
type
))
&&
(
ent
->
variability
==
uninitialized
)
&&
(
var
!=
uninitialized
))
{
/* Allocate datastructures for constant values */
ent
->
values
=
NEW_ARR_F
(
ir_node
*
,
1
);
ent
->
val_ents
=
NEW_ARR_F
(
entity
*
,
1
);
}
if
((
is_compound_type
(
ent
->
type
))
&&
(
var
==
uninitialized
)
&&
(
ent
->
variability
!=
uninitialized
))
{
/* Free datastructures for constant values */
DEL_ARR_F
(
ent
->
values
);
DEL_ARR_F
(
ent
->
val_ents
);
}
ent
->
variability
=
var
;
}
/* Set has no effect for entities of type method. */
inline
ir_node
*
get_atomic_ent_value
(
entity
*
ent
)
{
assert
(
ent
);
assert
(
is_atomic_entity
(
ent
));
assert
((
ent
->
variability
!=
uninitialized
));
return
ent
->
value
;
}
inline
void
set_atomic_ent_value
(
entity
*
ent
,
ir_node
*
val
)
{
assert
(
ent
&&
is_atomic_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
if
(
is_method_type
(
ent
->
type
))
return
;
ent
->
value
=
val
;
}
/* A value of a compound entity is a pair of value and the corresponding member of
the compound. */
inline
void
add_compound_ent_value
(
entity
*
ent
,
ir_node
*
val
,
entity
*
member
)
{
assert
(
ent
&&
is_compound_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
ARR_APP1
(
ir_node
*
,
ent
->
values
,
val
);
ARR_APP1
(
entity
*
,
ent
->
val_ents
,
member
);
}
inline
int
get_compound_ent_n_values
(
entity
*
ent
)
{
assert
(
ent
&&
is_compound_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
return
(
ARR_LEN
(
ent
->
values
))
-
1
;
}
inline
ir_node
*
get_compound_ent_value
(
entity
*
ent
,
int
pos
)
{
assert
(
ent
&&
is_compound_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
return
ent
->
values
[
pos
+
1
];
}
inline
entity
*
get_compound_ent_value_member
(
entity
*
ent
,
int
pos
)
{
assert
(
ent
&&
is_compound_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
return
ent
->
val_ents
[
pos
+
1
];
}
inline
void
set_compound_ent_value
(
entity
*
ent
,
ir_node
*
val
,
entity
*
member
,
int
pos
)
{
assert
(
ent
&&
is_compound_entity
(
ent
)
&&
(
ent
->
variability
!=
uninitialized
));
ent
->
values
[
pos
+
1
]
=
val
;
ent
->
val_ents
[
pos
+
1
]
=
member
;
}
inline
int
get_entity_offset
(
entity
*
ent
)
{
return
ent
->
offset
;
...
...
@@ -258,3 +345,15 @@ set_entity_irg(entity *ent, ir_graph *irg) {
assert
(
is_method_type
(
ent
->
type
));
ent
->
irg
=
irg
;
}
int
is_atomic_entity
(
entity
*
ent
)
{
type
*
t
=
ent
->
type
;
return
(
is_primitive_type
(
t
)
||
is_pointer_type
(
t
)
||
is_enumeration_type
(
t
)
||
is_method_type
(
t
));
}
int
is_compound_entity
(
entity
*
ent
)
{
type
*
t
=
ent
->
type
;
return
(
is_class_type
(
t
)
||
is_struct_type
(
t
)
||
is_array_type
(
t
)
||
is_union_type
(
t
));
}
ir/tr/entity.h
View file @
5052f2d2
...
...
@@ -83,6 +83,8 @@ typedef struct ir_graph ir_graph;
* @@@ Does this make sense???
* visibility A flag indicating the visibility of this entity (values: local,
* external_visible, external_allocated)
* variability A flag indicating the variability of this entity (values:
* uninitialized, initalized, part_constant, constant)
* offset The offset of the entity within the compound object. Only set
* if IR in the state "@@@" Wie nennen wir den??
* overwrites A list of entities overwritten by this entity. This list is only
...
...
@@ -167,6 +169,33 @@ typedef enum {
ent_visibility
get_entity_visibility
(
entity
*
ent
);
void
set_entity_visibility
(
entity
*
ent
,
ent_visibility
vis
);
/* This enumeration flags the variability of entities. */
typedef
enum
{
uninitialized
,
/* The content of the entity is completely unknown. */
initialized
,
/* After allocation the entity is initalized with the
value given somewhere in the entity. */
part_constant
,
/* For entities of compound types. Some members of the entity
are constant. The others are uninitialized. Those members
given a value for are constant. */
constant
/* The entity is constant. */
}
ent_variability
;
ent_variability
get_entity_variability
(
entity
*
ent
);
void
set_entity_variability
(
entity
*
ent
,
ent_variability
var
);
/* Set has no effect for entities of type method. */
ir_node
*
get_atomic_ent_value
(
entity
*
ent
);
void
set_atomic_ent_value
(
entity
*
ent
,
ir_node
*
val
);
/* A value of a compound entity is a pair of value and the corresponding member of
the compound. */
void
add_compound_ent_value
(
entity
*
ent
,
ir_node
*
val
,
entity
*
member
);
int
get_compound_ent_n_values
(
entity
*
ent
);
ir_node
*
get_compound_ent_value
(
entity
*
ent
,
int
pos
);
entity
*
get_compound_ent_value_member
(
entity
*
ent
,
int
pos
);
void
set_compound_ent_value
(
entity
*
ent
,
ir_node
*
val
,
entity
*
member
,
int
pos
);
/* Only set if layout = fixed. */
int
get_entity_offset
(
entity
*
ent
);
void
set_entity_offset
(
entity
*
ent
,
int
offset
);
...
...
@@ -193,6 +222,13 @@ ir_graph *get_entity_irg(entity *ent);
void
set_entity_irg
(
entity
*
ent
,
ir_graph
*
irg
);
/* Returns true if the type of the entity is a primitive, pointern
enumeration or method type. */
int
is_atomic_entity
(
entity
*
ent
);
/* Returns true if the type of the entity is a class, structure,
array or union type. */
int
is_compound_entity
(
entity
*
ent
);
/*****/
...
...
ir/tr/entity_t.h
View file @
5052f2d2
...
...
@@ -54,6 +54,10 @@ struct entity {
entities. */
ent_visibility
visibility
;
/* Specifies visibility to external program
fragments */
ent_variability
variability
;
/* Specifies variability of entities content */
ir_node
*
value
;
/* value of atomic entity */
ir_node
**
values
;
/* values of compound entities */
entity
**
val_ents
;
/* entities corresponding to constant values */
int
offset
;
/* Offset in byte for this entity. Fixed when layout
of owner is determined. */
void
*
link
;
/* To store some intermediate information */
...
...
@@ -61,8 +65,8 @@ struct entity {
ir_graph
*
irg
;
/* If (type == method_type) this is the corresponding irg.
The ir_graph constructor automatically sets this field.
@@@ Does this go here, or should it be in type_method,
or should Call have an attribute ent??
*/
/* Do we need to remember the initializer of fields?
*/
or should Call have an attribute ent??
Yes, it must be here.
*/
unsigned
long
visit
;
/* visited counter for walks of the type information */
};
...
...
ir/tr/type.c
View file @
5052f2d2
...
...
@@ -37,6 +37,9 @@
# include "tpop_t.h"
# include "typegmod_t.h"
# include "array.h"
# include "irprog.h"
# include "mangle.h"
# include "tv.h"
/*******************************************************************/
/** TYPE **/
...
...
@@ -529,6 +532,19 @@ int get_array_n_dimensions (type *array) {
assert
(
array
&&
(
array
->
type_op
==
type_array
));
return
array
->
attr
.
aa
.
n_dimensions
;
}
void
set_array_bounds_int
(
type
*
array
,
int
dimension
,
int
lower_bound
,
int
upper_bound
)
{
ir_graph
*
rem
;
assert
(
array
&&
(
array
->
type_op
==
type_array
));
rem
=
current_ir_graph
;
current_ir_graph
=
get_const_code_irg
();
array
->
attr
.
aa
.
lower_bound
[
dimension
]
=
new_Const
(
mode_I
,
tarval_from_long
(
mode_I
,
lower_bound
));
array
->
attr
.
aa
.
upper_bound
[
dimension
]
=
new_Const
(
mode_I
,
tarval_from_long
(
mode_I
,
upper_bound
));
current_ir_graph
=
rem
;
}
void
set_array_bounds
(
type
*
array
,
int
dimension
,
ir_node
*
lower_bound
,
ir_node
*
upper_bound
)
{
assert
(
array
&&
(
array
->
type_op
==
type_array
));
...
...
@@ -679,3 +695,12 @@ bool is_primitive_type (type *primitive) {
assert
(
primitive
);
if
(
primitive
->
type_op
==
type_primitive
)
return
1
;
else
return
0
;
}
int
is_atomic_type
(
type
*
tp
)
{
return
(
is_primitive_type
(
tp
)
||
is_pointer_type
(
tp
)
||
is_enumeration_type
(
tp
));
}
int
is_compound_type
(
type
*
tp
)
{
return
(
is_class_type
(
tp
)
||
is_struct_type
(
tp
)
||
is_array_type
(
tp
)
||
is_union_type
(
tp
));
}
ir/tr/type.h
View file @
5052f2d2
...
...
@@ -381,6 +381,8 @@ void set_union_delim_nameid (type *uni, int pos, ident *id);
* Representation of an array type.
* NOTE
* The array type represents rectangular multi dimensional arrays.
* The constants representing the bounds must be allocated to
* get_const_code_irg() by setting current_ir_graph accordingly.
* ATTRIBUTES
* n_dimensions Number of array dimensions.
* *lower_bound Lower bounds of dimensions. Usually all 0.
...
...
@@ -401,6 +403,9 @@ type *new_type_array (ident *name, int n_dimensions,
/* manipulate private fields of array type */
int
get_array_n_dimensions
(
type
*
array
);
/* Allocates Const nodes of mode_I for the array dimensions */
void
set_array_bounds_int
(
type
*
array
,
int
dimension
,
int
lower_bound
,
int
upper_bound
);
void
set_array_bounds
(
type
*
array
,
int
dimension
,
ir_node
*
lower_bound
,
ir_node
*
upper_bound
);
void
set_array_lower_bound
(
type
*
array
,
int
dimension
,
ir_node
*
lower_bound
);
...
...
@@ -486,4 +491,34 @@ type *new_type_primitive (ident *name, ir_mode *mode);
bool
is_primitive_type
(
type
*
primitive
);
/*****/
/****f* type/is_atomic_type
*
* NAME
* is_atomic_type - Checks whether a type is atomic.
* SYNOPSIS
* int is_atomic_type(type *tp);
* INPUTS
* tp - any type
* RESULT
* true if type is primitive, pointer or enumeration
***
*/
int
is_atomic_type
(
type
*
tp
);
/****f* type/is_compound_type
*
* NAME
* is_compound_type - Checks whether a type is compound.
* SYNOPSIS
* int is_compound_type(type *tp)
* INPUTS
* tp - any type