README: rename
[ppn.git] / size_simulate.cc
blob707661a4b2eb2bf10db9575de5e2425cf00d3137
1 #include <sys/wait.h>
2 #include <dlfcn.h>
3 #include <unistd.h>
4 #include <isl/id.h>
5 #include <isl/aff.h>
6 #include <isl/ast.h>
7 #include <isl/ast_build.h>
8 #include <isl/printer.h>
9 #include "size_simulate.h"
11 namespace size {
13 static int count(const char *tmpfile)
15 long (*c)();
16 void *module;
17 long max;
18 char *error;
20 module = dlopen(tmpfile, RTLD_LAZY);
21 unlink(tmpfile);
22 if ((error = dlerror()) != NULL) {
23 fprintf(stderr, "%s\n", error);
24 assert(0);
26 assert(module);
27 c = (long (*)()) dlsym(module, "__size_count");
28 if ((error = dlerror()) != NULL) {
29 fprintf(stderr, "%s\n", error);
30 assert(0);
32 max = c();
33 dlclose(module);
34 return max;
37 static __isl_give isl_printer *print_user(__isl_take isl_printer *p,
38 __isl_take isl_ast_print_options *print_options,
39 __isl_keep isl_ast_node *node, void *user)
41 isl_id *id;
42 isl_ast_expr *expr, *arg;
43 const char *name;
45 expr = isl_ast_node_user_get_expr(node);
46 arg = isl_ast_expr_get_op_arg(expr, 0);
47 id = isl_ast_expr_get_id(arg);
48 name = isl_id_get_name(id);
49 if (!strcmp(name, "write")) {
50 p = isl_printer_start_line(p);
51 p = isl_printer_print_str(p, "if (++count > max)");
52 p = isl_printer_end_line(p);
53 p = isl_printer_indent(p, 4);
54 p = isl_printer_start_line(p);
55 p = isl_printer_print_str(p, "max = count;");
56 p = isl_printer_end_line(p);
57 p = isl_printer_indent(p, -4);
58 } else {
59 p = isl_printer_start_line(p);
60 p = isl_printer_print_str(p, "--count;");
61 p = isl_printer_end_line(p);
63 isl_id_free(id);
64 isl_ast_expr_free(arg);
65 isl_ast_expr_free(expr);
66 isl_ast_print_options_free(print_options);
67 return p;
70 static int scan_program(__isl_keep isl_ast_node *tree)
72 int ret;
73 char tmpfile[L_tmpnam];
74 char buffer[L_tmpnam + 41];
75 FILE *dst;
76 char *name;
77 isl_ctx *ctx;
78 isl_printer *p;
79 isl_ast_print_options *print_options;
81 name = tmpnam(tmpfile);
82 assert(name);
84 snprintf(buffer, sizeof(buffer),
85 "gcc -std=c99 -x c -fPIC -O2 -shared - -o %s", tmpfile);
86 dst = popen(buffer, "w");
87 assert(dst);
89 ctx = isl_ast_node_get_ctx(tree);
91 p = isl_printer_to_file(ctx, dst);
92 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
94 p = isl_printer_start_line(p);
95 p = isl_printer_print_str(p, "#include <assert.h>");
96 p = isl_printer_end_line(p);
98 p = isl_printer_start_line(p);
99 p = isl_printer_print_str(p, "#include <stdio.h>");
100 p = isl_printer_end_line(p);
102 p = isl_ast_node_print_macros(tree, p);
104 p = isl_printer_start_line(p);
105 p = isl_printer_print_str(p, "long __size_count() {");
106 p = isl_printer_end_line(p);
108 p = isl_printer_indent(p, 4);
110 p = isl_printer_start_line(p);
111 p = isl_printer_print_str(p, "long count = 0, max = 0;");
112 p = isl_printer_end_line(p);
114 print_options = isl_ast_print_options_alloc(ctx);
115 print_options = isl_ast_print_options_set_print_user(print_options,
116 &print_user, NULL);
117 p = isl_ast_node_print(tree, p, print_options);
119 p = isl_printer_start_line(p);
120 p = isl_printer_print_str(p, "assert(count == 0);");
121 p = isl_printer_end_line(p);
123 p = isl_printer_start_line(p);
124 p = isl_printer_print_str(p, "return max;");
125 p = isl_printer_end_line(p);
127 p = isl_printer_indent(p, -4);
129 p = isl_printer_start_line(p);
130 p = isl_printer_print_str(p, "}");
131 p = isl_printer_end_line(p);
133 isl_printer_free(p);
135 ret = pclose(dst);
136 assert(WEXITSTATUS(ret) == 0);
138 return count(tmpfile);
141 int selfloop_size_simulate(__isl_take isl_map *dep, __isl_take isl_set *read)
143 int size;
144 isl_ctx *ctx = isl_map_get_ctx(dep);
145 isl_set *context;
146 isl_map *write;
147 isl_union_map *sched;
148 isl_ast_build *build;
149 isl_ast_node *tree;
151 dep = isl_map_intersect_range(dep, read);
152 write = isl_set_identity(isl_map_domain(isl_map_copy(dep)));
153 write = isl_map_set_tuple_name(write, isl_dim_in, "write");
154 dep = isl_map_set_tuple_name(dep, isl_dim_in, "read");
156 sched = isl_union_map_from_map(dep);
157 sched = isl_union_map_add_map(sched, write);
159 context = isl_set_universe(isl_union_map_get_space(sched));
160 build = isl_ast_build_from_context(context);
161 tree = isl_ast_build_ast_from_schedule(build, sched);
162 isl_ast_build_free(build);
164 size = scan_program(tree);
166 isl_ast_node_free(tree);
168 return size;