pet_scop_from_pet_stmt: fix error handling
[pet.git] / inliner.cc
blob6ae651c669d4eaf0a9f22fcc384ed824b61558fc
1 /*
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
7 * are met:
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
32 * Leiden University.
35 #include "clang.h"
36 #include "expr.h"
37 #include "id.h"
38 #include "inliner.h"
40 using namespace std;
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)
49 int type_size;
50 pet_expr *var;
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
64 * the inlined tree.
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();
76 isl_id *id;
77 pet_expr *var;
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);
82 add_sub(id, var);
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
89 * as an argument.
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,
98 int is_addr)
100 isl_id *id;
102 for (unsigned j = 0; j < expr->n_arg; ++j) {
103 pet_expr *var;
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);
110 if (is_addr)
111 expr = pet_expr_new_unary(0, pet_op_address_of, expr);
112 id = pet_id_from_decl(ctx, decl);
113 add_sub(id, expr);
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)
121 pet_expr *expr;
122 pet_tree *block;
123 int n = assignments.size() + 1;
125 block = pet_tree_new_block(ctx, 1, n);
127 for (unsigned i = 0; i < assignments.size(); ++i) {
128 pet_tree *tree_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);
141 return block;
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);