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
e26d4611
Commit
e26d4611
authored
Feb 28, 1993
by
Richard Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r3569
parent
41424fdd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
113 additions
and
113 deletions
+113
-113
gcc/c-iterate.c
+113
-113
No files found.
gcc/c-iterate.c
View file @
e26d4611
...
@@ -27,6 +27,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -27,6 +27,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "tree.h"
#include "tree.h"
#include "c-tree.h"
#include "c-tree.h"
#include "flags.h"
#include "flags.h"
#include "obstack.h"
#include "rtl.h"
static
void
expand_stmt_with_iterators_1
();
static
void
expand_stmt_with_iterators_1
();
static
tree
collect_iterators
();
static
tree
collect_iterators
();
...
@@ -36,29 +38,96 @@ static void add_ixpansion ();
...
@@ -36,29 +38,96 @@ static void add_ixpansion ();
static
void
delete_ixpansion
();
static
void
delete_ixpansion
();
static
int
top_level_ixpansion_p
();
static
int
top_level_ixpansion_p
();
static
void
istack_sublevel_to_current
();
static
void
istack_sublevel_to_current
();
/* A special obstack, and a pointer to the start of
all the data in it (so we can free everything easily). */
static
struct
obstack
ixp_obstack
;
static
char
*
ixp_firstobj
;
void
/*
iterator_for_loop_start
(
idecl
)
KEEPING TRACK OF EXPANSIONS
tree
idecl
;
In order to clean out expansions corresponding to statements inside
"{(...)}" constructs we have to keep track of all expansions. The
cleanup is needed when an automatic, or implicit, expansion on
iterator, say X, happens to a statement which contains a {(...)}
form with a statement already expanded on X. In this case we have
to go back and cleanup the inner expansion. This can be further
complicated by the fact that {(...)} can be nested.
To make this cleanup possible, we keep lists of all expansions, and
to make it work for nested constructs, we keep a stack. The list at
the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the
currently parsed level. All expansions of the levels below the
current one are kept in one list whose head is pointed to by
ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges
easy). The process works as follows:
-- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK.
The sublevel list is not changed at this point.
-- On "})" the list for the current level is appended to the sublevel
list.
-- On ";" sublevel lists are appended to the current level lists.
The reason is this: if they have not been superseded by the
expansion at the current level, they still might be
superseded later by the expansion on the higher level.
The levels do not have to distinguish levels below, so we
can merge the lists together. */
struct
ixpansion
{
{
iterator_loop_prologue
(
idecl
,
0
,
0
);
tree
ixdecl
;
/* Iterator decl */
}
rtx
ixprologue_start
;
/* First insn of epilogue. NULL means */
/* explicit (FOR) expansion*/
rtx
ixprologue_end
;
rtx
ixepilogue_start
;
rtx
ixepilogue_end
;
struct
ixpansion
*
next
;
/* Next in the list */
};
struct
iter_stack_node
{
struct
ixpansion
*
first
;
/* Head of list of ixpansions */
struct
ixpansion
*
last
;
/* Last node in list of ixpansions */
struct
iter_stack_node
*
next
;
/* Next level iterator stack node */
};
struct
iter_stack_node
*
iter_stack
;
struct
iter_stack_node
sublevel_ixpansions
;
/* Initialize our obstack once per compilation. */
void
void
iterator_for_loop_end
(
idecl
)
init_iterators
()
tree
idecl
;
{
{
iterator_loop_epilogue
(
idecl
,
0
,
0
);
gcc_obstack_init
(
&
ixp_obstack
);
ixp_firstobj
=
(
char
*
)
obstack_alloc
(
&
ixp_obstack
,
0
);
}
}
/* Handle the start of an explicit `for' loop for iterator IDECL. */
void
void
iterator_for_loop_
record
(
idecl
)
iterator_for_loop_
start
(
idecl
)
tree
idecl
;
tree
idecl
;
{
{
ITERATOR_BOUND_P
(
idecl
)
=
1
;
add_ixpansion
(
idecl
,
0
,
0
,
0
,
0
);
add_ixpansion
(
idecl
,
0
,
0
,
0
,
0
);
iterator_loop_prologue
(
idecl
,
0
,
0
);
}
}
/* Handle the end of an explicit `for' loop for iterator IDECL. */
void
iterator_for_loop_end
(
idecl
)
tree
idecl
;
{
iterator_loop_epilogue
(
idecl
,
0
,
0
);
ITERATOR_BOUND_P
(
idecl
)
=
0
;
}
/*
/*
ITERATOR DECLS
ITERATOR DECLS
...
@@ -100,16 +169,14 @@ build_iterator_decl (id, limit)
...
@@ -100,16 +169,14 @@ build_iterator_decl (id, limit)
/*
/*
ITERATOR RTL EXPANSIONS
ITERATOR RTL EXPANSIONS
Expanding simple statements with iterators is pretty straightforward:
Expanding simple statements with iterators is straightforward:
collect (collect_iterators) the list of all "free" iterators in the
collect the list of all free iterators in the statement, and
statement and for each of them add a special prologue before and an
generate a loop for each of them.
epilogue after the expansion for the statement. Iterator is "free" if
it has not been "bound" by a FOR operator. The rtx associated with the
An iterator is "free" if it has not been "bound" by a FOR
iterator's decl is used as the loop counter. Special processing is
operator. The DECL_RTL of the iterator is the loop counter. */
used for "{(...)}" constructs: each iterator expansion is registered
(by "add_ixpansion" function) and inner expansions are superseded by
/* Expand a statement STMT, possibly containing iterator usage, into RTL. */
outer ones. The cleanup of superseded expansions is done by a call to
delete_ixpansion. */
void
void
iterator_expand
(
stmt
)
iterator_expand
(
stmt
)
...
@@ -146,9 +213,9 @@ expand_stmt_with_iterators_1 (stmt, iter_list)
...
@@ -146,9 +213,9 @@ expand_stmt_with_iterators_1 (stmt, iter_list)
}
}
/* Return a list containing all the free (i.e. not bound by
"for"
/* Return a list containing all the free (i.e. not bound by
a
statement or anaccumulator) iterators mentioned in EXP,
containing `for' statement) iterators mentioned in EXP, plus those
plus those in LIST. Duplicates are avoided
. */
in LIST. Do not add duplicate entries to the list
. */
static
tree
static
tree
collect_iterators
(
exp
,
list
)
collect_iterators
(
exp
,
list
)
...
@@ -238,17 +305,18 @@ iterator_loop_prologue (idecl, start_note, end_note)
...
@@ -238,17 +305,18 @@ iterator_loop_prologue (idecl, start_note, end_note)
DECL_RTL is zeroed unless we are inside "({...})". The reason for that is
DECL_RTL is zeroed unless we are inside "({...})". The reason for that is
described below.
described below.
When we create two (or more) loops based on the same IDECL, and both
When we create two (or more) loops based on the same IDECL, and
inside the same "({...})" construct, we must be prepared to delete
both inside the same "({...})" construct, we must be prepared to
both of the loops and create a single one on the level above, i.e.
delete both of the loops and create a single one on the level
enclosing the "({...})". The new loop has to use the same counter rtl
above, i.e. enclosing the "({...})". The new loop has to use the
because the references to the iterator decl (IDECL) have already been
same counter rtl because the references to the iterator decl
expanded as references to the counter rtl.
(IDECL) have already been expanded as references to the counter
rtl.
It is incorrect to use the same counter reg in different functions,
It is incorrect to use the same counter reg in different functions,
and it is desirable to use different counters in disjoint loops
and it is desirable to use different counters in disjoint loops
when we know there's no need to combine them
when we know there's no need to combine them
(because then they can
(because then they can
get allocated separately). */
get allocated separately). */
static
void
static
void
iterator_loop_epilogue
(
idecl
,
start_note
,
end_note
)
iterator_loop_epilogue
(
idecl
,
start_note
,
end_note
)
...
@@ -275,65 +343,7 @@ iterator_loop_epilogue (idecl, start_note, end_note)
...
@@ -275,65 +343,7 @@ iterator_loop_epilogue (idecl, start_note, end_note)
*
end_note
=
emit_note
(
0
,
NOTE_INSN_DELETED
);
*
end_note
=
emit_note
(
0
,
NOTE_INSN_DELETED
);
}
}
/*
/* Return true if we are not currently inside a "({...})" construct. */
KEEPING TRACK OF EXPANSIONS
In order to clean out expansions corresponding to statements inside
"{(...)}" constructs we have to keep track of all expansions. The
cleanup is needed when an automatic, or implicit, expansion on
iterator, say X, happens to a statement which contains a {(...)}
form with a statement already expanded on X. In this case we have
to go back and cleanup the inner expansion. This can be further
complicated by the fact that {(...)} can be nested.
To make this cleanup possible, we keep lists of all expansions, and
to make it work for nested constructs, we keep a stack. The list at
the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the
currently parsed level. All expansions of the levels below the
current one are kept in one list whose head is pointed to by
ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges
easy). The process works as follows:
-- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK.
The sublevel list is not changed at this point.
-- On "})" the list for the current level is appended to the sublevel
list.
-- On ";" sublevel lists are appended to the current level lists.
The reason is this: if they have not been superseded by the
expansion at the current level, they still might be
superseded later by the expansion on the higher level.
The levels do not have to distinguish levels below, so we
can merge the lists together. */
struct
ixpansion
{
tree
ixdecl
;
/* Iterator decl */
rtx
ixprologue_start
;
/* First insn of epilogue. NULL means */
/* explicit (FOR) expansion*/
rtx
ixprologue_end
;
rtx
ixepilogue_start
;
rtx
ixepilogue_end
;
struct
ixpansion
*
next
;
/* Next in the list */
};
static
struct
obstack
ixp_obstack
;
static
char
*
ixp_firstobj
;
struct
iter_stack_node
{
struct
ixpansion
*
first
;
/* Head of list of ixpansions */
struct
ixpansion
*
last
;
/* Last node in list of ixpansions */
struct
iter_stack_node
*
next
;
/* Next level iterator stack node */
};
struct
iter_stack_node
*
iter_stack
;
struct
iter_stack_node
sublevel_ixpansions
;
/** Return true if we are not currently inside a "({...})" construct */
static
int
static
int
top_level_ixpansion_p
()
top_level_ixpansion_p
()
...
@@ -495,33 +505,22 @@ delete_ixpansion (idecl)
...
@@ -495,33 +505,22 @@ delete_ixpansion (idecl)
previx
=
ix
;
previx
=
ix
;
}
}
/*
We initialize iterators obstack once per file
*/
init_iterators
()
{
gcc_obstack_init
(
&
ixp_obstack
);
ixp_firstobj
=
(
char
*
)
obstack_alloc
(
&
ixp_obstack
,
0
);
}
#ifdef DEBUG_ITERATORS
#ifdef DEBUG_ITERATORS
/*
/*
The functions below are for use from source level debugger.
The functions below are for use from source level debugger.
They print short forms of iterator lists and the iterator stack. */
They print short forms of iterator lists and the iterator stack.
*/
/* Print the name of the iterator D.
*/
/* Print the name of the iterator D */
void
void
PRDECL
(
D
)
prdecl
(
d
)
tree
D
;
tree
d
;
{
{
if
(
D
)
if
(
d
)
{
{
if
(
TREE_CODE
(
D
)
==
VAR_DECL
)
if
(
TREE_CODE
(
d
)
==
VAR_DECL
)
{
{
tree
tname
=
DECL_NAME
(
D
);
tree
tname
=
DECL_NAME
(
d
);
char
*
dname
=
IDENTIFIER_POINTER
(
tname
);
char
*
dname
=
IDENTIFIER_POINTER
(
tname
);
fprintf
(
stderr
,
dname
);
fprintf
(
stderr
,
dname
);
}
}
...
@@ -539,10 +538,10 @@ pil (head)
...
@@ -539,10 +538,10 @@ pil (head)
tree
head
;
tree
head
;
{
{
tree
current
,
next
;
tree
current
,
next
;
for
(
current
=
head
;
current
;
current
=
next
)
for
(
current
=
head
;
current
;
current
=
next
)
{
{
tree
node
=
TREE_VALUE
(
current
);
tree
node
=
TREE_VALUE
(
current
);
PRDECL
(
node
);
prdecl
(
node
);
next
=
TREE_CHAIN
(
current
);
next
=
TREE_CHAIN
(
current
);
if
(
next
)
fprintf
(
stderr
,
","
);
if
(
next
)
fprintf
(
stderr
,
","
);
}
}
...
@@ -563,7 +562,7 @@ pixl (head)
...
@@ -563,7 +562,7 @@ pixl (head)
for
(
current
=
head
;
current
;
current
=
next
)
for
(
current
=
head
;
current
;
current
=
next
)
{
{
tree
node
=
current
->
ixdecl
;
tree
node
=
current
->
ixdecl
;
PRDECL
(
node
);
prdecl
(
node
);
next
=
current
->
next
;
next
=
current
->
next
;
if
(
next
)
if
(
next
)
fprintf
(
stderr
,
","
);
fprintf
(
stderr
,
","
);
...
@@ -587,4 +586,5 @@ pis ()
...
@@ -587,4 +586,5 @@ pis ()
stack_node
=
stack_node
->
next
)
stack_node
=
stack_node
->
next
)
pixl
(
stack_node
->
first
);
pixl
(
stack_node
->
first
);
}
}
#endif
#endif
/* DEBUG_ITERATORS */
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