From e8523b640e005cc2c029f2f742c9c382ddf259e0 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 27 Jan 2014 19:23:50 +0100 Subject: [PATCH] introduce pet_loc There are currently two places where location information is stored. We store the line number in a pet_stmt and the start and end offsets in a pet_scop. This information is extracted directly from the clang AST. In future, we want to extract a pet_scop from an intermediate pet_tree so we need to attach both pieces of information to a pet_tree. Combine these two pieces of information into a pet_loc. Signed-off-by: Sven Verdoolaege --- Makefile.am | 2 + emit.c | 12 ++-- include/pet.h | 33 +++++++--- loc.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ loc.h | 25 ++++++++ parse.c | 15 ++++- pet.cc | 6 +- scan.cc | 34 +++++----- scan.h | 5 +- scop.c | 96 ++++++++++++++++++++-------- scop.h | 8 ++- skip.c | 5 +- 12 files changed, 377 insertions(+), 66 deletions(-) create mode 100644 loc.c create mode 100644 loc.h diff --git a/Makefile.am b/Makefile.am index 5324d26..f29a019 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,8 @@ libpet_la_SOURCES = \ expr_arg.c \ filter.h \ filter.c \ + loc.h \ + loc.c \ nest.h \ nest.c \ options.h \ diff --git a/emit.c b/emit.c index 37da991..8ae46df 100644 --- a/emit.c +++ b/emit.c @@ -1,6 +1,6 @@ /* - * Copyright 2011 Leiden University. All rights reserved. - * Copyright 2013 Ecole Normale Superieure. All rights reserved. + * Copyright 2011 Leiden University. All rights reserved. + * Copyright 2013-2014 Ecole Normale Superieure. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,6 +35,7 @@ #include #include "expr.h" +#include "loc.h" #include "scop.h" #include "scop_yaml.h" @@ -506,7 +507,7 @@ static int emit_stmt(yaml_emitter_t *emitter, struct pet_stmt *stmt) if (emit_string(emitter, "line") < 0) return -1; - if (emit_int(emitter, stmt->line) < 0) + if (emit_int(emitter, pet_loc_get_line(stmt->loc)) < 0) return -1; if (emit_string(emitter, "domain") < 0) @@ -647,9 +648,10 @@ static int emit_scop(yaml_emitter_t *emitter, struct pet_scop *scop) if (!yaml_emitter_emit(emitter, &event)) return -1; - if (emit_named_unsigned(emitter, "start", scop->start) < 0) + if (emit_named_unsigned(emitter, + "start", pet_loc_get_start(scop->loc)) < 0) return -1; - if (emit_named_unsigned(emitter, "end", scop->end) < 0) + if (emit_named_unsigned(emitter, "end", pet_loc_get_end(scop->loc)) < 0) return -1; if (emit_string(emitter, "context") < 0) return -1; diff --git a/include/pet.h b/include/pet.h index 12bab46..8380e7c 100644 --- a/include/pet.h +++ b/include/pet.h @@ -31,6 +31,21 @@ int pet_options_get_detect_conditional_assignment(isl_ctx *ctx); int pet_options_set_signed_overflow(isl_ctx *ctx, int val); int pet_options_get_signed_overflow(isl_ctx *ctx); +struct pet_loc; +typedef struct pet_loc pet_loc; + +/* Return an additional reference to "loc". */ +__isl_give pet_loc *pet_loc_copy(__isl_keep pet_loc *loc); +/* Free a reference to "loc". */ +pet_loc *pet_loc_free(__isl_take pet_loc *loc); + +/* Return the offset in the input file of the start of "loc". */ +unsigned pet_loc_get_start(__isl_keep pet_loc *loc); +/* Return the offset in the input file of the character after "loc". */ +unsigned pet_loc_get_end(__isl_keep pet_loc *loc); +/* Return the line number of a line within the "loc" region. */ +int pet_loc_get_line(__isl_keep pet_loc *loc); + enum pet_expr_type { pet_expr_error = -1, pet_expr_access, @@ -200,7 +215,10 @@ int pet_expr_foreach_call_expr(__isl_keep pet_expr *expr, void pet_expr_dump(__isl_keep pet_expr *expr); -/* If the statement has arguments, i.e., n_arg != 0, then +/* "loc" represents the region of the source code that is represented + * by this statement. + * + * If the statement has arguments, i.e., n_arg != 0, then * "domain" is a wrapped map, mapping the iteration domain * to the values of the arguments for which this statement * is executed. @@ -212,7 +230,7 @@ void pet_expr_dump(__isl_keep pet_expr *expr); * for all of those accessed elements. */ struct pet_stmt { - int line; + pet_loc *loc; isl_set *domain; isl_map *schedule; pet_expr *body; @@ -312,12 +330,10 @@ struct pet_implication { isl_map *extension; }; -/* The start and end fields contain the offsets in the input file - * of the scop, where end points to the first character after the scop. +/* "loc" represents the region of the source code that is represented + * by this scop. * If the scop was detected based on scop and endscop pragmas, then - * the lines containing these pragmas are included in this range. - * Internally, end may be zero to indicate that no offset information is - * available (yet). + * the lines containing these pragmas are included in this region. * The context describes the set of parameter values for which * the scop can be executed. * context_value describes assignments to the parameters (if any) @@ -328,8 +344,7 @@ struct pet_implication { * The n_implication implications describe implications on boolean filters. */ struct pet_scop { - unsigned start; - unsigned end; + pet_loc *loc; isl_set *context; isl_set *context_value; diff --git a/loc.c b/loc.c new file mode 100644 index 0000000..42ecd32 --- /dev/null +++ b/loc.c @@ -0,0 +1,202 @@ +/* + * Copyright 2011 Leiden University. All rights reserved. + * Copyright 2014 Ecole Normale Superieure. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Leiden University. + */ + +#include + +#include "loc.h" + +/* A pet_loc object represents a region of the input file. + * The "start" and "end" fields contain the offsets in the input file + * of the region, where end points to the first character after the region. + * "line" is the line number of a line inside the region. + * + * A special pet_loc_dummy instance is used to indicate that + * no offset information is available (yet). + */ +struct pet_loc { + int ref; + isl_ctx *ctx; + + unsigned start; + unsigned end; + int line; +}; + +/* A special pet_loc object that is used to indicate that + * no region information is available yet. + * + * This special pet_loc object cannot be changed. + * In particular, it is not allowed to call pet_loc_cow on this object. + */ +pet_loc pet_loc_dummy = { + .ref = -1, + .ctx = NULL, + .start = 0, + .end = 0, + .line = -1, +}; + +/* Allocate a pet_loc with the given start, end and line number. + */ +__isl_give pet_loc *pet_loc_alloc(isl_ctx *ctx, + unsigned start, unsigned end, int line) +{ + pet_loc *loc; + + loc = isl_alloc_type(ctx, struct pet_loc); + if (!loc) + return NULL; + + loc->ctx = ctx; + isl_ctx_ref(ctx); + loc->ref = 1; + + loc->start = start; + loc->end = end; + loc->line = line; + + return loc; +} + +/* Return a pet_loc that is equal to "loc" and that has only one reference. + * + * It is not allowed to call pet_loc_cow on pet_loc_dummy. + * We cannot raise an error in this case because pet_loc_dummy does + * not have a reference to a valid isl_ctx. + */ +__isl_give pet_loc *pet_loc_cow(__isl_take pet_loc *loc) +{ + if (loc == &pet_loc_dummy) + return NULL; + if (!loc) + return NULL; + + if (loc->ref == 1) + return loc; + loc->ref--; + return pet_loc_alloc(loc->ctx, loc->start, loc->end, loc->line); +} + +/* Return an extra reference to "loc". + * + * The special pet_loc_dummy object is not reference counted. + */ +__isl_give pet_loc *pet_loc_copy(__isl_keep pet_loc *loc) +{ + if (loc == &pet_loc_dummy) + return loc; + + if (!loc) + return NULL; + + loc->ref++; + return loc; +} + +/* Free a reference to "loc" and return NULL. + * + * The special pet_loc_dummy object is not reference counted. + */ +__isl_null pet_loc *pet_loc_free(__isl_take pet_loc *loc) +{ + if (loc == &pet_loc_dummy) + return NULL; + if (!loc) + return NULL; + if (--loc->ref > 0) + return NULL; + + isl_ctx_deref(loc->ctx); + free(loc); + return NULL; +} + +/* Return the offset in the input file of the start of "loc". + */ +unsigned pet_loc_get_start(__isl_keep pet_loc *loc) +{ + return loc ? loc->start : 0; +} + +/* Return the offset in the input file of the character after "loc". + */ +unsigned pet_loc_get_end(__isl_keep pet_loc *loc) +{ + return loc ? loc->end : 0; +} + +/* Return the line number of a line within the "loc" region. + */ +int pet_loc_get_line(__isl_keep pet_loc *loc) +{ + return loc ? loc->line : -1; +} + +/* Update loc->start and loc->end to include the region from "start" + * to "end". + * + * Since we may be modifying "loc", it should be different from + * pet_loc_dummy. + */ +__isl_give pet_loc *pet_loc_update_start_end(__isl_take pet_loc *loc, + unsigned start, unsigned end) +{ + loc = pet_loc_cow(loc); + if (!loc) + return NULL; + + if (start < loc->start) + loc->start = start; + if (end > loc->end) + loc->end = end; + + return loc; +} + +/* Update loc->start and loc->end to include the region of "loc2". + * + * "loc" may be pet_loc_dummy, in which case we return a copy of "loc2". + * Similarly, if "loc2" is pet_loc_dummy, then we leave "loc" untouched. + */ +__isl_give pet_loc *pet_loc_update_start_end_from_loc(__isl_take pet_loc *loc, + __isl_keep pet_loc *loc2) +{ + if (!loc2) + return pet_loc_free(loc); + if (loc == &pet_loc_dummy) + return pet_loc_copy(loc2); + if (loc2 == &pet_loc_dummy) + return loc; + return pet_loc_update_start_end(loc, loc2->start, loc2->end); +} diff --git a/loc.h b/loc.h new file mode 100644 index 0000000..3db082a --- /dev/null +++ b/loc.h @@ -0,0 +1,25 @@ +#ifndef PET_LOC_H +#define PET_LOC_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +extern pet_loc pet_loc_dummy; + +__isl_give pet_loc *pet_loc_alloc(isl_ctx *ctx, + unsigned start, unsigned end, int line); +__isl_give pet_loc *pet_loc_update_start_end(__isl_take pet_loc *loc, + unsigned start, unsigned end); +__isl_give pet_loc *pet_loc_update_start_end_from_loc(__isl_take pet_loc *loc, + __isl_keep pet_loc *loc2); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/parse.c b/parse.c index 1147181..8b6b36f 100644 --- a/parse.c +++ b/parse.c @@ -36,6 +36,7 @@ #include #include "expr.h" +#include "loc.h" #include "scop.h" #include "scop_yaml.h" @@ -617,6 +618,8 @@ static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document, { struct pet_stmt *stmt; yaml_node_pair_t * pair; + int line = -1; + unsigned start = 0, end = 0; if (node->type != YAML_MAPPING_NODE) isl_die(ctx, isl_error_invalid, "expecting mapping", @@ -626,6 +629,8 @@ static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document, if (!stmt) return NULL; + stmt->loc = &pet_loc_dummy; + for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; ++pair) { yaml_node_t *key, *value; @@ -638,7 +643,11 @@ static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document, return pet_stmt_free(stmt)); if (!strcmp((char *) key->data.scalar.value, "line")) - stmt->line = extract_int(ctx, document, value); + line = extract_int(ctx, document, value); + if (!strcmp((char *) key->data.scalar.value, "start")) + start = extract_int(ctx, document, value); + if (!strcmp((char *) key->data.scalar.value, "end")) + end = extract_int(ctx, document, value); if (!strcmp((char *) key->data.scalar.value, "domain")) stmt->domain = extract_set(ctx, document, value); if (!strcmp((char *) key->data.scalar.value, "schedule")) @@ -653,6 +662,10 @@ static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document, return NULL; } + stmt->loc = pet_loc_alloc(ctx, start, end, line); + if (!stmt->loc) + return pet_stmt_free(stmt); + return stmt; } diff --git a/pet.cc b/pet.cc index 64c1c4b..d9265b6 100644 --- a/pet.cc +++ b/pet.cc @@ -1003,10 +1003,12 @@ struct pet_transform_data { static int pet_transform(struct pet_scop *scop, void *user) { struct pet_transform_data *data = (struct pet_transform_data *) user; + unsigned start; - if (copy(data->in, data->out, data->end, scop->start) < 0) + start = pet_loc_get_start(scop->loc); + if (copy(data->in, data->out, data->end, start) < 0) goto error; - data->end = scop->end; + data->end = pet_loc_get_end(scop->loc); scop = pet_scop_set_input_file(scop, data->in); data->p = data->transform(data->p, scop, data->user); if (!data->p) diff --git a/scan.cc b/scan.cc index 2652175..dab4a21 100644 --- a/scan.cc +++ b/scan.cc @@ -2564,16 +2564,17 @@ static SourceLocation move_to_start_of_line_if_first_token(SourceLocation loc, return loc; } -/* Update start and end of "scop" to include the region covered by "range". +/* Construct a pet_loc corresponding to the region covered by "range". * If "skip_semi" is set, then we assume "range" is followed by * a semicolon and also include this semicolon. */ -struct pet_scop *PetScan::update_scop_start_end(struct pet_scop *scop, - SourceRange range, bool skip_semi) +__isl_give pet_loc *PetScan::construct_pet_loc(SourceRange range, + bool skip_semi) { SourceLocation loc = range.getBegin(); SourceManager &SM = PP.getSourceManager(); const LangOptions &LO = PP.getLangOpts(); + int line = PP.getSourceManager().getExpansionLineNumber(loc); unsigned start, end; loc = move_to_start_of_line_if_first_token(loc, SM, LO); @@ -2585,8 +2586,7 @@ struct pet_scop *PetScan::update_scop_start_end(struct pet_scop *scop, loc = PP.getLocForEndOfToken(loc); end = getExpansionOffset(SM, loc); - scop = pet_scop_update_start_end(scop, start, end); - return scop; + return pet_loc_alloc(ctx, start, end, line); } /* Convert a top-level pet_expr to a pet_scop with one statement @@ -2604,16 +2604,15 @@ struct pet_scop *PetScan::extract(__isl_take pet_expr *expr, SourceRange range, { struct pet_stmt *ps; struct pet_scop *scop; - SourceLocation loc = range.getBegin(); - int line = PP.getSourceManager().getExpansionLineNumber(loc); + pet_loc *loc; expr = pet_expr_plug_in_args(expr, pc); expr = pet_expr_resolve_nested(expr); expr = pet_expr_resolve_assume(expr, pc); - ps = pet_stmt_from_pet_expr(line, label, n_stmt++, expr); - scop = pet_scop_from_pet_stmt(ctx, ps); - scop = update_scop_start_end(scop, range, skip_semi); + loc = construct_pet_loc(range, skip_semi); + ps = pet_stmt_from_pet_expr(loc, label, n_stmt++, expr); + scop = pet_scop_from_pet_stmt(ctx, ps); return scop; } @@ -2759,8 +2758,7 @@ struct pet_scop *PetScan::extract_non_affine_condition(Expr *cond, int stmt_nr, { pet_expr *expr, *write; struct pet_stmt *ps; - SourceLocation loc = cond->getLocStart(); - int line = PP.getSourceManager().getExpansionLineNumber(loc); + pet_loc *loc; write = pet_expr_from_index(index); write = pet_expr_access_set_write(write, 1); @@ -2769,7 +2767,8 @@ struct pet_scop *PetScan::extract_non_affine_condition(Expr *cond, int stmt_nr, expr = pet_expr_plug_in_args(expr, pc); expr = pet_expr_resolve_nested(expr); expr = pet_expr_new_binary(1, pet_op_assign, write, expr); - ps = pet_stmt_from_pet_expr(line, NULL, stmt_nr, expr); + loc = construct_pet_loc(cond->getSourceRange(), false); + ps = pet_stmt_from_pet_expr(loc, NULL, stmt_nr, expr); return pet_scop_from_pet_stmt(ctx, ps); } @@ -3116,6 +3115,7 @@ struct pet_scop *PetScan::extract(Stmt *stmt, __isl_keep pet_context *pc, bool skip_declarations) { struct pet_scop *scop; + pet_loc *loc; if (isa(stmt)) return extract(extract_expr(cast(stmt)), @@ -3154,7 +3154,9 @@ struct pet_scop *PetScan::extract(Stmt *stmt, __isl_keep pet_context *pc, if (partial || skip_declarations) return scop; - scop = update_scop_start_end(scop, stmt->getSourceRange(), false); + loc = construct_pet_loc(stmt->getSourceRange(), false); + scop = pet_scop_update_start_end_from_loc(scop, loc); + pet_loc_free(loc); return scop; } @@ -3170,6 +3172,7 @@ struct pet_stmt *PetScan::extract_kill(struct pet_scop *scop) isl_multi_pw_aff *index; isl_map *access; pet_expr *arg; + pet_loc *loc; if (!scop) return NULL; @@ -3188,7 +3191,8 @@ struct pet_stmt *PetScan::extract_kill(struct pet_scop *scop) index = isl_multi_pw_aff_reset_tuple_id(index, isl_dim_in); access = isl_map_reset_tuple_id(access, isl_dim_in); kill = pet_expr_kill_from_access_and_index(access, index); - return pet_stmt_from_pet_expr(stmt->line, NULL, n_stmt++, kill); + loc = pet_loc_copy(stmt->loc); + return pet_stmt_from_pet_expr(loc, NULL, n_stmt++, kill); } /* Mark all arrays in "scop" as being exposed. diff --git a/scan.h b/scan.h index 65a3723..da3661f 100644 --- a/scan.h +++ b/scan.h @@ -10,6 +10,7 @@ #include #include "context.h" +#include "loc.h" #include "scop.h" /* The location of the scop, as delimited by scop and endscop @@ -129,8 +130,8 @@ private: struct pet_scop *extract(clang::DeclStmt *expr, __isl_keep pet_context *pc); - struct pet_scop *update_scop_start_end(struct pet_scop *scop, - clang::SourceRange range, bool skip_semi); + __isl_give pet_loc *construct_pet_loc(clang::SourceRange range, + bool skip_semi); struct pet_scop *extract(__isl_take pet_expr *expr, clang::SourceRange range, bool skip_semi, __isl_keep pet_context *pc, __isl_take isl_id *label = NULL); diff --git a/scop.c b/scop.c index 0ced71e..86e9124 100644 --- a/scop.c +++ b/scop.c @@ -38,6 +38,7 @@ #include "expr.h" #include "filter.h" +#include "loc.h" #include "nest.h" #include "scop.h" #include "print.h" @@ -70,7 +71,7 @@ struct pet_scop_ext { FILE *input; }; -/* Construct a pet_stmt with given line number and statement +/* Construct a pet_stmt with given location and statement * number from a pet_expr. * The initial iteration domain is the zero-dimensional universe. * The name of the domain is given by "label" if it is non-NULL. @@ -78,8 +79,8 @@ struct pet_scop_ext { * The domains of all access relations are modified to refer * to the statement iteration domain. */ -struct pet_stmt *pet_stmt_from_pet_expr(int line, __isl_take isl_id *label, - int id, __isl_take pet_expr *expr) +struct pet_stmt *pet_stmt_from_pet_expr(__isl_take pet_loc *loc, + __isl_take isl_id *label, int id, __isl_take pet_expr *expr) { struct pet_stmt *stmt; isl_ctx *ctx; @@ -89,7 +90,7 @@ struct pet_stmt *pet_stmt_from_pet_expr(int line, __isl_take isl_id *label, isl_multi_pw_aff *add_name; char name[50]; - if (!expr) + if (!loc || !expr) goto error; ctx = pet_expr_get_ctx(expr); @@ -111,7 +112,7 @@ struct pet_stmt *pet_stmt_from_pet_expr(int line, __isl_take isl_id *label, add_name = isl_multi_pw_aff_zero(dim); expr = pet_expr_update_domain(expr, add_name); - stmt->line = line; + stmt->loc = loc; stmt->domain = dom; stmt->schedule = sched; stmt->body = expr; @@ -122,6 +123,7 @@ struct pet_stmt *pet_stmt_from_pet_expr(int line, __isl_take isl_id *label, return stmt; error: isl_id_free(label); + pet_loc_free(loc); pet_expr_free(expr); return NULL; } @@ -133,6 +135,7 @@ void *pet_stmt_free(struct pet_stmt *stmt) if (!stmt) return NULL; + pet_loc_free(stmt->loc); isl_set_free(stmt->domain); isl_map_free(stmt->schedule); pet_expr_free(stmt->body); @@ -173,7 +176,7 @@ static void stmt_dump(struct pet_stmt *stmt, int indent) if (!stmt) return; - fprintf(stderr, "%*s%d\n", indent, "", stmt->line); + fprintf(stderr, "%*s%d\n", indent, "", pet_loc_get_line(stmt->loc)); fprintf(stderr, "%*s", indent, ""); isl_set_dump(stmt->domain); fprintf(stderr, "%*s", indent, ""); @@ -258,6 +261,9 @@ struct pet_scop *pet_scop_alloc(isl_ctx *ctx) } /* Construct a pet_scop with room for n statements. + * + * Since no information on the location is known at this point, + * scop->loc is initialized with pet_loc_dummy. */ static struct pet_scop *scop_alloc(isl_ctx *ctx, int n) { @@ -275,6 +281,7 @@ static struct pet_scop *scop_alloc(isl_ctx *ctx, int n) if (!scop->context || !scop->stmts) return pet_scop_free(scop); + scop->loc = &pet_loc_dummy; scop->n_stmt = n; return scop; @@ -402,6 +409,10 @@ struct pet_scop *pet_scop_from_pet_stmt(isl_ctx *ctx, struct pet_stmt *stmt) goto error; scop->stmts[0] = stmt; + scop->loc = pet_loc_copy(stmt->loc); + + if (!scop->loc) + return pet_scop_free(scop); return scop; error: @@ -523,30 +534,57 @@ static struct pet_scop *scop_combine_skips(struct pet_scop *scop, return &ext->scop; } -/* Update scop->start and scop->end to include the region from "start" - * to "end". In particular, if scop->end == 0, then "scop" does not - * have any offset information yet and we simply take the information - * from "start" and "end". Otherwise, we update the fields if the - * region from "start" to "end" is not already included. +/* Update start and end of scop->loc to include the region from "start" + * to "end". In particular, if scop->loc == &pet_loc_dummy, then "scop" + * does not have any offset information yet and we simply take the information + * from "start" and "end". Otherwise, we update loc using "start" and "end". */ struct pet_scop *pet_scop_update_start_end(struct pet_scop *scop, unsigned start, unsigned end) { if (!scop) return NULL; - if (scop->end == 0) { - scop->start = start; - scop->end = end; - } else { - if (start < scop->start) - scop->start = start; - if (end > scop->end) - scop->end = end; - } + + if (scop->loc == &pet_loc_dummy) + scop->loc = pet_loc_alloc(isl_set_get_ctx(scop->context), + start, end, -1); + else + scop->loc = pet_loc_update_start_end(scop->loc, start, end); + + if (!scop->loc) + return pet_scop_free(scop); return scop; } +/* Update start and end of scop->loc to include the region identified + * by "loc". + */ +struct pet_scop *pet_scop_update_start_end_from_loc(struct pet_scop *scop, + __isl_keep pet_loc *loc) +{ + return pet_scop_update_start_end(scop, pet_loc_get_start(loc), + pet_loc_get_end(loc)); +} + +/* Replace the location of "scop" by "loc". + */ +struct pet_scop *pet_scop_set_loc(struct pet_scop *scop, + __isl_take pet_loc *loc) +{ + if (!scop || !loc) + goto error; + + pet_loc_free(scop->loc); + scop->loc = loc; + + return scop; +error: + pet_loc_free(loc); + pet_scop_free(scop); + return NULL; +} + /* Does "implication" appear in the list of implications of "scop"? */ static int is_known_implication(struct pet_scop *scop, @@ -631,12 +669,10 @@ static struct pet_scop *scop_collect_implications(isl_ctx *ctx, static struct pet_scop *scop_combine_start_end(struct pet_scop *scop, struct pet_scop *scop1, struct pet_scop *scop2) { - if (scop1->end) - scop = pet_scop_update_start_end(scop, - scop1->start, scop1->end); - if (scop2->end) - scop = pet_scop_update_start_end(scop, - scop2->start, scop2->end); + if (scop1->loc != &pet_loc_dummy) + scop = pet_scop_update_start_end_from_loc(scop, scop1->loc); + if (scop2->loc != &pet_loc_dummy) + scop = pet_scop_update_start_end_from_loc(scop, scop2->loc); return scop; } @@ -790,6 +826,7 @@ struct pet_scop *pet_scop_free(struct pet_scop *scop) if (!scop) return NULL; + pet_loc_free(scop->loc); isl_set_free(scop->context); isl_set_free(scop->context_value); if (scop->types) @@ -900,7 +937,7 @@ int pet_stmt_is_equal(struct pet_stmt *stmt1, struct pet_stmt *stmt2) if (!stmt1 || !stmt2) return 0; - if (stmt1->line != stmt2->line) + if (pet_loc_get_line(stmt1->loc) != pet_loc_get_line(stmt2->loc)) return 0; if (!isl_set_is_equal(stmt1->domain, stmt2->domain)) return 0; @@ -3300,6 +3337,7 @@ __isl_give isl_printer *pet_scop_print_original(struct pet_scop *scop, { struct pet_scop_ext *ext = (struct pet_scop_ext *) scop; FILE *output; + unsigned start, end; if (!scop || !p) return isl_printer_free(p); @@ -3313,7 +3351,9 @@ __isl_give isl_printer *pet_scop_print_original(struct pet_scop *scop, if (!output) return isl_printer_free(p); - if (copy(ext->input, output, scop->start, scop->end) < 0) + start = pet_loc_get_start(scop->loc); + end = pet_loc_get_end(scop->loc); + if (copy(ext->input, output, start, end) < 0) return isl_printer_free(p); return p; diff --git a/scop.h b/scop.h index 8d28f09..50cab5b 100644 --- a/scop.h +++ b/scop.h @@ -15,8 +15,8 @@ extern "C" { */ enum pet_skip { pet_skip_now = 0, pet_skip_later = 1 }; -struct pet_stmt *pet_stmt_from_pet_expr(int line, __isl_take isl_id *label, - int id, __isl_take pet_expr *expr); +struct pet_stmt *pet_stmt_from_pet_expr(__isl_take pet_loc *loc, + __isl_take isl_id *label, int id, __isl_take pet_expr *expr); void pet_stmt_dump(struct pet_stmt *stmt); void *pet_stmt_free(struct pet_stmt *stmt); @@ -92,6 +92,10 @@ struct pet_scop *pet_scop_add_boolean_array(struct pet_scop *scop, struct pet_scop *pet_scop_update_start_end(struct pet_scop *scop, unsigned start, unsigned end); +struct pet_scop *pet_scop_update_start_end_from_loc(struct pet_scop *scop, + __isl_keep pet_loc *loc); +struct pet_scop *pet_scop_set_loc(struct pet_scop *scop, + __isl_take pet_loc *loc); struct pet_scop *pet_scop_set_input_file(struct pet_scop *scop, FILE *input); #if defined(__cplusplus) diff --git a/skip.c b/skip.c index 906edc0..1fc0469 100644 --- a/skip.c +++ b/skip.c @@ -1,4 +1,5 @@ #include "expr.h" +#include "loc.h" #include "scop.h" #include "skip.h" @@ -137,7 +138,7 @@ static struct pet_scop *extract_skip_if(__isl_take isl_multi_pw_aff *test_index, expr_skip = pet_expr_access_set_write(expr_skip, 1); expr_skip = pet_expr_access_set_read(expr_skip, 0); expr = pet_expr_new_binary(1, pet_op_assign, expr_skip, expr); - stmt = pet_stmt_from_pet_expr(-1, NULL, (*n_stmt)++, expr); + stmt = pet_stmt_from_pet_expr(&pet_loc_dummy, NULL, (*n_stmt)++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); scop = pet_scop_add_boolean_array(scop, skip_index, int_size); @@ -368,7 +369,7 @@ static struct pet_scop *extract_skip_seq( expr_skip = pet_expr_access_set_write(expr_skip, 1); expr_skip = pet_expr_access_set_read(expr_skip, 0); expr = pet_expr_new_binary(1, pet_op_assign, expr_skip, expr); - stmt = pet_stmt_from_pet_expr(-1, NULL, (*n_stmt)++, expr); + stmt = pet_stmt_from_pet_expr(&pet_loc_dummy, NULL, (*n_stmt)++, expr); scop = pet_scop_from_pet_stmt(ctx, stmt); scop = pet_scop_add_boolean_array(scop, skip_index, int_size); -- 2.11.4.GIT