[PATCH, MELT] fixing upgrade-warmelt target
Hello, I am trying to fix upgrade-warmelt into last revision of MELT. We are using some move-if-change on meltdesc file (in melt-stage3 for example) to make a save (to a meltdesc\~) but we still need the meltdesc file for the generated files. So I replaced move-ifchange by a cp and it goes beyond (but there are still issues. Pierre Vittet Index: melt-build.tpl === --- melt-build.tpl (révision 178131) +++ melt-build.tpl (copie de travail) @@ -579,7 +579,7 @@ ENDFOR melt_translator_file+] [+FOR melt_translator_file+] @echo upgrading MELT translator [+base+] ## dont indent the [+base+]+meltdesc.c - $(melt_make_move) $(MELT_LAST_STAGE)/[+base+]+meltdesc.c $(MELT_LAST_STAGE)/[+base+]+meltdesc.c~; \ + cp $(MELT_LAST_STAGE)/[+base+]+meltdesc.c $(MELT_LAST_STAGE)/[+base+]+meltdesc.c~; \ sed s/$(MELT_LAST_STAGE)/MELT-STAGE-ZERO/g $(MELT_LAST_STAGE)/[+base+]+meltdesc.c > $(srcdir)/melt/generated/[+base+]+meltdesc.c for f in $(MELT_LAST_STAGE)/[+base+].c $(MELT_LAST_STAGE)/[+base+]+[0-9]*.c ; do \ bf=`basename $$f`; \ 2011-08-27 Pierre Vittet * melt-build.tpl (warmelt-upgrade-translator): replace move-if-change by a cp. Index: Makefile.in === --- Makefile.in (révision 178131) +++ Makefile.in (copie de travail) @@ -5516,7 +5516,7 @@ upgrade-warmelt: $(WARMELT_LAST) for f in $(wildcard meltrunsup*.[ch]); do \ cp $$f $$f-tmp; \ cp $(srcdir)/melt/generated/$$f $$f-old; \ - $(SHELL) $(srcdir)/../move-if-change $$f-tmp $(srcdir)/melt/generated/$$f; \ + $(SHELL) cp $$f-tmp $(srcdir)/melt/generated/$$f; \ done $(RM) melt-runtime.o melt-runtime.i s-gtype */warmelt*.o $(MAKE) s-gtype 2011-08-27 Pierre Vittet * Makefile.in (upgrade-warmelt): replace move-if-change by a cp.
Re: [PATCH, MELT, minor] add a primitive read_strv
Hello, this is a ping for http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01503.html. I thought this was integrated into MELT but it does not look to be in the current trunk. It just add a primitive read_strv allowing to use meltgc_read_from_val to get a list of s-expression from a boxed C string of a strbuf. Pierre Vittet Index: gcc/melt/warmelt-base.melt === --- gcc/melt/warmelt-base.melt (revision 176434) +++ gcc/melt/warmelt-base.melt (working copy) @@ -272,6 +272,11 @@ number $NUM opaque location number $LOC.}# :doc #{Read from file named by the $FILNAM string balue a list of MELT s-expressions.}# #{(meltgc_read_file (melt_string_str((melt_ptr_t)($filnam)), (char*)0))}#) +(defprimitive read_strv (strv) :value + :doc #{Return the list of sexpr contained in $STRV. $STRV can be a boxed + string or a strbuf value.}# + #{(meltgc_read_from_val ($strv, NULL))}# +) ;; to signal an error in a source with some additional string value (defprimitive error_strv (loc :cstring cmsg :value strv) :void @@ -2441,6 +2446,7 @@ polyhedron values.}# pair_set_head ppstrbuf_mixbigint read_file + read_strv register_pass_execution_hook register_pragma_handler register_pre_genericize_hook 2011-07-18 Pierre Vittet * melt/warmelt-base.melt (read_strv): New primitive.
[PATCH, MELT] add primitive isnull_tree
Hello, This is a small patch adding primitive isnull_tree (as there is already a primitive isnull_basicblock). Pierre Vittet Index: gcc/melt/xtramelt-ana-base.melt === --- gcc/melt/xtramelt-ana-base.melt (révision 178282) +++ gcc/melt/xtramelt-ana-base.melt (copie de travail) @@ -1447,12 +1447,15 @@ (defprimitive gimpleseq_content (v) :gimple_seq #{(melt_gimpleseq_content((melt_ptr_t)($v)))}# ) + - - (defprimitive is_tree (v) :long #{(melt_magic_discr((melt_ptr_t)($v)) == MELTOBMAG_TREE)}# ) +(defprimitive isnull_tree (:tree tr) :long + #{$tr == (tree)0}# +) + (defprimitive make_tree (discr :tree g) :value #{(meltgc_new_tree((meltobject_ptr_t)($discr),($g)))}# ) @@ -3597,7 +3600,8 @@ and discriminant $DIS, usually $DISCR_MIXED_LOCATI is_mapgimple is_maploop is_maptree - is_tree + is_tree + isnull_tree isnull_basicblock loop_body_tuple loop_can_be_parallel 2011-08-30 Pierre Vittet * melt/xtramelt-ana-base.melt(isnull_tree): Add primitive.
[PATCH, libiberty] correct md5_process_bytes with unaligned pointers
Hello, The patch is the result of the following threads: Here is a patch correcting md5_process_bytes when we are in the case of unaligned pointers.A pair of brace was missing, leading the buffer to be shift 2 times losing a part of its content. The patch also remove a preprocessor #if testing if _STRING_ARCH_unaligned is defined. This symbol is never defined in gcc and could be only used in CFLAGS. Looking at the code, it does not looks usefull to define it (and it is only tested on libiberty/md5.c and libiberty/sha1.c), as we already check the pointer alignement, so removing it clean the code. I searched on google, and it does not looks to be used. Does anyone want it or thing that it should not be removed? Ok for trunk ? Thanks! Pierre Vittet PS: I also write a small gcc plugin, allowing to easily test md5_process_bytes, if can change your environment in a way where the pointer buffer is not aligned, you should get the bug. Index: libiberty/md5.c === --- libiberty/md5.c (révision 178905) +++ libiberty/md5.c (copie de travail) @@ -227,7 +227,6 @@ md5_process_bytes (const void *buffer, size_t len, /* Process available complete blocks. */ if (len > 64) { -#if !_STRING_ARCH_unaligned /* To check alignment gcc has an appropriate operator. Other compilers don't. */ # if __GNUC__ >= 2 @@ -244,10 +243,11 @@ md5_process_bytes (const void *buffer, size_t len, len -= 64; } else -#endif - md5_process_block (buffer, len & ~63, ctx); - buffer = (const void *) ((const char *) buffer + (len & ~63)); - len &= 63; + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const void *) ((const char *) buffer + (len & ~63)); + len &= 63; + } } /* Move remaining bytes in internal buffer. */ 2011-09-16 Pierre Vittet * md5.c (md5_process_bytes): Remove unused _STRING_ARCH_unaligned, add missing braces. micro_plugin_md5.tar.gz Description: GNU Zip compressed data
Re: [PATCH, libiberty] correct md5_process_bytes with unaligned pointers
Hello, Ping! I would like to get a return on this patch. I don't know quite well the status of libiberty in GNU, please if I must this patch on another mailing list, please say me on which. Thanks! Pierre Vittet
[PATCH, MELT] correct meltgc_string_hex_md5sum_file_sequence
Hello Here is a patch allowing to compute correctly the md5 of a file sequence even with the bug rapported here: http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00963.html. The function will work with both gcc 4.6 without the patch and a gcc with the patch applied. The problem cames from the fact that we were calling md5_process_bytes several times with a buffer of a size which was not a multiple of 64. Doing so, the next buffer was modified to take those data in account and doing so, we had not always an aligned pointer. We now concatenate file stream and so we can have a buffer with a multiple of 64 size, so we can call md5_process_block. We only call md5_process_bytes for the last data. Thanks! Pierre Vittet 2011-09-19 Pierre Vittet * melt-runtime.c (meltgc_string_hex_md5sum_file_sequence): Concatenate files stream to call md5_process_block, we only call md5_process_bytes for the last datas. Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (révision 178881) +++ gcc/melt-runtime.c (copie de travail) @@ -5374,7 +5374,11 @@ melt_compile_source (const char *srcbase, const ch } /* compute the hexadecimal encoded md5sum string of a tuple of file -paths, or NULL on failure */ +paths, or NULL on failure. +When we finish to proceed a file, we immediatly add the beginning of the +following file to bufblock to keep a size of a multiple of 64. This permit +to call md5_process_block. We only call md5_process_bytes for the last +data. */ melt_ptr_t meltgc_string_hex_md5sum_file_sequence (melt_ptr_t pathtup_p) { @@ -5385,6 +5389,7 @@ melt_compile_source (const char *srcbase, const ch FILE *fil = NULL; int nbtup = 0; int cnt = 0; + int new_file_cnt = 0; struct md5_ctx ctx; MELT_ENTERFRAME(3, NULL); #define resv meltfram__.mcfr_varptr[0] @@ -5394,12 +5399,12 @@ melt_compile_source (const char *srcbase, const ch memset (&ctx, 0, sizeof(ctx)); memset (md5srctab, 0, sizeof (md5srctab)); memset (md5hex, 0, sizeof (md5hex)); - memset (bufblock, 0, sizeof (bufblock)); if (melt_magic_discr ((melt_ptr_t)pathtupv) != MELTOBMAG_MULTIPLE) goto end; md5_init_ctx (&ctx); nbtup = melt_multiple_length ((melt_ptr_t)pathtupv); /* this loop does not garbage collect! */ + memset (bufblock, 0, sizeof (bufblock)); for (ix=0; ix < nbtup; ix++) { const char *curpath = NULL; @@ -5414,22 +5419,33 @@ melt_compile_source (const char *srcbase, const ch goto end; while (!feof (fil)) { - memset (bufblock, 0, sizeof (bufblock)); - cnt = fread (bufblock, 1, sizeof(bufblock), fil); + if (cnt != 0) /*means that we havent process bufblock from previous + file.*/ +{ + new_file_cnt =fread (bufblock+cnt, sizeof(char),sizeof(bufblock)-cnt, fil); + cnt = cnt + new_file_cnt; + +} + else +{ + cnt = fread (bufblock, sizeof(char), sizeof(bufblock), fil); +} if (cnt ==sizeof(bufblock)) { /* an entire block has been read. */ - md5_process_bytes (bufblock, sizeof(bufblock), &ctx); + md5_process_block (bufblock, sizeof(bufblock), &ctx); + memset (bufblock, '\0', sizeof (bufblock)); + cnt = 0; } - else -{ - md5_process_bytes (bufblock, (size_t) cnt, &ctx); -} } fclose (fil); fil = NULL; curpath = NULL; } + if (cnt !=0) /*We still have some data in the buffer*/ + { + md5_process_bytes (bufblock, (size_t) cnt, &ctx); + } md5_finish_ctx (&ctx, md5srctab); memset (md5hex, 0, sizeof(md5hex)); for (ix=0; ix<16; ix++) {
[PATCH, MELT] add pragma support in MELT plugin
Hello, The following patch allows to use pragma in a MELT plugin. For exemple we can recover the following pragmas: #pragma GCCPLUGIN melt op or #pragma GCCPLUGIN melt op (arg1, arg2, ...) with argX a name, a string, or a number. It is easy to change the pragma space ("GCCPLUGIN") and name ("melt"), so I am open to suggestion. This plugin works on the MELT heart and so It need to regenerate the source. The first .diff (addPragma-warmelt-first) contains the gcc/melt/warmelt-first.melt file: I have added a field in the MELT class_system_data class which allows the user to add a function handling pragma. After adding this diff, it is needed to use 'make upgrade-warmelt' in the gcc directory to regenerate gcc/melt/generated. After this, it is possible to add the second diff (addPragma-runtime): it contains change in gcc/melt-runtime.c and gcc/melt-runtime.h: it adds the melt_pragma_callback which register the pragma handler defined in the same file. The pragma handler calls the function defined by the user and gives it the trees corresponding to the pragma operator and argument. I have been obliged to use weak symbols for pragma_lex and c_register_pragma as they are not defined when using lto. This is a temporary solution that I commented. I am going to send a test in the Testsuite, but I have already tried it successfully with something like that: (defun my_simple_pragma_handler(val1 lstarg) (debug_msg val1 "debugging melt pragma") ) (put_fields initial_system_data :sysdata_meltpragma_definer my_simple_pragma_handler ) Pierre Vittet Index: gcc/melt/warmelt-first.melt === --- gcc/melt/warmelt-first.melt (revision 174379) +++ gcc/melt/warmelt-first.melt (working copy) @@ -436,6 +436,7 @@ don't instanciate this class!}# sysdata_pass_dict;stringmap for passes sysdata_exit_finalizer ;;closure to be called after the passes, at finalization sysdata_meltattr_definer ;;closure to be called for melt attributes + sysdata_meltpragma_definer ;;closure to be called for melt pragma sysdata_patmacro_exporter;closure to export a patmacro sysdata_debugmsg ;closure for debugmsg sysdata_stdout ;raw file for stdout Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 174379) +++ gcc/melt-runtime.c (working copy) @@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not se #include "plugin.h" #include "cppdefault.h" +#include "c-pragma.h" #if BUILDING_GCC_VERSION > 4005 /* GCC 4.6 has realmpfr.h which includes */ #include "realmpfr.h" @@ -8930,7 +8931,124 @@ melt_attribute_callback(void *gcc_data ATTRIBUTE_U register_attribute(&melt_attr_spec); } +/*We declare weak functions because they cannot be linked when we use lto (it +loses langage specific informations). +If you use one of those functions you must check them to be not NULL. +*/ +extern enum cpp_ttype __attribute__((weak)) pragma_lex (tree *); +extern void __attribute__((weak)) c_register_pragma (const char *, const char +*, pragma_handler); +#define GCC_BAD(gmsgid) \ + do { warning (OPT_Wpragmas, gmsgid); goto end; } while (0) + + +void melt_handle_melt_pragma (melt_ptr_t optreev, melt_ptr_t listargtreev); + +/* handle a melt pragma*/ +static void +handle_melt_pragma (cpp_reader *ARG_UNUSED(dummy)) +{ + enum cpp_ttype token; + /*list containing the pragma argument*/ + tree x; + MELT_ENTERFRAME (3, NULL); +#define seqv meltfram__.mcfr_varptr[0] +#define treev meltfram__.mcfr_varptr[1] +#define optreev meltfram__.mcfr_varptr[2] + if(! pragma_lex || ! c_register_pragma) +GCC_BAD("Cannot use pragma symbol at this level (maybe you use -flto which \ +is incompatible)."); + + token = pragma_lex (&x); + if(token != CPP_NAME) +GCC_BAD ("malformed #pragma melt, ignored"); + optreev = meltgc_new_tree((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), x); + /*If the pragma has the form #pragma PLUGIN melt id (...) then optreev is the + tree containing "id". + Next element should be a parenthese opening. */ + token = pragma_lex (&x); + if (token != CPP_OPEN_PAREN){ +if (token != CPP_EOF) + GCC_BAD ("malformed #pragma melt, ignored"); + +else{ /* we have a pragma of the type '#pragma PLUGIN melt instr' */ + melt_handle_melt_pragma ((melt_ptr_t ) optreev, (melt_ptr_t ) NULL); +} + } + else{/* opening parenthesis */ +seqv = meltgc_new_list ((meltobject_ptr_t) MELT_PREDEF (DISCR_LIST)); +do { + token = pragma_lex (&x); + if(token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER) +
Re: [PATCH] c-pragma: adding a data field to pragma_handler
Thank you for your answer! I send you a new patch I have corrected the errors you raised. I have make my patch compatible with the old use of c_register_pragma and c_register_pragma_with_expansion. I don't know what is the best solution, maybe changing every call c_register_pragma allows to keep a more clear code. I can do it, if you think it is better. I have successfully compiled gcc with my patch and I have tried it with a modified version of gcc/testsuite/g++.dg/plugin/pragma_plugin.c. Pierre Vittet On 02/06/2011 19:51, Tom Tromey wrote: "Pierre" == Pierre writes: Pierre> I have changed this handler in order to accept a second parameter Pierre> which is a void *, allowing to give extra datas to the handler. I Pierre> think this data field might be of general use: we can have condition Pierre> or data at register time that we want to express in the handler. I Pierre> guess this is a common way to pass data to an handler function. I can't approve or reject this patch, but the idea seems reasonable enough to me. Pierre> I would like your opinion on this patch! Thanks! It has a number of formatting issues. Pierre> +typedef void (*pragma_handler)(struct cpp_reader *, void * ); No space after the final "*". Pierre> +/* Internally use to keep the data of the handler. */ Pierre> +struct internal_pragma_handler_d{ Space before the "{". Pierre> + pragma_handler handler; Pierre> + void * data; No space. Lots of instances of this. Pierre> /* A vector of registered pragma callbacks. */ Pierre> +/*This is never freed as we need it during the whole execution */ Coalesce the two comments. The comment formatting is wrong, see GNU standards. Pierre> ns_name.space = space; Pierre> ns_name.name = name; Pierre> + Pierre> VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas,&ns_name); Gratuitous newline addition. Pierre> + ihandler->handler = handler; Pierre> + ihandler->data = data; I didn't see anything that initialized ihandler. Pierre> + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, Pierre> +&ihandler); I think you wanted just `internal_pragma_handler ihandler', no "*", for the definition. Pierre> +c_register_pragma (const char *space, const char *name, pragma_handler handler, Pierre> + void * data) There are lots of calls to this that you did not update. Do a recursive grep to see. One way to avoid a massive change is to add a new "overload" that passes in the data to c_register_pragma_1; and then change the "legacy" functions to pass NULL. I don't know if that approach is ok (it is typical in gdb...), so if not, you have to update all callers. Tom Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -53,7 +53,7 @@ typedef struct GTY(()) align_stack { static GTY(()) struct align_stack * alignment_stack; -static void handle_pragma_pack (cpp_reader *); +static void handle_pragma_pack (cpp_reader *, void * data); /* If we have a "global" #pragma pack() in effect when the first #pragma pack(push,) is encountered, this stores the value of @@ -133,7 +133,7 @@ pop_alignment (tree id) #pragma pack (pop) #pragma pack (pop, ID) */ static void -handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy)) +handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data)) { tree x, id = 0; int align = -1; @@ -247,7 +247,7 @@ DEF_VEC_ALLOC_O(pending_weak,gc); static GTY(()) VEC(pending_weak,gc) *pending_weaks; static void apply_pragma_weak (tree, tree); -static void handle_pragma_weak (cpp_reader *); +static void handle_pragma_weak (cpp_reader *, void * data); static void apply_pragma_weak (tree decl, tree value) @@ -334,7 +334,7 @@ maybe_apply_pending_pragma_weaks (void) /* #pragma weak name [= value] */ static void -handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy)) +handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data)) { tree name, value, x, decl; enum cpp_ttype t; @@ -411,11 +411,12 @@ DEF_VEC_ALLOC_O(pending_redefinition,gc); static GTY(()) VEC(pending_redefinition,gc) *pending_redefine_extname; -static void handle_pragma_redefine_extname (cpp_reader *); +static void handle_pragma_redefine_extname (cpp_reader *, void * data); /* #pragma redefine_extname oldname newname */ static void -handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) +handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy), +void * ARG_UNUSED (data)) { tree oldname, newname, decl, x; enum cpp_ttype t; @@ -481,7 +482,8 @@ static GTY(()) tree
Re: [PATCH] c-pragma: adding a data field to pragma_handler
Hello, I am sorry, my editor (vim) was not correctly configure (I used http://gcc.gnu.org/ml/gcc/2011-03/msg00425.html to improve it). I guess it is ok now. If I still have issue, I will post on the mailing list if there is some tips for vim otherway I will use Emacs (I am not very comfortable with it for now ;). Pierre Vittet On 03/06/2011 17:47, Basile Starynkevitch wrote: On Fri, 03 Jun 2011 17:31:25 +0200 Pierre Vittet wrote: Thank you for your answer! I send you a new patch I have corrected the errors you raised. I have make my patch compatible with the old use of c_register_pragma and c_register_pragma_with_expansion. I find the patch quite interesting, but I cannot approve it. void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_handler_2arg handler, + void * data) Perhaps there are some spaces (vs tabs) issues here. Cheers Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } /* A vector of registered pragma callbacks. */ +/* This is never freed as we need it during the whole execution. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1216,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1235,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1249,90 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an +extra data field which can be used by the handler. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma +expansion as in the following exemple: + #define NUMBER 10 + #pragma count (NUMBER) +Name expansion is still disallowed. */ +void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, true); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, true); } +/* Register a C pragma handler, using a space and a name, it also carries an +extra data field which can be used by the handler. It allows pragma expansion +as in the following exemple: + #define NUMBER 10 + #pragma count (NUMBER) +Name expansion is still disallowed. */ void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_hand
Re: [PATCH] c-pragma: adding a data field to pragma_handler
I have written a test for this patch and run it (it works correctly). I guess there is no reason why it should not be accepted now. To recap, this patch add a void * data field to the pragma handler, allowing to pass extra data. If we want to use this field, we need to use the function c_register_pragma_with_data or c_register_pragma_with_expansion_and_data. The old c_register_pragma(_with_expansion) is kept compatible. I give two diff and two ChangeLog, the first are for the patch itself, the second are for the test. I have tried to make things as good as possible, if there is a remark, please, send me it. Especially, I am not sure about the format of my ChangeLog, if there is an issue, I am ready to change it. Changelog gcc: 2011-06-08 Pierre Vittet * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg, gen_pragma_handler, internal_pragma_handler, c_register_pragma, c_register_pragma_with_data, c_register_pragma_with_expansion, c_register_pragma_with_expansion_and_data): allows to add data to a pragma handler using a new c_register. Old c_register keep old behaviour for compatibility. * c-pragma.c (registered_pragmas, c_register_pragma_1, c_register_pragma, c_register_pragma_with_data, c_register_pragma_with_expansion, c_register_pragma_with_expansion_and_data, c_invoke_pragma_handler, init_pragma): allows to add data to a pragma handler using a new c_register. Old registers keep old behaviour for compatibility. Changelog testsuite 2011-06-08 Pierre Vittet * g++.dg/plugin/pragma_plugin_with_data.c: New test. Thanks! Pierre Vittet Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } /* A vector of registered pragma callbacks. */ +/* This is never freed as we need it during the whole execution. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1216,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1235,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1249,90 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an +extra data field which can be used by the handler. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma +expansion as in the following exemple: + #define NUMBER 10 + #pragma count (NUMBER) +Name expansion is still disallowed. */ +void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg
Re: [PATCH] c-pragma: adding a data field to pragma_handler
You are right, the new version is in the diff. The diff for the test hasn't changed and is in the previous mail. In the previous version of the file, the registered_pragmas was not better freed. I don't know if it is really important (it would need a callback at the end of the front-end passes). Thanks. On 09/06/2011 08:16, Basile Starynkevitch wrote: On Wed, 08 Jun 2011 23:26:39 +0200 Pierre Vittet wrote: I have written a test for this patch and run it (it works correctly). I guess there is no reason why it should not be accepted now. To recap, this patch add a void * data field to the pragma handler, allowing to pass extra data. If we want to use this field, we need to use the function c_register_pragma_with_data or c_register_pragma_with_expansion_and_data. The old c_register_pragma(_with_expansion) is kept compatible. === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } /* A vector of registered pragma callbacks. */ +/* This is never freed as we need it during the whole execution. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); Sorry to be picky Pierre, but that comment is not correct. It should be instead. /* A vector of registered pragma callbacks, which is never freed. */ What I mean is that you are right that the vector is never freed, but it is not because it is needed during the entire execution, since middle-end and back-end passes don't know about pragmas. I hope your patch will be ok-ed with that small change. Perhaps a future patch would free that registered_pragmas vector, but I feel that is not necessary, since it is not a big vector in practice. Regards. Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } } -/* A vector of registered pragma callbacks. */ +/* A vector of registered pragma callbacks, which is never freed. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1248,90 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an +extra data field which can be used by the handler. It disallows pragma +expansion (if you want it, use c_register_pragma_with_expansion instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma +expansion as in the following exemple: + #define NUMBER 10 + #pragma count (NUMBER) +Name expansion is stil
Re: [PATCH] c-pragma: adding a data field to pragma_handler
thanks! I formatted as you requested. I cannot commit myself as I haven't a "write after approval" status, maye you can do it, or I can wait my GSOC mentor, Basile Starynkevitch to do this (He mights be busy for a few days). Pierre Vittet Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } } -/* A vector of registered pragma callbacks. */ +/* A vector of registered pragma callbacks, which is never freed. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion_and_data + instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ +void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, true); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, true); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, true); +} + +void c_invoke_pragma_handler (unsigned int id) { - pragma_handler handler; + internal_pragma_handler *ihandler; + pragma_handler_1arg handler_1arg; + pragma_handler_2arg handler_2arg; id -= PRAGMA_FIRST_EXTERNAL; - handler = *VEC_index (pragma_handler, registered_pragmas, id); - - handler (parse_in); + ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id); + if (ihandler->extra_data) +{ +
Re: [PATCH] c-pragma: adding a data field to pragma_handler
I guess this is better now. Changelog (gcc/c-family): 2011-06-10 Pierre Vittet * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg): New handler. (gen_pragma_handler): New union. (internal_pragma_handler): New type. (c_register_pragma_with_data, c_register_pragma_with_expansion_and_data): New functions. * c-pragma.c (registered_pragmas, c_register_pragma_1, c_register_pragma, c_register_pragma_with_expansion, c_invoke_pragma_handler): Changed to work with internal_pragma_handler. (c_register_pragma_with_data, c_register_pragma_with_expansion_and_data): New functions. Changelog (gcc/testsuite): 2011-06-10 Pierre Vittet * g++.dg/plugin/pragma_plugin_with_data.c: New test file. * g++.dg/plugin/pragma_plugin_with_data-test-1.C: New test file. * g++.dg/plugin/plugin.exp (plugin_test_list): Add the new test Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } } -/* A vector of registered pragma callbacks. */ +/* A vector of registered pragma callbacks, which is never freed. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion_and_data + instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ +void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, true); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, true); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data) +{ + internal_pragma
[APPROVED PATCH] c-pragma: adding a data field to pragma_handler
Thoses two patchs have already been approved (see http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01159.html). I haven't write permission currently, could someone commit them? ChangeLogs have to be applied on gcc/c-family/ChangeLog . Thanks ! Pierre Vittet Index: gcc/c-family/c-pragma.c === --- gcc/c-family/c-pragma.c (revision 174521) +++ gcc/c-family/c-pragma.c (working copy) @@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A } } -/* A vector of registered pragma callbacks. */ +/* A vector of registered pragma callbacks, which is never freed. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); +static VEC(internal_pragma_handler, heap) *registered_pragmas; -static VEC(pragma_handler, heap) *registered_pragmas; - typedef struct { const char *space; @@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char ** static void c_register_pragma_1 (const char *space, const char *name, -pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion_and_data + instead). */ void +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ +void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, true); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, true); } +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, true); +} + +void c_invoke_pragma_handler (unsigned int id) { - pragma_handler handler; + internal_pragma_handler *ihandler; + pragma_handler_1arg handler_1arg; + pragma_handler_2arg handler_2arg; id -= PRAGMA_FIRST_EXTERNAL; - handler = *VEC_index (pragma_handler, registered_pragmas, id); - - handler (parse_in); + ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id); + if (ihandler->extra_data) +{ +
[PATCH, MELT] fix minor issue with meltgc_new_split_string
Hello, I got a bug when using meltgc_new_split_string (in melt-runtime.c) with a string (argument str) like this one "mystringanotherString" with the separator. The function is not working on a string that start with the separator. I guess this case can happen in real case, for exemple when an user give arguments with a space as a separator. The function was also not working properly on a string like this one: "firstStrsecondStr". With the patch, we get a correct list, ignoring the possible presence of a first separator and of separator immediatly followed by another. I took this opportunity to add a small comment to the function (in the second diff). ChangeLog 2011-06-21 Pierre Vittet * melt-runtime.c (meltgc_new_split_string): Fix issue. 2011-06-21 Pierre Vittet * melt-runtime.c (meltgc_new_split_string): Add comment. Pierre Vittet Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175247) +++ gcc/melt-runtime.c (working copy) @@ -4638,6 +4638,12 @@ meltgc_new_split_string (const char*str, int sep, { cursep = NULL; strv = NULL; + /* avoid errors when we have str which starts with the separator or when + we have a separator immediatly followed by another one (like + 'first::second'). + */ + while (*pc == sep) +pc++; if (ISSPACE (sep)) for (cursep=pc; *cursep && !ISSPACE (*cursep); cursep++); else Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175247) +++ gcc/melt-runtime.c (working copy) @@ -4604,7 +4604,8 @@ end: #undef str_strv } - +/* Split a string into a list of string value using sep as separating character. +*/ melt_ptr_t meltgc_new_split_string (const char*str, int sep, melt_ptr_t discr_p) {
[PATCH, MELT] loading extra module before setting options
Hello, In the function load_melt_modules_and_do_mode of melt-runtime.c, we first load initial modules, then we set options, and then we look at extra modules. With this patch, we load extra modules before we set options, because extra modules can contain code to handle options. This change has been compiled and tested without errors. ChangeLog: 2011-06-22 Pierre Vittet * melt-runtime.c (load_melt_modules_and_do_mode): load extra module before setting options Pierre Vittet Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175330) +++ gcc/melt-runtime.c (working copy) @@ -8721,65 +8721,6 @@ load_melt_modules_and_do_mode (void) } /** - * Then we set MELT options. - **/ - MELT_LOCATION_HERE ("before setting options"); - optstr = melt_argument ("option"); - debugeprintf ("load_initial_melt_modules optstr %s", optstr); - if (optstr && optstr[0] - && (optsetv=melt_get_inisysdata (FSYSDAT_OPTION_SET)) != NULL - && melt_magic_discr ((melt_ptr_t) optsetv) == MELTOBMAG_CLOSURE) -{ - char *optc = 0; - char *optname = 0; - char *optvalue = 0; - for (optc = CONST_CAST (char *, optstr); - optc && *optc; - ) - { - optname = optvalue = NULL; - if (!ISALPHA(*optc)) - melt_fatal_error ("invalid MELT option name %s [should start with letter]", - optc); - optname = optc; - while (*optc && (ISALNUM(*optc) || *optc=='_' || *optc=='-')) - optc++; - if (*optc == '=') { - *optc = (char)0; - optc++; - optvalue = optc; - while (*optc && *optc != ',') - optc++; - } - if (*optc==',') { - *optc = (char)0; - optc++; - } - optsymbv = meltgc_named_symbol (optname, MELT_CREATE); - { - union meltparam_un pararg[1]; - memset (¶rg, 0, sizeof (pararg)); - pararg[0].meltbp_cstring = optvalue; - MELT_LOCATION_HERE ("option set before apply"); - debugeprintf ("MELT option %s value %s", optname, - optvalue?optvalue:"_"); - optresv = - melt_apply ((meltclosure_ptr_t) optsetv, - (melt_ptr_t) optsymbv, - MELTBPARSTR_CSTRING, pararg, "", NULL); - if (!optresv) - warning (0, "unhandled MELT option %s", optname); - } - } - - /* after options setting, force a minor collection to ensure -nothing is left in young region */ - MELT_LOCATION_HERE ("option set done"); - melt_garbcoll (0, MELT_ONLY_MINOR); -} - MELT_LOCATION_HERE ("after setting options"); - - /** * Then we handle extra modules if given. **/ debugeprintf ("xtrastr %p %s", xtrastr, xtrastr); @@ -8845,6 +8786,65 @@ load_melt_modules_and_do_mode (void) debugeprintf ("no xtrastr %p", xtrastr); /** + * Then we set MELT options. + **/ + MELT_LOCATION_HERE ("before setting options"); + optstr = melt_argument ("option"); + debugeprintf ("load_initial_melt_modules optstr %s", optstr); + if (optstr && optstr[0] + && (optsetv=melt_get_inisysdata (FSYSDAT_OPTION_SET)) != NULL + && melt_magic_discr ((melt_ptr_t) optsetv) == MELTOBMAG_CLOSURE) +{ + char *optc = 0; + char *optname = 0; + char *optvalue = 0; + for (optc = CONST_CAST (char *, optstr); + optc && *optc; + ) + { + optname = optvalue = NULL; + if (!ISALPHA(*optc)) + melt_fatal_error ("invalid MELT option name %s [should start with letter]", + optc); + optname = optc; + while (*optc && (ISALNUM(*optc) || *optc=='_' || *optc=='-')) + optc++; + if (*optc == '=') { + *optc = (char)0; + optc++; + optvalue = optc; + while (*optc && *optc != ',') + optc++; + } + if (*optc==',') { + *optc = (char)0; + optc++; + } + optsymbv = meltgc_named_symbol (optname, MELT_CREATE); + { + union meltparam_un pararg[1]; + memset (¶rg, 0, sizeof (pararg)); + pararg[0].meltbp_cstring = optvalue; + MELT_LOCATION_HERE ("option set before apply"); + debugeprintf ("MELT option %s value %s", optname, + optvalue?optvalue:"_"); + optresv =
[PATCH, MELT] pragma support in MELT
Hello, This patch completes the pragma support in MELT. Now, a plugin can register several pragmas (with different name) in the following format (for GCC > 4.6): #pragma MELT (,...). This pragma can be easily handle in a MELT function, giving the operator and the list of arguments as parameters. For GCC<=4.6, there is a minimal pragma support, we can handle following pragma: #pragma GCCPLUGIN melt (,...) with only melt as name. ChangeLog: 2011-06-24 Pierre Vittet * melt-runtime.c (GCC_PRAGMA_BAD): Macro to return an error from the pragma handling system. [__GNUC__>4.6](melt_handle_melt_pragma, handle_melt_pragma, melt_pragma_callback): Add functions for full pragma handling. [__GNUC__<=4.6](melt_handle_melt_pragma, handle_melt_pragma, melt_pragma_callback): Add functions for limited pragma handling. (melt_startunit_callback): Register a callback for pragma. * Makefile.in (CFAMILYINC): We need c-family header in include headers. Index: gcc/Makefile.in === --- gcc/Makefile.in (revision 175348) +++ gcc/Makefile.in (working copy) @@ -359,6 +359,9 @@ DECNUMFMT = $(srcdir)/../libdecnumber/$(enable_dec DECNUMINC = -I$(DECNUM) -I$(DECNUMFMT) -I../libdecnumber LIBDECNUMBER = ../libdecnumber/libdecnumber.a +#c-family header +CFAMILYINC=-I$(srcdir)/c-family + # Target to use when installing include directory. Either # install-headers-tar, install-headers-cpio or install-headers-cp. INSTALL_HEADERS_DIR = @build_install_headers_dir@ @@ -1096,8 +1099,8 @@ INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@ -I$(srcdir)/melt/generated \ -I$(srcdir)/../include @INCINTL@ \ $(CPPINC) $(GMPINC) $(DECNUMINC) \ - $(PPLINC) $(CLOOGINC) - + $(PPLINC) $(CLOOGINC) \ + $(CFAMILYINC) .c.o: $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION) Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175348) +++ gcc/melt-runtime.c (working copy) @@ -74,7 +74,9 @@ along with GCC; see the file COPYING3. If not se #include "md5.h" #include "plugin.h" #include "cppdefault.h" +#include "c-pragma.h" + #if BUILDING_GCC_VERSION > 4005 /* GCC 4.6 has realmpfr.h which includes */ #include "realmpfr.h" @@ -8938,7 +8940,284 @@ melt_attribute_callback(void *gcc_data ATTRIBUTE_U register_attribute(&melt_attr_spec); } +/* We declare weak functions because they cannot be linked when we use lto (it + loses langage specific informations). + If you use one of those functions you must check them to be not NULL. +*/ +extern enum cpp_ttype __attribute__((weak)) pragma_lex (tree *); + + +#define GCC_PRAGMA_BAD(gmsgid) \ + do { warning (OPT_Wpragmas, gmsgid); goto end; } while (0) + + + +/* Test for GCC > 4.6.0 */ +#if __GNUC__ > 4 || \ +(__GNUC__ == 4 && (__GNUC_MINOR__ > 6)) +/*Full pragma with data support.*/ + +void melt_handle_melt_pragma (melt_ptr_t optreev, melt_ptr_t listargtreev, + int indice_handler); + +extern void __attribute__((weak)) c_register_pragma_with_expansion_and_data +(const char *space, const char *name, + pragma_handler_2arg handler, void *data); + +/* handle a melt pragma: data contain the name of the command (as a string)*/ +static void +handle_melt_pragma (cpp_reader *ARG_UNUSED(dummy), void * data) +{ + enum cpp_ttype token; + /*list containing the pragma argument*/ + tree x; + int ihandler = (int) data; + MELT_ENTERFRAME (3, NULL); +#define seqv meltfram__.mcfr_varptr[0] +#define treev meltfram__.mcfr_varptr[1] +#define optreev meltfram__.mcfr_varptr[2] + if(! pragma_lex || ! c_register_pragma_with_expansion_and_data) +GCC_PRAGMA_BAD("Cannot use pragma symbol at this level \ + (maybe you use -flto which is incompatible)."); + + token = pragma_lex (&x); + if(token != CPP_NAME) +GCC_PRAGMA_BAD ("malformed #pragma melt, ignored"); + optreev = meltgc_new_tree((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), x); + /*If the pragma has the form #pragma PLUGIN melt id (...) then optreev is the + tree containing "id". + Next element should be a parenthese opening. */ + token = pragma_lex (&x); + if (token != CPP_OPEN_PAREN){ +if (token != CPP_EOF) + GCC_PRAGMA_BAD ("malformed #pragma melt, ignored"); + +else{ /* we have a pragma of the type '#pragma PLUGIN melt instr' */ + melt_handle_melt_pragma ((melt_ptr_t ) optreev, (melt_ptr_t ) NULL, + ihandler); +} + } + else{/* opening parenthesis */ +seqv = meltgc_new_list ((meltobject_ptr_t) MELT_PREDEF (DISCR_LIST)); +do { +
[PATCH, MELT] correct meltgc_read_from_val without location
Hello, The function meltgc_read_from_val (in melt-runtime.c) takes two arguments, a string value and a second one which is a location. In the comments, it is written that we can pass a NULL pointer if we have no location (it is a direct string). However, this conduct MELT to crash because it doesn't handle correctly the absence of file. This patch correct this, if there is no file, it create a "virtual" one which is named "stringBuffer". Pierre Vittet Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175348) +++ gcc/melt-runtime.c (working copy) @@ -6326,7 +6326,7 @@ melt_linemap_compute_current_location (struct read { int colnum = 1; int cix = 0; - if (!rd || !rd->rcurlin) + if (!rd || !rd->rcurlin || !rd->rpfilnam) return; for (cix=0; cixrcol; cix++) { char c = rd->rcurlin[cix]; @@ -6702,13 +6702,22 @@ static melt_ptr_t makesexpr (struct reading_st *rd, int lineno, melt_ptr_t contents_p, location_t loc, bool ismacrostring) { - MELT_ENTERFRAME (4, NULL); + MELT_ENTERFRAME (5, NULL); #define sexprv meltfram__.mcfr_varptr[0] #define contsv meltfram__.mcfr_varptr[1] #define locmixv meltfram__.mcfr_varptr[2] #define sexpclassv meltfram__.mcfr_varptr[3] +#define locnamv meltfram__.mcfr_varptr[4] contsv = contents_p; gcc_assert (melt_magic_discr ((melt_ptr_t) contsv) == MELTOBMAG_LIST); + /* If there is no filename associated, we create a false one, named +"stringBuffer". */ + if(rd->rpfilnam == NULL) +{ + locnamv = meltgc_new_string ((meltobject_ptr_t) MELT_PREDEF(DISCR_STRING), + "stringBuffer"); + rd->rpfilnam = (melt_ptr_t *) &locnamv; +} if (loc == 0) locmixv = meltgc_new_mixint ((meltobject_ptr_t) MELT_PREDEF (DISCR_MIXED_INTEGER), *rd->rpfilnam, (long) lineno); @@ -6728,6 +6737,7 @@ makesexpr (struct reading_st *rd, int lineno, melt meltgc_touch (sexprv); MELT_EXITFRAME (); return (melt_ptr_t) sexprv; +#undef locnamv #undef sexprv #undef contsv #undef locmixv @@ -8414,6 +8424,7 @@ meltgc_read_from_val (melt_ptr_t strv_p, melt_ptr_ strv = strv_p; locnamv = locnam_p; rbuf = 0; + seqv = meltgc_new_list ((meltobject_ptr_t) MELT_PREDEF (DISCR_LIST)); strmagic = melt_magic_discr ((melt_ptr_t) strv); switch (strmagic) { @@ -8442,7 +8453,10 @@ meltgc_read_from_val (melt_ptr_t strv_p, melt_ptr_ rds.rlineno = 0; rds.rcurlin = rbuf; rd = &rds; - rds.rpfilnam = (melt_ptr_t *) & locnamv; + if(locnamv == NULL) +rds.rpfilnam = NULL; + else +rds.rpfilnam = (melt_ptr_t *) & locnamv; while (rdcurc ()) { bool got = FALSE; 2011-06-24 Pierre Vittet * melt-runtime.c (melt_linemap_compute_current_location, makesexpr, meltgc_read_from_val): Handle the case of reading a string sexp without given location.
Re: [PATCH, MELT] pragma support in MELT
Hello, This patch is an improvment of http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01861.html. It completes pragma support into MELT. Main changes are mostly comments improvments, better respect of coding standard and using long instead of int for pragma index when we have several pragmas being registered. I also removed the PRAGMA_BAD macro as it was said to be less readable, and changed malformed pragma warnings into errors. I tested the patch without seing any error or regression. Pierre Vittet 2011-07-03 Pierre Vittet * melt-runtime.c: include c-pragma.h. [__GNUC__>4.6] (melt_handle_melt_pragma, handle_melt_pragma, melt_pragma_callback): Add functions for full pragma handling. [__GNUC__<=4.6] (melt_handle_melt_pragma, handle_melt_pragma, melt_pragma_callback): Add functions for limited pragma handling. (melt_really_initialize): Register a callback for pragma. * Makefile.in (CFAMILYINC): We need c-family header in include headers. Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 175724) +++ gcc/melt-runtime.c (working copy) @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not se #include "md5.h" #include "plugin.h" #include "cppdefault.h" +#include "c-pragma.h" #if BUILDING_GCC_VERSION > 4005 /* GCC 4.6 has realmpfr.h which includes */ @@ -8982,7 +8983,296 @@ melt_attribute_callback(void *gcc_data ATTRIBUTE_U register_attribute(&melt_attr_spec); } +/* We declare weak functions because they cannot be linked when we use lto (it + loses langage specific informations). + If you use one of those functions you must check them to be not NULL. +*/ +extern enum cpp_ttype __attribute__((weak)) pragma_lex (tree *); +/* Test for GCC > 4.6.0. */ +#if __GNUC__ > 4 || \ +(__GNUC__ == 4 && (__GNUC_MINOR__ > 6)) +/* Full pragma with data support. */ + +/* Call the MELT function which handle pragma: it is one of the handler of the + list sysdata_meltpragmas. First argument is a tree containing the operator + and the second argument contains a list of tree (the arguments of the + pragma). Third argument is the index of the handler to use (in list + sysdata_meltpragmas). */ +void melt_handle_melt_pragma (melt_ptr_t optreev, melt_ptr_t listargtreev, + long i_handler); + +extern void __attribute__((weak)) c_register_pragma_with_expansion_and_data +(const char *space, const char *name, + pragma_handler_2arg handler, void *data); + +/* Handle a melt pragma: data contains the index of the pragma handler. */ +static void +handle_melt_pragma (cpp_reader *ARG_UNUSED(dummy), void *data) +{ + enum cpp_ttype token; + /* List containing the pragma arguments . */ + tree x; + long i_handler = (long) data; + MELT_ENTERFRAME (3, NULL); +#define seqv meltfram__.mcfr_varptr[0] +#define treev meltfram__.mcfr_varptr[1] +#define optreev meltfram__.mcfr_varptr[2] + if (!pragma_lex || !c_register_pragma_with_expansion_and_data) +fatal_error ("Cannot use pragma symbol at this level \ + (maybe you use -flto which is incompatible)."); + + token = pragma_lex (&x); + if (token != CPP_NAME) +{ + error ("malformed #pragma melt, ignored"); + goto end; +} + optreev = meltgc_new_tree ((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), x); + /* If the pragma has the form #pragma MELT name id (...) then optreev is the + tree containing "id". */ + /* Next element should be a parenthesis opening. */ + token = pragma_lex (&x); + if (token != CPP_OPEN_PAREN) +{ + if (token != CPP_EOF) + { + error ("malformed #pragma melt, ignored"); + goto end; + } + else{ /* We have a pragma of the type '#pragma MELT name instr'. */ + melt_handle_melt_pragma ((melt_ptr_t ) optreev, (melt_ptr_t ) NULL, +i_handler); + } +} + else +{/* Opening parenthesis. */ + seqv = meltgc_new_list ((meltobject_ptr_t) MELT_PREDEF (DISCR_LIST)); + do + { + token = pragma_lex (&x); + if(token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER) + { + error ("malformed #pragma melt, ignored"); + goto end; + } + /* Convert gcc tree into a boxed tree. */ + treev = meltgc_new_tree ((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), + x); + /* Put the arg in IDENTIFIER_POINTER (x) in a list. */ + meltgc_append_list ((melt_ptr_t) seqv, (melt_ptr_t) treev); + token = pragma_lex (&x); + } while (
Re: C++ mangling, function name to mangled name (or tree)
On 06/07/2011 18:25, Kevin André wrote: On Wed, Jul 6, 2011 at 18:00, Pierre Vittet wrote: I would like user of the plugin to give in arguments the name of the functions on which he would like a test to be run. That means that I must convert the string containing a function name (like "myclass::init") and get either the mangled name or the tree corresponding to the function. I know that there might be several results (functions with the same name and different arguments), a good policy for me would be to recover every concerned functions (at least for the moment). I guess what I want to do is possible, because there are already some tools doing it (like gdb). Are you absolutely sure about gdb? It could be doing it the other way around, i.e. start from the mangled names in the object file and demangle all of them. Then it would search for a function name in its list of demangled names. Just guessing, though :) Regards, Kevin André Hello, no I am not sure, but I guess it would really have an important cost to do it like you said. Would it no be easier to have a field containing the 'demangled' names? At least in debug since it has an important space complexity. Thanks! Pierre Vittet
[PATCH, MELT] new function register_data_handler
Hi, this patch add a new function allowing to add a pragma handler more easily. In the past, we were directly modifying the :sysdata_meltpragmas field of initial_system_data. The pragma handler take a list of new pragma handler that we want to add. The reason is that the field :sysdata_meltpragmas is a tuple (fixed size, this is a mandatory because we uses index to recognize the handler later). Each time we call register_data_handler, we recreate the tuple, so we try to give a list of handler to call it not to often. This function should works with a GCC 4.6 but should be used with care, as we can only register a single pragma named "melt" (maybe we could use another function specially for 4.6 ?). Thanks! Pierre Vittet 2011-07-07 Pierre Vittet * melt/warmelt-base.melt (register_pragma_handler ): new function. Index: gcc/melt/warmelt-base.melt === --- gcc/melt/warmelt-base.melt (revision 175906) +++ gcc/melt/warmelt-base.melt (working copy) @@ -1135,6 +1135,42 @@ registered with $REGISTER_PASS_EXECUTION_HOOK.}# }#) ))) +;;register a new pragma handler. +(defun register_pragma_handler (lsthandler) + :doc #{register a list of new pragma handlers. As :sysdata_meltpragmas must + be a tuple (we use an index to recognize handlers), we have to recreate this + tuple each time we call this function. That why $LSTHANDLER is a list of + handlers (class_gcc_pragma) and not a single object. }# + (assert_msg "register_pragma_handler takes a list as argument." +(is_list lsthandler)) + (let ((oldtuple (get_field :sysdata_meltpragmas initial_system_data)) +(:long oldsize 0)) +(if notnull oldtuple) + (setq oldsize (multiple_length oldtuple)) +(let ((:long newsize (+i (multiple_length oldtuple) + (list_length lsthandler))) + (newtuple (make_multiple discr_multiple newsize)) + (:long i 0)) +;;copy in oldhandlers in the newtuple +(foreach_in_multiple +(oldtuple) +(curhander :long iunused) + (multiple_put_nth newtuple i curhander) + (setq i (+i i 1)) +) +;;add new handler from lsthandler +(foreach_in_list +(lsthandler) +(curpair curhandler) + (assert_msg "register_pragma_handler must be a list of class_gcc_pragma." +(is_a curhandler class_gcc_pragma)) + (multiple_put_nth newtuple i curhandler) + (setq i (+i i 1)) +) +(put_fields initial_system_data :sysdata_meltpragmas newtuple) +)) +) + the descriptions of values which are not ctype related. (defclass class_value_descriptor @@ -2361,6 +2397,7 @@ polyhedron values.}# ppstrbuf_mixbigint read_file register_pass_execution_hook + register_pragma_handler retrieve_value_descriptor_list some_integer_greater_than some_integer_multiple
[PATH, MELT] correct makefile, install-default-module-list
Hello, To compile the last revision of the MELT branch, I have been obliged to do the following change in the Makefile: We were trying to install the file gcc/melt-default-modules which doesn't exist, we now install melt-default-modules.modlis. The loops installing the different /melt-default-modules-*.modlis was incorrect, a ';' was missing in the install instruction. Pierre Vittet 2011-07-15 Pierre Vittet * Makefile.in (install-melt-default-modules-list): Fix bad file call. Index: gcc/Makefile.in === --- gcc/Makefile.in (revision 176307) +++ gcc/Makefile.in (working copy) @@ -5473,9 +5473,9 @@ install-melt-mk: melt-module.mk ## install the default modules list install-melt-default-modules-list: $(melt_default_modules_list).modlis $(wildcard $(melt_default_modules_list)-*.modlis) - $(INSTALL_DATA) $(melt_default_modules_list) $(DESTDIR)/$(melt_module_dir) - for f in $(wildcard $(melt_default_modules_list)-*.modlis) ; do \ - $(INSTALL_DATA) $$f $(DESTDIR)/$(melt_module_dir) \ + $(INSTALL_DATA) $(melt_default_modules_list).modlis $(DESTDIR)/$(melt_module_dir) + for f in $(wildcard $(melt_default_modules_list)-*.modlis) ; do \ + $(INSTALL_DATA) $$f $(DESTDIR)/$(melt_module_dir); \ done this phony target is given manually to copy the generated
[PATCH, MELT] Add PRE_GENERICIZE callback support in MELT
Hello, The following patch add support for PLUGIN_PRE_GENERICIZE callback. The add_sysdata_pre_genericize patch add a field (sysdata_pre_genericize) in initial system data, allowing to register a closure to be called on PLUGIN_PRE_GENERICIZE event. This patch must be first applied and a make warmelt-upgrade must be run in order to regenerate generated melt files. The add_pre_genericize_hook patch add a function (in melt-runtime.c) to be called on PLUGIN_PRE_GENERICIZE, which call the closure sysdata_pre_genericize defined by the users. Thanks Pierre Vittet 2011-07-15 Pierre Vittet * melt-runtime.h (enum FSYDAT*): Add a FSYSDAT_PRE_GENERICIZE field. * melt/warmelt-first.melt (class_system_data): add a sysdata_pre_genericize field. Index: gcc/melt/warmelt-first.melt === --- gcc/melt/warmelt-first.melt (revision 176032) +++ gcc/melt/warmelt-first.melt (working copy) @@ -441,6 +441,8 @@ don't instanciate this class!}# sysdata_stdout ;raw file for stdout sysdata_stderr ;raw file for stderr sysdata_dumpfile ;raw file for dump_file + sysdata_pre_genericize ;closure to be called for PLUGIN_PRE_GENERICIZE: + ;look at gcc/c-decl.c. sysdata_unit_starter ;closure to be called at ;compilation unit start sysdata_unit_finisher;closure to be called at Index: gcc/melt-runtime.h === --- gcc/melt-runtime.h (revision 176032) +++ gcc/melt-runtime.h (working copy) @@ -2324,6 +2324,7 @@ enum FSYSDAT_STDOUT, /* raw boxed file for stdout */ FSYSDAT_STDERR, /* raw boxed file for stderr */ FSYSDAT_DUMPFILE,/* raw boxed file for dump_file */ + FSYSDAT_PRE_GENERICIZE, /* closure for PLUGIN_PRE_GENERICIZE */ FSYSDAT_UNIT_STARTER,/* closure for start of compilation unit */ FSYSDAT_UNIT_FINISHER,/* closure for start of compilation unit */ FSYSDAT_OPTION_SET, /* closure to set options */ 2011-07-15 Pierre Vittet * melt-runtime.c (melt_really_initialize): Register a new Callback to PLUGIN_PRE_GENERICIZE. (melt_pre_genericize_callback): New function, use field sysdata_pre_genericize to transmit the callbacks. 2011-07-15 Pierre Vittet * melt-runtime.c (melt_really_initialize): Register a new Callback to PLUGIN_PRE_GENERICIZE. (melt_pre_genericize_callback): New function, use field sysdata_pre_genericize to transmit the callbacks.
Re: [PATCH, MELT] Add PRE_GENERICIZE callback support in MELT
Right, here is the new version of the patch (with the correct files). I added, a function register_pre_genericize_hook in melt/warmelt-base.melt to be called when we want to register a MELT function to handle the callback, so we don't manually set sysdata_pre_genericize field. Pierre Vittet On 15/07/2011 18:41, Romain Geissler wrote: Le 15 juil. 2011 à 18:17, Pierre Vittet a écrit : Hello, The following patch add support for PLUGIN_PRE_GENERICIZE callback. The add_sysdata_pre_genericize patch add a field (sysdata_pre_genericize) in initial system data, allowing to register a closure to be called on PLUGIN_PRE_GENERICIZE event. This patch must be first applied and a make warmelt-upgrade must be run in order to regenerate generated melt files. The add_pre_genericize_hook patch add a function (in melt-runtime.c) to be called on PLUGIN_PRE_GENERICIZE, which call the closure sysdata_pre_genericize defined by the users. Thanks Pierre Vittet Great ! You forgot to attach the patch for melt-runtime.c (there is only the changelog) I know your performing some simple static analysis, mostly based on matching some c source code patterns (check that there is a if (fopen_result) just after a fopen. Is there a particular reason to do that as a pass (so at the gimple level) rather that doing it just after the function has been parsed (eg upon PLUGIN_PRE_GENERICIZE) ? 2011-07-15 Pierre Vittet * melt-runtime.h (enum FSYDAT*): Add a FSYSDAT_PRE_GENERICIZE field. * melt/warmelt-first.melt (class_system_data): add a sysdata_pre_genericize field. Index: gcc/melt/warmelt-first.melt === --- gcc/melt/warmelt-first.melt (revision 176032) +++ gcc/melt/warmelt-first.melt (working copy) @@ -441,6 +441,8 @@ don't instanciate this class!}# sysdata_stdout ;raw file for stdout sysdata_stderr ;raw file for stderr sysdata_dumpfile ;raw file for dump_file + sysdata_pre_genericize ;closure to be called for PLUGIN_PRE_GENERICIZE: + ;look at gcc/c-decl.c. sysdata_unit_starter ;closure to be called at ;compilation unit start sysdata_unit_finisher;closure to be called at Index: gcc/melt-runtime.h === --- gcc/melt-runtime.h (revision 176032) +++ gcc/melt-runtime.h (working copy) @@ -2324,6 +2324,7 @@ enum FSYSDAT_STDOUT, /* raw boxed file for stdout */ FSYSDAT_STDERR, /* raw boxed file for stderr */ FSYSDAT_DUMPFILE,/* raw boxed file for dump_file */ + FSYSDAT_PRE_GENERICIZE, /* closure for PLUGIN_PRE_GENERICIZE */ FSYSDAT_UNIT_STARTER,/* closure for start of compilation unit */ FSYSDAT_UNIT_FINISHER,/* closure for start of compilation unit */ FSYSDAT_OPTION_SET, /* closure to set options */ 2011-07-15 Pierre Vittet * melt-runtime.c (melt_really_initialize): Register a new Callback to PLUGIN_PRE_GENERICIZE. (melt_pre_genericize_callback): New function, use field sysdata_pre_genericize to transmit the callbacks. * melt/warmelt-base.melt (register_pre_genericize_hook): New function. Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 176032) +++ gcc/melt-runtime.c (working copy) @@ -9044,6 +9044,35 @@ melt_pragma_callback (void *gcc_data ATTRIBUTE_UNU #endif /*GCC >4.6 for handling pragma support*/ + +/* This function is used when PLUGIN_PRE_GENERICIZE callback is invoked. It + calls the closure registered in field sydata_pre_genericize of + initial_system_data. The first argument is the tree containing the function + declaration (as given in file gcc/c-decl.c). */ +static void +melt_pre_genericize_callback (void *ptr_fndecl, + void *user_data ATTRIBUTE_UNUSED) +{ + MELT_ENTERFRAME (2, NULL); +#define pregenclosv meltfram__.mcfr_varptr[0] +#define fndeclv meltfram__.mcfr_varptr[1] + fndeclv = meltgc_new_tree ((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), +((tree) ptr_fndecl)); + pregenclosv = melt_get_inisysdata (FSYSDAT_PRE_GENERICIZE); + if (melt_magic_discr ((melt_ptr_t) pregenclosv) == MELTOBMAG_CLOSURE) +{ + MELT_LOCATION_HERE + ("melt_pre_genericize befire applying pre_genericize closure"); + (void) melt_apply ((meltclosure_ptr_t) pregenclosv, (melt_ptr_t) fndeclv, +"", NULL, "", NULL); +} + MELT_EXITFRAME (); +#undef fndeclv +#undef pregenclosv +} + + + /* the plugin callback when starting a compilation unit */ static void melt_startunit_callback(void *gc
[PATCH, MELT, minor] add a primitive read_strv
Hello, This minor patch add a primitive to get a list of s-expression from a boxed C string of a strbuf. This is only the MELT part, as the called C code was already written. I compiled and test it. Thanks! Pierre Vittet 2011-07-18 Pierre Vittet * melt/warmelt-base.melt (read_strv): New primitive. Index: gcc/melt/warmelt-base.melt === --- gcc/melt/warmelt-base.melt (revision 176434) +++ gcc/melt/warmelt-base.melt (working copy) @@ -272,6 +272,11 @@ number $NUM opaque location number $LOC.}# :doc #{Read from file named by the $FILNAM string balue a list of MELT s-expressions.}# #{(meltgc_read_file (melt_string_str((melt_ptr_t)($filnam)), (char*)0))}#) +(defprimitive read_strv (strv) :value + :doc #{Return the list of sexpr contained in $STRV. $STRV can be a boxed + string or a strbuf value.}# + #{(meltgc_read_from_val ($strv, NULL))}# +) ;; to signal an error in a source with some additional string value (defprimitive error_strv (loc :cstring cmsg :value strv) :void @@ -2441,6 +2446,7 @@ polyhedron values.}# pair_set_head ppstrbuf_mixbigint read_file + read_strv register_pass_execution_hook register_pragma_handler register_pre_genericize_hook
[PATCH, MELT] correct function meltgc_string_hex_md5sum_file_sequence
Hello, this patch correct the function meltgc_string_hex_md5sum_file_sequence, it now returns the same than "cat myfile1 myfile2 ... | md5sum". fread was not correctly used + it looks like you can't mix function md5_process_bytes and md5_process_blocks. Pierre Vittet Index: gcc/melt-runtime.c === --- gcc/melt-runtime.c (revision 176817) +++ gcc/melt-runtime.c (working copy) @@ -5426,6 +5426,7 @@ meltgc_string_hex_md5sum_file_sequence (melt_ptr_t char bufblock[1024]; /* size should be multiple of 64 for md5_process_block */ FILE *fil = NULL; int nbtup = 0; + int cnt = 0; struct md5_ctx ctx = {}; MELT_ENTERFRAME(3, NULL); #define resv meltfram__.mcfr_varptr[0] @@ -5456,16 +5457,14 @@ meltgc_string_hex_md5sum_file_sequence (melt_ptr_t while (!feof (fil)) { memset (bufblock, 0, sizeof (bufblock)); - if (fread (bufblock, sizeof(bufblock), 1, fil)==1) + cnt = fread (bufblock, 1, sizeof(bufblock), fil); + if (cnt ==sizeof(bufblock)) { /* an entire block has been read. */ - md5_process_block (bufblock, sizeof(bufblock), &ctx); + md5_process_bytes (bufblock, sizeof(bufblock), &ctx); } else { - int cnt = fread (bufblock, 1, sizeof(bufblock), fil); - if (cnt <= 0) - break; md5_process_bytes (bufblock, (size_t) cnt, &ctx); } } 2011-07-27 Pierre Vittet * melt-runtime.c (meltgc_string_hex_md5sum_file_sequence): Correct fread use + only use md5_process_bytes
[PATCH, MELT] fix useless forcing of GCC garbage collector
This patch is for the MELT branch. My GCC contributor number is 634276. After speaking with Basile Starynkevitch, we saw that there might be a useless forcing of the garbage collector in melt-runtime.c . I tested with the patch, and I haven't seen any problem (I could compile GCC, using a MELT plugin with the patched version). I have also measured a small time improvement while compiling the file gcc.c (which is more that 8000 lines): Whithout the modification: usersys 1.563 0.145s With the modification: usersys 1.144 0.106s Changelog: 2011-05-09 Pierre Vittet * melt-runtime.c: Remove variable forcing the garbage collector while it was not needed. Thanks Pierre Vittet Index: melt-runtime.c === --- melt-runtime.c (revision 173571) +++ melt-runtime.c (working copy) @@ -1159,16 +1159,13 @@ melt_nb_garbcoll, melt_startalz, melt_endalz); if (needfull) { - bool wasforced = ggc_force_collect; melt_nb_full_garbcoll++; debugeprintf ("melt_garbcoll #%ld fullgarbcoll #%ld", melt_nb_garbcoll, melt_nb_full_garbcoll); /* force major collection, with our callback */ - ggc_force_collect = true; - debugeprintf ("melt_garbcoll forcing fullgarbcoll #%ld", melt_nb_full_garbcoll); + debugeprintf ("melt_garbcoll calling gcc_collect #%ld", melt_nb_full_garbcoll); ggc_collect (); - ggc_force_collect = wasforced; - debugeprintf ("melt_garbcoll forced fullgarbcoll #%ld", melt_nb_full_garbcoll); + debugeprintf ("melt_garbcoll after fullgarbcoll #%ld", melt_nb_full_garbcoll); /* Delete the unmarked specials. */ prevspecptr = &melt_oldspeclist; for (specp = melt_oldspeclist; specp; specp = nextspecp)
Re: [PATCH, MELT] fix useless forcing of GCC garbage collector
Thanks you for the correction, I will take care next time. Pierre On 09/05/2011 19:03, Basile Starynkevitch wrote: On Mon, 09 May 2011 14:15:30 +0200 Pierre Vittet wrote: This patch is for the MELT branch. The diff file was slightly wrong (diff run under gcc/). Pierre, you should run svn diff -x -p at the top source directory to get a patch file. I applied the patch. The gcc/ChangeLog.MELT proposed by Pierre was wrong, I wrote: 2011-05-09 Pierre Vittet * melt-runtime.c (melt_garbcoll): Don't force collection by gcc_collect. Committed revision 173576. Folks, what is the procedure to get Pierre an svn+ssh write access to GCC svn server (mostly for the MELT branch, and write after approval for the rest). As far as I understood, all legal stuff has been completed. My GCC contributor number is 634276. This is the copyright assignment legal document reference for Pierre Vittet. What does he (or me) have to do to get svn+ssh://gcc.melt.org/ write access? Cheers.
Re: [PATCH] comment precising need to use free_dominance_info
So maybe this patch adding a comment on calculate_dominance_info is more adapted. ChangeLog: 2011-05-17 Pierre Vittet * dominance.c (calculate_dominance_info): Add comment precising when to free with free_dominance_info contributor number: 634276 Index: gcc/dominance.c === --- gcc/dominance.c (revision 173830) +++ gcc/dominance.c (working copy) @@ -628,8 +628,15 @@ compute_dom_fast_query (enum cdi_direction dir) } /* The main entry point into this module. DIR is set depending on whether - we want to compute dominators or postdominators. */ + we want to compute dominators or postdominators. + We try to keep dominance info alive as long as possible (to avoid + recomputing it often). It has to be freed with free_dominance_info when CFG + transformation makes it invalide. + + post_dominance info is less often used, and should be freed after each use. +*/ + void calculate_dominance_info (enum cdi_direction dir) {
[PATCH, MELT] correcting path error in the Makefile.in
This patch correct a bug in the current revision of MELT, which was preventing MELT to run correctly. This was a path problem in gcc/Makefile.in (melt-modules/ and melt-modules.mk) were not found. My contributor number is 634276. changelog : 2011-05-17 Pierre Vittet * Makefile.in : Correct path errors for melt_module_dir and for install-melt-mk target Index: gcc/Makefile.in === --- gcc/Makefile.in (revision 173832) +++ gcc/Makefile.in (working copy) @@ -5352,7 +5352,7 @@ melt_default_modules_list=melt-default-modules melt_source_dir=$(libexecsubdir)/melt-source/ ## this is the installation directory of melt dynamic modules (*.so) -melt_module_dir=$(libexecsubdir)/melt-module/ +melt_module_dir=$(libexecsubdir)/melt-modules/ ## this is the installed path of the MELT module makefile melt_installed_module_makefile=$(libexecsubdir)/melt-module.mk @@ -5416,8 +5416,8 @@ install-melt-modules: melt-modules melt-all-module ## install the makefile for MELT modules install-melt-mk: melt-module.mk - $(mkinstalldirs) $(DESTDIR)$(plugin_includedir) - $(INSTALL_DATA) $< $(DESTDIR)/$(plugin_includedir)/ + $(mkinstalldirs) $(DESTDIR)$(libexecsubdir) + $(INSTALL_DATA) $< $(DESTDIR)/$(libexecsubdir)/ ## install the default modules list install-melt-default-modules-list: $(melt_default_modules_list).modlis
[PATCH, MELT] add dominance functions
Hello, I have written a patch to allow the use of the GCC dominance functions into MELT. This is made in order to abstract the use of calculate_dominance_info and free_dominance_info: If the user use one of the MELT dominance related functions, it will only call calculate_dominance_info and register a call to free_dominance_info (at the end of the MELT pass) if the dominance info were not previously calculated. The idea is : - dominance info were already calculated (in a previous pass): -we can use dominance info and at the end of pass, no call is made to free_dominance_info (as we expect a next pass to use dominance info and to free only when necessary). -dominance info were not already calculated: -We first compute dominance info, use them during the pass and free them at the end of the plugin pass (as we don't expect a next pass to use it). Unsafe functions are only for internal use and so are not exported. I have compiled GCC MELT with the patch and successfully test the functions. Changelog: 2011-05-17 Pierre Vittet * melt/xtramelt-ana-base.melt (is_dominance_info_available, is_post_dominance_info_available, calculate_dominance_info_unsafe, calculate_post_dominance_info_unsafe, free_dominance_info, free_post_dominance_info, calculate_dominance_info, calculate_post_dominance_info, debug_dominance_info, debug_post_dominance_info, get_immediate_dominator_unsafe, get_immediate_dominator, get_immediate_post_dominator_unsafe, get_immediate_post_dominator, dominated_by_other_unsafe, dominated_by_other, post_dominated_by_other_unsafe, post_dominated_by_other, foreach_dominated_unsafe, dominated_by_bb_iterator): Add primitives, functions, iterators for using dominance info. Index: gcc/melt/xtramelt-ana-base.melt === --- gcc/melt/xtramelt-ana-base.melt (revision 173832) +++ gcc/melt/xtramelt-ana-base.melt (working copy) @@ -1910,6 +1910,242 @@ (defprimitive basicblock_nth_succ_edge (:basic_block bb :long ix) :edge #{(($bb && $ix>=0 && $ixsuccs))?EDGE_SUCC($bb,$ix):NULL)}#) +;Primitives concerning dominance in basic_blocks +;those functions mainly come from gcc/dominance.c + +(defprimitive is_dominance_info_available () :long + :doc #{Check if dominance info are already calculated. +User normally doesn't have to call this primitive, as MELT functions +check if there is a need to use this. +}# + #{dom_info_available_p(CDI_DOMINATORS)}# +) + +(defprimitive is_post_dominance_info_available () :long + :doc #{Check if post dominance info are already calculated. +User normally doesn't have to call this primitive, as MELT functions +check if there is a need to use this. + }# + #{dom_info_available_p(CDI_POST_DOMINATORS)}# +) + +(defprimitive calculate_dominance_info_unsafe() :void + :doc #{This primitive is internaly called, user doesn't need it. +Build the struct containing dominance info. +This struct is necessary to use others dominance related function. +This function is unsafe because it does not register any future call to +free_dominance_info. +}# + #{calculate_dominance_info(CDI_DOMINATORS)}# +) + +(defprimitive calculate_post_dominance_info_unsafe () :void + :doc #{This primitive is internaly called, user doesn't need it. +Build the struct containing post dominance info. +This struct is necessary to use other dominance related function. +This function is unsafe because it does not register any future call to +free_dominance_info. +}# + #{calculate_dominance_info(CDI_POST_DOMINATORS)}# +) + +(defprimitive free_dominance_info () :void + :doc #{This primitive is internaly called, user doesn't need it. + Clear dominance info if they have been allocated. + }# + #{free_dominance_info(CDI_DOMINATORS)}# +) + +(defprimitive free_post_dominance_info () :void + :doc #{This primitive is internaly called, user doesn't need it. + Clear post dominance info if they have been allocated. + }# + #{free_dominance_info(CDI_POST_DOMINATORS)}# +) + +(defun calculate_dominance_info() + :doc #{This primitive is internaly called, user doesn't need it. + Build the struct containing dominance info. + This struct is necessary to use other dominance related info. + It place a call to free dominance info when pass is finished if it is + necessary. + }# + (if (is_dominance_info_available) +() ;; do nothing +(progn ;; else calculate dom and ask to free them at end of pass + (calculate_dominance_info_unsafe) + (at_end_melt_pass_first free_dominance_info) +)) +) + +(defun calculate_post_dominance_info () + :doc #{This primitive is internaly called, user doesn't need it + Build the struct containing post dominance info. + This struct is necessary to use other p
Re: [PATCH, MELT] add dominance functions
I have corrected my patch with your remarks. Especially about the debug functions, it takes the debug melt flag into account. Moreover, I have allowed the user to give a message when calling this function, as usual in MELT debug functions. Giving this message was a bit difficult (This is the only argument of the function, so this must be a MELT value, and that uneasy to convert the value into :cstring). I have used debugeprintf macro into a code_chunk to give the MELT file + line numbers, followed by a outstr_err, which displays the user message. I think the only disavantage is that it puts an end of lines between the two informations. If you think there is a best way to do this, I am ok to try it. The new changelog: 2011-05-20 Pierre Vittet * melt/xtramelt-ana-base.melt (is_dominance_info_available, is_post_dominance_info_available, calculate_dominance_info_unsafe, calculate_post_dominance_info_unsafe, free_dominance_info, free_post_dominance_info, calculate_dominance_info, calculate_post_dominance_info, debug_dominance_info, debug_post_dominance_info, get_immediate_dominator_unsafe, get_immediate_dominator, get_immediate_post_dominator_unsafe, get_immediate_post_dominator, dominated_by_other_unsafe, dominated_by_other, post_dominated_by_other_unsafe, post_dominated_by_other, foreach_dominated_unsafe, dominated_by_bb_iterator): Add primitives, functions, iterators for using dominance info. On 19/05/2011 07:32, Basile Starynkevitch wrote: On Wed, 18 May 2011 21:04:39 +0200 Pierre Vittet wrote: Hello, I have written a patch to allow the use of the GCC dominance functions into MELT. [...] Changelog: 2011-05-17 Pierre Vittet * melt/xtramelt-ana-base.melt (is_dominance_info_available, is_post_dominance_info_available, calculate_dominance_info_unsafe, calculate_post_dominance_info_unsafe, free_dominance_info, free_post_dominance_info, calculate_dominance_info, calculate_post_dominance_info, debug_dominance_info, debug_post_dominance_info, get_immediate_dominator_unsafe, get_immediate_dominator, get_immediate_post_dominator_unsafe, get_immediate_post_dominator, dominated_by_other_unsafe, dominated_by_other, post_dominated_by_other_unsafe, post_dominated_by_other, foreach_dominated_unsafe, dominated_by_bb_iterator): Add primitives, functions, iterators for using dominance info. Thanks for the patch. Some minor tweaks: First, put a space between formal arguments list& function name. So +(defprimitive calculate_dominance_info_unsafe() :void should be +(defprimitive calculate_dominance_info_unsafe () :void Then, please put the defined name on the same line that defprimitive or defun or def... When consecutive MELT formals have the same ctype, you don't need to repeat it So +(defprimitive + dominated_by_other_unsafe(:basic_block bbA :basic_block bbB) :long should be +(defprimitive dominated_by_other_unsafe (:basic_block bbA bbB) :long In :doc strings, document when something is a boxed value (distinction between values& stuffs is crucial), so write instead [I added the boxed word, it is important] +(defun get_immediate_dominator (bb) + :doc#{Return the next immediate dominator of the boxed basic_block $BB as a MELT +value.}# At last, all debug* operations should only output debug to stderr only when flag_melt_debug is set and give the MELT source position (because we don't want any debug printing in the usual case when -fmelt-debug is not given to our cc1) Look at debugloop in xtramelt-ana-base.melt for an example (notice that debugeprintfnonl is a C macro printing the MELT source position. So please resubmit a slightly improved patch. Regards. Index: gcc/melt/xtramelt-ana-base.melt === --- gcc/melt/xtramelt-ana-base.melt (revision 173936) +++ gcc/melt/xtramelt-ana-base.melt (working copy) @@ -1871,7 +1871,6 @@ (defprimitive make_basicblock (discr :basic_block bb) :value #{/*make_basicblock*/(meltgc_new_basicblock((meltobject_ptr_t)($discr),($bb)))}# ) - (defprimitive basicblock_content (v) :basic_block #{(melt_basicblock_content((melt_ptr_t)($v)))}# ) @@ -1910,6 +1909,243 @@ (defprimitive basicblock_nth_succ_edge (:basic_block bb :long ix) :edge #{(($bb && $ix>=0 && $ixsuccs))?EDGE_SUCC($bb,$ix):NULL)}#) +;; Primitives concerning dominance in basic_blocks +;; those functions mainly come from gcc/dominance.c + +(defprimitive is_dominance_info_available () :long + :doc #{Check if dominance info are already calculated. +User normally doesn't have to call this primitive, as MELT functions +check if there is a need to use this.}# + #{dom_info_available_p(CDI_DOMINATORS)}# +) + +(defprimitive is_post_dominance_info_available () :long + :doc #{Check if
[Patch] get an order number on -fdump-tree-all
Hello, When we use fdump-tree-all, we get the dump file, however there is no way to know in which order the pass was executed. We can use gdb with a breakpoint at the good position (something like execute_one_pass), however this solution is not satisfiying for plugin devellopers for exemple. There is a number in the name of the dumpped file but from what I know it is a static number related to the pass but it has nothing to do with the order in which it is executed. I would enjoy to have a number, giving the pass position, something like : 1.cfile.c.XXXt.pass I have make a small change in tree-dump.c in order to have this working with -fdump-tree-all (patch file in attachment) The drawback is that, as the pass is called for each function, we get a different file for each function, while it was written in the same file previously. I am also surprized to see that the function print_current_pass is only called on a fail and that debug_pass doesn't appear to be called at all. Maybe in DEBUG, or at least with an f*_dump_all, we could print the order of the pass. thanks Pierre Vittet Index: gcc/tree-dump.c === --- gcc/tree-dump.c (revision 171340) +++ gcc/tree-dump.c (working copy) @@ -925,21 +925,35 @@ struct dump_file_info *dfi; FILE *stream; + /*allow to know how many pass have already been explored*/ + static int nb_explored_pass = 0; + /*add to the name a position at which the pass is explored*/ + char * name_with_pass_pos; + int name_with_pass_pos_size; + if (phase == TDI_none || !dump_enabled_p (phase)) return NULL; name = get_dump_file_name (phase); + name_with_pass_pos_size=sizeof(char)*strlen(name)+ sizeof(nb_explored_pass)+1; + name_with_pass_pos= (char*) xmalloc(name_with_pass_pos_size); + + snprintf (name_with_pass_pos, name_with_pass_pos_size, "%d.%s", nb_explored_pass, name); dfi = get_dump_file_info (phase); - stream = fopen (name, dfi->state < 0 ? "w" : "a"); + stream = fopen (name_with_pass_pos, dfi->state < 0 ? "w" : "a"); + if (!stream) error ("could not open dump file %qs: %m", name); else dfi->state = 1; free (name); + free (name_with_pass_pos); if (flag_ptr) *flag_ptr = dfi->flags; + nb_explored_pass++; + return stream; }