2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2015 Sven Verdoolaege. 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
41 using namespace clang
;
43 /* Add an assignment of "expr" to a variable with identifier "id" and
44 * type "qt" and return a pet_expr corresponding to the assigned variable.
46 __isl_give pet_expr
*pet_inliner::assign( __isl_take isl_id
*id
, QualType qt
,
47 __isl_take pet_expr
*expr
)
52 var
= pet_id_create_index_expr(id
);
53 type_size
= pet_clang_get_type_size(qt
, ast_context
);
54 var
= pet_expr_set_type_size(var
, type_size
);
56 assignments
.push_back(pair
<pet_expr
*, pet_expr
*>(var
, expr
));
58 return pet_expr_copy(var
);
61 /* Add a scalar argument to the inliner.
62 * "decl" is the declaration of the formal argument.
63 * "name" is the name that should be used in the assignment before
65 * "expr" is the actual argument.
67 * Create an identifier called "name" referring to "decl".
68 * Assign it the value of "expr" and keep track of
69 * the substitution of the identifier corresponding to "decl" by
70 * the expression that is assigned the value.
72 void pet_inliner::add_scalar_arg(ValueDecl
*decl
, const string
&name
,
73 __isl_take pet_expr
*expr
)
75 QualType type
= decl
->getType();
79 id
= pet_id_from_name_and_decl(ctx
, name
.c_str(), decl
);
80 var
= assign(id
, type
, expr
);
81 id
= pet_id_from_decl(ctx
, decl
);
85 /* Add an array argument to the inliner.
86 * "decl" is the declaration of the formal argument.
87 * "expr" is the actual argument and is and access expression.
88 * "is_addr" is set if it is the address of "expr" that is passed
91 * Create identifiers for the arguments of "expr".
92 * Assign each of them the value of the corresponding argument and
93 * replace the argument by the expression that is assigned the value.
94 * Keep track of the substitution of the identifier corresponding
95 * to "decl" by the resulting expression.
97 void pet_inliner::add_array_arg(ValueDecl
*decl
, __isl_take pet_expr
*expr
,
102 for (unsigned j
= 0; j
< expr
->n_arg
; ++j
) {
104 QualType type
= ast_context
.IntTy
;
106 id
= pet_id_arg_from_type(ctx
, n_arg
++, type
);
107 var
= assign(id
, type
, pet_expr_copy(expr
->args
[j
]));
108 expr
= pet_expr_set_arg(expr
, j
, var
);
111 expr
= pet_expr_new_unary(0, pet_op_address_of
, expr
);
112 id
= pet_id_from_decl(ctx
, decl
);
116 /* Inline "tree" by applying the substitutions to "tree" and placing
117 * the result in a block after the assignments stored in "assignments".
119 __isl_give pet_tree
*pet_inliner::inline_tree(__isl_take pet_tree
*tree
)
123 int n
= assignments
.size() + 1;
125 block
= pet_tree_new_block(ctx
, 1, n
);
127 for (unsigned i
= 0; i
< assignments
.size(); ++i
) {
130 expr
= pet_expr_copy(assignments
[i
].first
);
131 expr
= pet_expr_access_set_write(expr
, 1);
132 expr
= pet_expr_access_set_read(expr
, 0);
133 tree_i
= pet_tree_new_decl_init(expr
,
134 pet_expr_copy(assignments
[i
].second
));
135 block
= pet_tree_block_add_child(block
, tree_i
);
138 tree
= substitute(tree
);
139 block
= pet_tree_block_add_child(block
, tree
);
144 /* Free all elements in the assignments.
146 pet_inliner::~pet_inliner()
148 std::vector
<std::pair
<pet_expr
*, pet_expr
*> >::iterator it
;
150 for (it
= assignments
.begin(); it
!= assignments
.end(); ++it
) {
151 pet_expr_free(it
->first
);
152 pet_expr_free(it
->second
);