isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / codegen.c
1 /*
2  * Copyright 2012      Ecole Normale Superieure
3  *
4  * Use of this software is governed by the MIT license
5  *
6  * Written by Sven Verdoolaege,
7  * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
8  */
9
10 /* This program prints an AST that scans the domain elements of
11  * the domain of a given schedule in the order of their image(s).
12  *
13  * The input consists of three sets/relations.
14  * - a schedule
15  * - a context
16  * - a relation describing AST generation options
17  */
18
19 #include <assert.h>
20 #include <isl/ast.h>
21 #include <isl/ast_build.h>
22 #include <isl/options.h>
23 #include <isl/set.h>
24
25 struct options {
26         struct isl_options      *isl;
27         unsigned                 atomic;
28         unsigned                 separate;
29 };
30
31 ISL_ARGS_START(struct options, options_args)
32 ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options")
33 ISL_ARG_BOOL(struct options, atomic, 0, "atomic", 0,
34         "globally set the atomic option")
35 ISL_ARG_BOOL(struct options, separate, 0, "separate", 0,
36         "globally set the separate option")
37 ISL_ARGS_END
38
39 ISL_ARG_DEF(options, struct options, options_args)
40
41 /* Return a universal, 1-dimensional set with the given name.
42  */
43 static __isl_give isl_union_set *universe(isl_ctx *ctx, const char *name)
44 {
45         isl_space *space;
46
47         space = isl_space_set_alloc(ctx, 0, 1);
48         space = isl_space_set_tuple_name(space, isl_dim_set, name);
49         return isl_union_set_from_set(isl_set_universe(space));
50 }
51
52 /* Set the "name" option for the entire schedule domain.
53  */
54 static __isl_give isl_union_map *set_universe(__isl_take isl_union_map *opt,
55         __isl_keep isl_union_map *schedule, const char *name)
56 {
57         isl_ctx *ctx;
58         isl_union_set *domain, *target;
59         isl_union_map *option;
60
61         ctx = isl_union_map_get_ctx(opt);
62
63         domain = isl_union_map_range(isl_union_map_copy(schedule));
64         domain = isl_union_set_universe(domain);
65         target = universe(ctx, name);
66         option = isl_union_map_from_domain_and_range(domain, target);
67         opt = isl_union_map_union(opt, option);
68
69         return opt;
70 }
71
72 /* Update the build options based on the user-specified options.
73  *
74  * If the --separate or --atomic options were specified, then
75  * we clear any separate or atomic options that may already exist in "opt".
76  */
77 static __isl_give isl_ast_build *set_options(__isl_take isl_ast_build *build,
78         __isl_take isl_union_map *opt, struct options *options,
79         __isl_keep isl_union_map *schedule)
80 {
81         if (options->separate || options->atomic) {
82                 isl_ctx *ctx;
83                 isl_union_set *target;
84
85                 ctx = isl_union_map_get_ctx(schedule);
86
87                 target = universe(ctx, "separate");
88                 opt = isl_union_map_subtract_range(opt, target);
89                 target = universe(ctx, "atomic");
90                 opt = isl_union_map_subtract_range(opt, target);
91         }
92
93         if (options->separate)
94                 opt = set_universe(opt, schedule, "separate");
95         if (options->atomic)
96                 opt = set_universe(opt, schedule, "atomic");
97
98         build = isl_ast_build_set_options(build, opt);
99
100         return build;
101 }
102
103 int main(int argc, char **argv)
104 {
105         isl_ctx *ctx;
106         isl_set *context;
107         isl_union_map *schedule;
108         isl_union_map *options_map;
109         isl_ast_build *build;
110         isl_ast_node *tree;
111         struct options *options;
112         isl_printer *p;
113
114         options = options_new_with_defaults();
115         assert(options);
116         argc = options_parse(options, argc, argv, ISL_ARG_ALL);
117
118         ctx = isl_ctx_alloc_with_options(&options_args, options);
119
120         schedule = isl_union_map_read_from_file(ctx, stdin);
121         context = isl_set_read_from_file(ctx, stdin);
122         options_map = isl_union_map_read_from_file(ctx, stdin);
123
124         build = isl_ast_build_from_context(context);
125         build = set_options(build, options_map, options, schedule);
126         tree = isl_ast_build_ast_from_schedule(build, schedule);
127         isl_ast_build_free(build);
128
129         p = isl_printer_to_file(ctx, stdout);
130         p = isl_printer_set_output_format(p, ISL_FORMAT_C);
131         p = isl_printer_print_ast_node(p, tree);
132         isl_printer_free(p);
133
134         isl_ast_node_free(tree);
135
136         isl_ctx_free(ctx);
137         return 0;
138 }