2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013 Ecole Normale Superieure. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
40 #include "scop_plus.h"
44 using namespace clang
;
46 /* And the sequence of nested arrays of structures "ancestors"
47 * to "arrays". The final element in the sequence may be a leaf
48 * and may therefore refer to a primitive type rather than a record type.
50 * Futhermore, if the innermost array in the sequence is an array of structures
51 * then recursively call collect_sub_arrays for all subfields of this
54 static void collect_sub_arrays(ValueDecl
*decl
, vector
<ValueDecl
*> ancestors
,
55 array_desc_set
&arrays
)
57 QualType type
= decl
->getType();
59 RecordDecl::field_iterator it
;
61 arrays
.insert(ancestors
);
63 type
= pet_clang_base_type(type
);
65 if (!type
->isRecordType())
68 record
= pet_clang_record_decl(type
);
70 for (it
= record
->field_begin(); it
!= record
->field_end(); ++it
) {
71 FieldDecl
*field
= *it
;
72 bool anonymous
= field
->isAnonymousStructOrUnion();
75 ancestors
.push_back(field
);
76 collect_sub_arrays(field
, ancestors
, arrays
);
82 /* Extract one or more sequences of declarations from the access expression
83 * "expr" and them to "arrays".
85 * If "expr" represents an array access, then the extracted sequence
86 * contains a single element corresponding to the array declaration.
87 * Otherwise, if "expr" represents a member access, then the extracted
88 * sequences contain an element for the outer array of structures and
89 * for each nested array or scalar. One such sequence is (recursively)
90 * added for each member of the accessed outer array.
92 * If the array being accessed has a NULL ValueDecl, then it
93 * is a virtual scalar. We don't need to collect such scalars
94 * because they are added to the scop of the statement writing
97 static void access_collect_arrays(__isl_keep pet_expr
*expr
,
98 array_desc_set
&arrays
)
103 vector
<ValueDecl
*> ancestors
;
105 if (pet_expr_is_affine(expr
))
108 space
= pet_expr_access_get_data_space(expr
);
110 while (space
&& isl_space_is_wrapping(space
))
111 space
= isl_space_domain(isl_space_unwrap(space
));
113 id
= isl_space_get_tuple_id(space
, isl_dim_set
);
114 isl_space_free(space
);
118 decl
= (ValueDecl
*)isl_id_get_user(id
);
124 ancestors
.push_back(decl
);
125 collect_sub_arrays(decl
, ancestors
, arrays
);
128 static void expr_collect_arrays(__isl_keep pet_expr
*expr
,
129 array_desc_set
&arrays
)
136 n
= pet_expr_get_n_arg(expr
);
137 for (int i
= 0; i
< n
; ++i
) {
140 arg
= pet_expr_get_arg(expr
, i
);
141 expr_collect_arrays(arg
, arrays
);
145 if (pet_expr_get_type(expr
) == pet_expr_access
)
146 access_collect_arrays(expr
, arrays
);
149 /* Wrapper around access_collect_arrays for use as a callback function
150 * to pet_tree_foreach_access_expr.
152 static int access_collect_wrap(__isl_keep pet_expr
*expr
, void *user
)
154 array_desc_set
*arrays
= (array_desc_set
*) user
;
156 access_collect_arrays(expr
, *arrays
);
161 static void stmt_collect_arrays(struct pet_stmt
*stmt
,
162 array_desc_set
&arrays
)
167 for (int i
= 0; i
< stmt
->n_arg
; ++i
)
168 expr_collect_arrays(stmt
->args
[i
], arrays
);
170 pet_tree_foreach_access_expr(stmt
->body
, &access_collect_wrap
, &arrays
);
173 /* Collect the set of all accessed arrays (or scalars) in "scop",
174 * except those that already appear in scop->arrays,
175 * and put them in "arrays".
177 * Each accessed array is represented by a sequence of nested
178 * array declarations, one for the outer array of structures
179 * and one for each member access.
181 * The arrays that already appear in scop->arrays are assumed
182 * to be simple arrays, represented by a sequence of a single element.
184 void pet_scop_collect_arrays(struct pet_scop
*scop
,
185 array_desc_set
&arrays
)
190 for (int i
= 0; i
< scop
->n_stmt
; ++i
)
191 stmt_collect_arrays(scop
->stmts
[i
], arrays
);
193 for (int i
= 0; i
< scop
->n_array
; ++i
) {
195 vector
<ValueDecl
*> ancestors
;
197 isl_id
*id
= isl_set_get_tuple_id(scop
->arrays
[i
]->extent
);
198 decl
= (ValueDecl
*)isl_id_get_user(id
);
204 ancestors
.push_back(decl
);
206 arrays
.erase(ancestors
);