1 /*
2  * Copyright 2011      Leiden University. All rights reserved.
3  * Copyright 2013-2015 Ecole Normale Superieure. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *    1. Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *
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.
16  *
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.
28  *
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
32  * Leiden University.
33  */
34 
35 #include <clang/AST/ASTContext.h>
36 #include <clang/AST/Decl.h>
37 #include <clang/AST/Type.h>
38 
39 #include <isl/aff.h>
40 #include <isl/id.h>
41 
42 #include "clang.h"
43 #include "expr.h"
44 #include "expr_plus.h"
45 #include "id.h"
46 
47 using namespace clang;
48 
49 /* Return the depth of the array accessed by the index expression "index".
50  * If "index" is an affine expression, i.e., if it does not access
51  * any array, then return 1.
52  * If "index" represent a member access, i.e., if its range is a wrapped
53  * relation, then return the sum of the depth of the array of structures
54  * and that of the member inside the structure.
55  */
extract_depth(__isl_keep isl_multi_pw_aff * index)56 static int extract_depth(__isl_keep isl_multi_pw_aff *index)
57 {
58 	isl_id *id;
59 	QualType qt;
60 
61 	if (!index)
62 		return -1;
63 
64 	if (isl_multi_pw_aff_range_is_wrapping(index)) {
65 		int domain_depth, range_depth;
66 		isl_multi_pw_aff *domain, *range;
67 
68 		domain = isl_multi_pw_aff_copy(index);
69 		domain = isl_multi_pw_aff_range_factor_domain(domain);
70 		domain_depth = extract_depth(domain);
71 		isl_multi_pw_aff_free(domain);
72 		range = isl_multi_pw_aff_copy(index);
73 		range = isl_multi_pw_aff_range_factor_range(range);
74 		range_depth = extract_depth(range);
75 		isl_multi_pw_aff_free(range);
76 
77 		return domain_depth + range_depth;
78 	}
79 
80 	if (!isl_multi_pw_aff_has_tuple_id(index, isl_dim_out))
81 		return 1;
82 
83 	id = isl_multi_pw_aff_get_tuple_id(index, isl_dim_out);
84 	if (!id)
85 		return -1;
86 	qt = pet_id_get_array_type(id);
87 	isl_id_free(id);
88 
89 	return pet_clang_array_depth(qt);
90 }
91 
92 /* Return the depth of the array accessed by the access expression "expr".
93  */
extract_depth(__isl_keep pet_expr * expr)94 static int extract_depth(__isl_keep pet_expr *expr)
95 {
96 	isl_multi_pw_aff *index;
97 	int depth;
98 
99 	index = pet_expr_access_get_index(expr);
100 	depth = extract_depth(index);
101 	isl_multi_pw_aff_free(index);
102 
103 	return depth;
104 }
105 
106 /* Convert the index expression "index" into an access pet_expr of type "qt".
107  */
pet_expr_access_from_index(QualType qt,__isl_take pet_expr * index,ASTContext & ast_context)108 __isl_give pet_expr *pet_expr_access_from_index(QualType qt,
109 	__isl_take pet_expr *index, ASTContext &ast_context)
110 {
111 	int depth;
112 	int type_size;
113 
114 	depth = extract_depth(index);
115 	type_size = pet_clang_get_type_size(qt, ast_context);
116 
117 	index = pet_expr_set_type_size(index, type_size);
118 	index = pet_expr_access_set_depth(index, depth);
119 
120 	return index;
121 }
122 
123 /* Construct an access pet_expr for an access
124  * to the variable represented by "id".
125  */
pet_expr_access_from_id(__isl_take isl_id * id,ASTContext & ast_context)126 __isl_give pet_expr *pet_expr_access_from_id(__isl_take isl_id *id,
127 	ASTContext &ast_context)
128 {
129 	QualType qt;
130 	pet_expr *expr;
131 
132 	qt = pet_id_get_array_type(id);
133 	expr = pet_id_create_index_expr(id);
134 	return pet_expr_access_from_index(qt, expr, ast_context);
135 }
136