it compiles now
[official-gcc.git] / gcc / python / py-stmt-pass-lower.c
blobabbe81b24641a3cf4044bfa42b77c677f0180869
1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
6 version.
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
17 #include "config.h"
18 #include "system.h"
19 #include "ansidecl.h"
20 #include "coretypes.h"
21 #include "tm.h"
22 #include "opts.h"
23 #include "tree.h"
24 #include "tree-iterator.h"
25 #include "tree-pass.h"
26 #include "gimple.h"
27 #include "toplev.h"
28 #include "debug.h"
29 #include "options.h"
30 #include "flags.h"
31 #include "convert.h"
32 #include "diagnostic-core.h"
33 #include "langhooks.h"
34 #include "langhooks-def.h"
35 #include "target.h"
36 #include "cgraph.h"
38 #include <gmp.h>
39 #include <mpfr.h>
41 #include "vec.h"
42 #include "hashtab.h"
44 #include "gpython.h"
45 #include "py-dot.h"
46 #include "py-vec.h"
47 #include "py-tree.h"
48 #include "py-builtins.h"
50 static VEC(tree,gc) * gpy_stmt_pass_lower_genericify (gpy_hash_tab_t *, VEC(gpydot,gc) *);
51 static tree gpy_stmt_pass_lower_get_module_type (const char *, gpy_hash_tab_t *);
52 static void gpy_stmt_pass_lower_gen_toplevl_context (tree, tree, gpy_hash_tab_t *);
54 static tree gpy_stmt_pass_lower_gen_concat_identifier (const char *, const char *);
55 static tree gpy_stmt_pass_lower_gen_main (tree);
57 static
58 tree gpy_stmt_pass_lower_gen_concat_identifier (const char * s1,
59 const char * s2)
61 debug ("s1 = <%s> s2 = <%s>!\n", s1, s2);
62 size_t s1len = strlen (s1);
63 size_t s2len = strlen (s2);
64 size_t tlen = s1len + s2len;
66 size_t idx = 0, idy = 0;
67 char buffer[tlen+3];
68 strncpy (buffer,s1,s1len);
70 buffer[s1len] = '.';
71 for (idx = s1len+1; idx<tlen+2; ++idx)
73 buffer[idx] = s2[idy];
74 ++idy;
76 buffer[tlen+1] = '\0';
77 debug ("buffer = <%s>!\n", buffer);
79 return get_identifier (buffer);
82 static
83 tree gpy_stmt_pass_lower_get_module_type (const char * s,
84 gpy_hash_tab_t * modules)
86 tree retval = error_mark_node;
88 gpy_hashval_t h = gpy_dd_hash_string (s);
89 gpy_hash_entry_t * e = gpy_dd_hash_lookup_table (modules, h);
90 if (e)
92 if (e->data)
93 retval = (tree) e->data;
96 return retval;
99 static
100 void gpy_stmt_pass_lower_gen_toplevl_context (tree module, tree param_decl,
101 gpy_hash_tab_t * context)
103 if (module == error_mark_node)
104 return;
105 else
107 tree field = TYPE_FIELDS (module);
108 do {
109 gcc_assert (TREE_CODE (field) == FIELD_DECL);
111 debug ("generating refernence to <%s>!\n", IDENTIFIER_POINTER(DECL_NAME (field)));
112 gpy_hashval_t h = gpy_dd_hash_string (IDENTIFIER_POINTER(DECL_NAME (field)));
113 tree ref = build3 (COMPONENT_REF, TREE_TYPE (field), build_fold_indirect_ref(param_decl),
114 field, NULL_TREE);
115 void ** e = gpy_dd_hash_insert (h, ref, context);
117 debug_tree (ref);
118 if (e)
119 fatal_error ("problem inserting component reference into context!\n");
120 } while ((field = DECL_CHAIN (field)));
125 Creates a DECL_CHAIN of stmts to fold the scalar
126 with the last tree being the address of the primitive
128 tree gpy_stmt_decl_lower_scalar (gpy_dot_tree_t * decl, tree * cblock)
130 tree retval = error_mark_node;
132 gcc_assert (DOT_TYPE (decl) == D_PRIMITIVE);
133 gcc_assert (DOT_lhs_T (decl) == D_TD_COM);
135 switch (DOT_lhs_TC (decl)->T)
137 case D_T_INTEGER:
139 retval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
140 create_tmp_var_name ("P"),
141 gpy_object_type_ptr);
142 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, retval,
143 gpy_builtin_get_fold_int_call (DOT_lhs_TC (decl)->o.integer)),
144 cblock);
146 break;
148 default:
149 error ("invalid scalar type!\n");
150 break;
153 return retval;
156 tree gpy_stmt_decl_lower_modify (gpy_dot_tree_t * decl, tree * cblock,
157 VEC(gpy_ctx_t,gc) * context)
159 tree retval = error_mark_node;
160 gpy_dot_tree_t * lhs = DOT_lhs_TT (decl);
161 gpy_dot_tree_t * rhs = DOT_rhs_TT (decl);
164 We dont handle full target lists yet
165 all targets are in the lhs tree.
167 To implment a target list such as:
168 x,y,z = 1
170 The lhs should be a DOT_CHAIN of identifiers!
171 So we just iterate over them and deal with it as such!
174 gcc_assert (DOT_TYPE (lhs) == D_IDENTIFIER);
176 tree addr = gpy_ctx_lookup_decl (context, DOT_IDENTIFIER_POINTER (lhs));
177 if (!addr)
179 /* since not previously declared we need to declare the variable! */
180 gpy_hash_tab_t * current_context = VEC_index (gpy_ctx_t, context,
181 (VEC_length (gpy_ctx_t, context)
182 - 1)
184 addr = build_decl (UNKNOWN_LOCATION, VAR_DECL,
185 get_identifier (DOT_IDENTIFIER_POINTER (lhs)),
186 gpy_object_type_ptr);
188 if (!gpy_ctx_push_decl (addr, DOT_IDENTIFIER_POINTER (lhs),
189 current_context))
190 fatal_error ("error pushing decl <%q+E>!\n", addr);
192 gcc_assert (addr != error_mark_node);
194 tree addr_rhs_tree = gpy_stmt_decl_lower_expr (rhs, cblock, context);
196 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, addr, addr_rhs_tree), cblock);
197 append_to_statement_list (gpy_builtin_get_incr_ref_call (addr), cblock);
198 retval = addr;
200 return retval;
203 tree gpy_stmt_decl_lower_binary_op (gpy_dot_tree_t * decl, tree * cblock,
204 VEC(gpy_ctx_t,gc) * context)
206 tree retval = error_mark_node;
208 gcc_assert (DOT_T_FIELD (decl) == D_D_EXPR);
210 gpy_dot_tree_t * lhs = DOT_lhs_TT (decl);
211 gpy_dot_tree_t * rhs = DOT_rhs_TT (decl);
213 tree lhs_eval = gpy_stmt_decl_lower_expr (lhs, cblock, context);
214 tree rhs_eval = gpy_stmt_decl_lower_expr (rhs, cblock, context);
216 tree op = error_mark_node;
217 switch (DOT_TYPE (decl))
219 case D_ADD_EXPR:
220 op = gpy_builtin_get_eval_expression_call (lhs_eval, rhs_eval, DOT_TYPE (decl));
221 break;
223 // ....
225 default:
226 error ("unhandled binary operation type!\n");
227 break;
229 gcc_assert (op != error_mark_node);
232 tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL, create_tmp_var_name("T"),
233 gpy_object_type_ptr);
234 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, retaddr, op), cblock);
235 retval = retaddr;
237 return retval;
240 tree gpy_stmt_decl_lower_expr (gpy_dot_tree_t * decl, tree * cblock,
241 VEC(gpy_ctx_t,gc) * context)
243 tree retval = error_mark_node;
245 switch (DOT_TYPE (decl))
247 case D_PRIMITIVE:
248 retval = gpy_stmt_decl_lower_scalar (decl, cblock);
249 break;
251 case D_IDENTIFIER:
252 retval = gpy_ctx_lookup_decl (context,
253 DOT_IDENTIFIER_POINTER (decl));
254 break;
256 default:
258 switch (DOT_TYPE (decl))
260 case D_MODIFY_EXPR:
261 retval = gpy_stmt_decl_lower_modify (decl, cblock, context);
262 break;
264 case D_ADD_EXPR:
265 retval = gpy_stmt_decl_lower_binary_op (decl, cblock, context);
266 break;
268 // ... the rest of the binary operators!
270 default:
271 error ("unhandled operation type!\n");
272 break;
275 break;
278 return retval;
281 tree gpy_stmt_pass_lower_functor (gpy_dot_tree_t * decl,
282 gpy_hash_tab_t * modules)
284 tree block = alloc_stmt_list ();
286 gpy_hash_tab_t toplvl, topnxt;
287 gpy_dd_hash_init_table (&toplvl);
288 gpy_dd_hash_init_table (&topnxt);
290 tree main_init_module = gpy_stmt_pass_lower_get_module_type ("main.main",
291 modules);
292 tree pdecl_t = build_pointer_type (main_init_module);
293 tree fntype = build_function_type_list (void_type_node, pdecl_t,
295 handle function parameters
296 ...
298 NULL_TREE);
299 tree concat_ident = gpy_stmt_pass_lower_gen_concat_identifier ("main.main",
300 DOT_IDENTIFIER_POINTER (DOT_FIELD (decl)));
301 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, concat_ident, fntype);
303 DECL_EXTERNAL (fndecl) = 0;
304 TREE_PUBLIC (fndecl) = 1;
305 TREE_STATIC (fndecl) = 1;
306 tree arglist = NULL_TREE;
308 tree result_decl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
309 integer_type_node);
310 DECL_RESULT (fndecl) = result_decl;
312 SET_DECL_ASSEMBLER_NAME (fndecl, concat_ident);
314 tree self_parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
315 get_identifier ("__self__"),
316 pdecl_t);
318 DECL_CONTEXT (self_parm_decl) = fndecl;
319 DECL_ARG_TYPE (self_parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
320 TREE_READONLY (self_parm_decl) = 1;
321 arglist = chainon (arglist, self_parm_decl);
323 TREE_USED (self_parm_decl) = 1;
324 DECL_ARGUMENTS (fndecl) = arglist;
326 gpy_stmt_pass_lower_gen_toplevl_context (main_init_module, self_parm_decl,
327 &toplvl);
329 VEC(gpy_ctx_t,gc) * toplevl_context = VEC_alloc (gpy_ctx_t, gc, 0);
330 VEC_safe_push (gpy_ctx_t, gc, toplevl_context, &toplvl);
331 VEC_safe_push (gpy_ctx_t, gc, toplevl_context, &topnxt);
333 DECL_INITIAL(fndecl) = block;
334 gpy_dot_tree_t * idtx = DOT_rhs_TT (decl);
336 Iterating over the DOT IL to lower/generate the GENERIC code
337 required to compile the stmts and decls
339 do {
340 if (DOT_T_FIELD (idtx) == D_D_EXPR)
342 // append to stmt list as this goes into the module initilizer...
343 gpy_stmt_decl_lower_expr (idtx, &block, toplevl_context);
344 continue;
347 switch (DOT_TYPE (idtx))
349 default:
350 fatal_error ("unhandled dot tree code <%i>!\n", DOT_TYPE (idtx));
351 break;
353 } while ((idtx = DOT_CHAIN (idtx)));
355 tree bl = make_node(BLOCK);
356 BLOCK_SUPERCONTEXT(bl) = fndecl;
357 DECL_INITIAL(fndecl) = bl;
358 BLOCK_VARS(bl) = NULL_TREE;
359 TREE_USED(bl) = 1;
360 tree bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(bl),
361 NULL_TREE, bl);
362 TREE_SIDE_EFFECTS(bind) = 1;
364 BIND_EXPR_BODY(bind) = block;
365 block = bind;
366 DECL_SAVED_TREE(fndecl) = block;
368 gimplify_function_tree (fndecl);
370 cgraph_add_new_function (fndecl, false);
371 cgraph_finalize_function (fndecl, true);
373 return fndecl;
376 static
377 VEC(tree,gc) * gpy_stmt_pass_lower_genericify (gpy_hash_tab_t * modules,
378 VEC(gpydot,gc) * decls)
380 VEC(tree,gc) * retval = VEC_alloc (tree,gc,0);
382 tree block = alloc_stmt_list ();
383 // tree declvars = NULL_TREE;
385 gpy_hash_tab_t toplvl, topnxt;
386 gpy_dd_hash_init_table (&toplvl);
387 gpy_dd_hash_init_table (&topnxt);
389 tree main_init_module = gpy_stmt_pass_lower_get_module_type ("main.main", modules);
390 tree pdecl_t = build_pointer_type (main_init_module);
392 tree main_init_fntype = build_function_type_list (void_type_node, pdecl_t, NULL_TREE);
393 tree main_init_fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
394 get_identifier ("main.main.init"),
395 main_init_fntype);
396 DECL_EXTERNAL (main_init_fndecl) = 0;
397 TREE_PUBLIC (main_init_fndecl) = 1;
398 TREE_STATIC (main_init_fndecl) = 1;
400 tree result_decl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
401 integer_type_node);
402 DECL_RESULT (main_init_fndecl) = result_decl;
404 tree arglist = NULL_TREE;
406 SET_DECL_ASSEMBLER_NAME (main_init_fndecl, get_identifier("main.main.init"));
407 tree self_parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
408 get_identifier ("__self__"),
409 pdecl_t);
410 DECL_CONTEXT (self_parm_decl) = main_init_fndecl;
411 DECL_ARG_TYPE (self_parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (main_init_fndecl)));
412 TREE_READONLY (self_parm_decl) = 1;
413 arglist = chainon (arglist, self_parm_decl);
415 TREE_USED (self_parm_decl) = 1;
416 DECL_ARGUMENTS (main_init_fndecl) = arglist;
418 gpy_stmt_pass_lower_gen_toplevl_context (main_init_module, self_parm_decl,
419 &toplvl);
421 VEC(gpy_ctx_t,gc) * toplevl_context = VEC_alloc (gpy_ctx_t, gc, 0);
422 VEC_safe_push (gpy_ctx_t, gc, toplevl_context, &toplvl);
423 VEC_safe_push (gpy_ctx_t, gc, toplevl_context, &topnxt);
425 DECL_INITIAL(main_init_fndecl) = block;
427 int idx = 0;
428 gpy_dot_tree_t * idtx = NULL_DOT;
430 Iterating over the DOT IL to lower/generate the GENERIC code
431 required to compile the stmts and decls
433 for (idx = 0; VEC_iterate (gpydot, decls, idx, idtx); ++idx)
435 if (DOT_T_FIELD (idtx) == D_D_EXPR)
437 // append to stmt list as this goes into the module initilizer...
438 gpy_stmt_decl_lower_expr (idtx, &block, toplevl_context);
439 continue;
442 switch (DOT_TYPE (idtx))
444 case D_STRUCT_METHOD:
447 They are self contained decls so we just pass them to the
448 return vector for gimplification
450 debug ("lowering function toplevel!\n");
451 VEC_safe_push (tree, gc, retval,
452 gpy_stmt_pass_lower_functor (idtx, modules)
454 debug ("lowered function toplevel!\n");
456 break;
458 default:
459 fatal_error ("unhandled dot tree code <%i>!\n", DOT_TYPE (idtx));
460 break;
464 tree bl = make_node(BLOCK);
465 BLOCK_SUPERCONTEXT(bl) = main_init_fndecl;
466 DECL_INITIAL(main_init_fndecl) = bl;
467 BLOCK_VARS(bl) = NULL_TREE;
468 TREE_USED(bl) = 1;
469 tree bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(bl),
470 NULL_TREE, bl);
471 TREE_SIDE_EFFECTS(bind) = 1;
473 BIND_EXPR_BODY(bind) = block;
474 block = bind;
475 DECL_SAVED_TREE(main_init_fndecl) = block;
477 gimplify_function_tree (main_init_fndecl);
479 cgraph_add_new_function (main_init_fndecl, false);
480 cgraph_finalize_function (main_init_fndecl, true);
482 VEC_safe_push (tree,gc,retval, main_init_fndecl);
484 return retval;
487 static
488 tree gpy_stmt_pass_lower_gen_main (tree module)
490 tree main_fn_type = build_function_type_list (integer_type_node, NULL_TREE);
491 tree main_fn_decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
492 get_identifier("main"), main_fn_type);
494 DECL_CONTEXT (main_fn_decl) = NULL_TREE;
495 TREE_STATIC (main_fn_decl) = 1;
496 TREE_PUBLIC (main_fn_decl) = 1;
497 DECL_ARGUMENTS (main_fn_decl) = NULL_TREE;
499 /* Define the return type (represented by RESULT_DECL) for the main functin */
500 tree main_ret = build_decl (BUILTINS_LOCATION, RESULT_DECL,
501 NULL_TREE, TREE_TYPE(main_fn_type));
502 DECL_CONTEXT(main_ret) = main_fn_decl;
503 DECL_ARTIFICIAL(main_ret) = 1;
504 DECL_IGNORED_P(main_ret) = 1;
505 DECL_RESULT(main_fn_decl) = main_ret;
507 tree main_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
508 DECL_INITIAL(main_fn_decl) = main_art_block;
510 tree declare_vars = NULL_TREE;
511 tree main_stmts = alloc_stmt_list ();
513 append_to_statement_list (gpy_builtin_get_init_call(), &main_stmts);
514 tree mod_decl = build_decl (BUILTINS_LOCATION, VAR_DECL, create_tmp_var_name ("I"),
515 module);
516 declare_vars = mod_decl;
517 tree module_init_fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
518 get_identifier ("main.main.init"),
519 build_function_type_list (void_type_node,
520 build_pointer_type (module), NULL_TREE)
522 append_to_statement_list (build_call_expr (module_init_fndecl, 1, build_fold_addr_expr(mod_decl)),
523 &main_stmts);
524 append_to_statement_list ( gpy_builtin_get_cleanup_final_call (), &main_stmts);
526 tree main_set_ret = build2 (MODIFY_EXPR, TREE_TYPE(main_ret),
527 main_ret, build_int_cst(integer_type_node, 0));
528 tree main_ret_expr = build1 (RETURN_EXPR, void_type_node, main_set_ret);
529 append_to_statement_list (main_ret_expr, &main_stmts);
531 tree bind = NULL_TREE;
532 tree bl = make_node(BLOCK);
533 BLOCK_SUPERCONTEXT(bl) = main_fn_decl;
534 DECL_INITIAL(main_fn_decl) = bl;
535 BLOCK_VARS(bl) = declare_vars;
536 TREE_USED(bl) = 1;
537 bind = build3( BIND_EXPR, void_type_node, BLOCK_VARS(bl),
538 NULL_TREE, bl );
539 TREE_SIDE_EFFECTS(bind) = 1;
541 BIND_EXPR_BODY(bind) = main_stmts;
542 main_stmts = bind;
543 DECL_SAVED_TREE(main_fn_decl) = main_stmts;
545 gimplify_function_tree (main_fn_decl);
546 cgraph_finalize_function (main_fn_decl, false);
548 return main_fn_decl;
551 /* Now we start to iterate over the dot IL to lower it down to */
552 /* a vector of GENERIC decls */
554 /* Which is then passed over to the pass manager for any other */
555 /* defined passes which can be placed into the queue but arent */
556 /* nessecary for now. */
557 VEC(tree,gc) * gpy_stmt_pass_lower (VEC(tree,gc) *modules,
558 VEC(gpydot,gc) *decls)
560 VEC(tree,gc) * retval;
562 gpy_hash_tab_t module_ctx;
563 gpy_dd_hash_init_table (&module_ctx);
565 int idx = 0;
566 tree itx = NULL_TREE;
568 for (; VEC_iterate (tree, modules, idx, itx); ++idx)
570 debug ("hashing module name <%s>!\n", IDENTIFIER_POINTER (TYPE_NAME(itx)));
571 gpy_hashval_t h = gpy_dd_hash_string (IDENTIFIER_POINTER (TYPE_NAME(itx)));
572 void ** e = gpy_dd_hash_insert (h, itx, &module_ctx);
574 if (e)
575 fatal_error ("module <%q+E> is already defined!\n", itx);
578 retval = gpy_stmt_pass_lower_genericify (&module_ctx, decls);
579 VEC_safe_push (tree, gc, retval,
580 gpy_stmt_pass_lower_gen_main (gpy_stmt_pass_lower_get_module_type ("main.main",
581 &module_ctx)
584 // free (context.array);
586 return retval;