whereis asm_nodes? how to migrate it for GCC v6.x?
Hi GCC developers, There was extern GTY(()) struct asm_node *asm_nodes; for GCC v4.x, but how to migrate it for v6.x? there is no asm_nodes deprecated log in ChangeLog-201X nor git log cgraph.h... please give me some hint, thanks a lot! -- Regards, Leslie Zhai https://reviews.llvm.org/p/xiangzhai/
Re: whereis asm_nodes? how to migrate it for GCC v6.x?
Hi Segher, Thanks for your kind response! 在 2017年07月05日 18:52, Segher Boessenkool 写道: Hi Leslie, On Wed, Jul 05, 2017 at 05:36:15PM +0800, Leslie Zhai wrote: There was extern GTY(()) struct asm_node *asm_nodes; for GCC v4.x, but how to migrate it for v6.x? there is no asm_nodes deprecated log in ChangeLog-201X nor git log cgraph.h... please give me some hint, thanks a lot! symtab->first_asm_symbol ? yes! works for me :) such as: for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)... Segher -- Regards, Leslie Zhai https://reviews.llvm.org/p/xiangzhai/
How to migrate TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts for GCC v6.x?
Hi GCC developers, As ChangeLog-2014 mentioned, tree-pass.h (TODO_verify_ssa, TODO_verify_flow, TODO_verify_stmts...): Remove. When I am trying to migrate: static struct rtl_opt_pass pass_rtl_emit_function = { { RTL_PASS, "rtl_emit_function", /* name */ #if (GCC_MINOR >= 8) OPTGROUP_NONE, /* optinfo_flags */ #endif NULL, /* gate */ rtl_emit_function, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts } }; to GCC v6.x const pass_data pass_data_rtl_emit_function = { RTL_PASS, /* type */ "rtl_emit_function", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish,/* todo_flags_finish */ }; class pass_rtl_emit_function : public rtl_opt_pass { public: pass_rtl_emit_function(gcc::context *ctxt) : rtl_opt_pass(pass_data_rtl_emit_function, ctxt) {} virtual unsigned int execute(function *) { return rtl_emit_function(); } }; I have no idea how to choose the todo_flags_XXX, please give me some hint, thanks a lot! -- Regards, Leslie Zhai https://reviews.llvm.org/p/xiangzhai/
Re: How to migrate TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts for GCC v6.x?
在 2017年07月06日 17:02, Leslie Zhai 写道: Hi GCC developers, As ChangeLog-2014 mentioned, tree-pass.h (TODO_verify_ssa, TODO_verify_flow, TODO_verify_stmts...): Remove. When I am trying to migrate: static struct rtl_opt_pass pass_rtl_emit_function = { { RTL_PASS, "rtl_emit_function", /* name */ #if (GCC_MINOR >= 8) OPTGROUP_NONE, /* optinfo_flags */ #endif NULL, /* gate */ rtl_emit_function, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts } }; to GCC v6.x const pass_data pass_data_rtl_emit_function = { RTL_PASS, /* type */ "rtl_emit_function", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish,/* todo_flags_finish */ Just 0 because const pass_data pass_data_dse migrate the todo_flags as https://github.com/gcc-mirror/gcc/blob/master/gcc/tree-ssa-dse.c#L818 }; class pass_rtl_emit_function : public rtl_opt_pass { public: pass_rtl_emit_function(gcc::context *ctxt) : rtl_opt_pass(pass_data_rtl_emit_function, ctxt) {} virtual unsigned int execute(function *) { return rtl_emit_function(); } }; I have no idea how to choose the todo_flags_XXX, please give me some hint, thanks a lot! -- Regards, Leslie Zhai https://reviews.llvm.org/p/xiangzhai/
whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
gengtype not support #if (GCC_MAJOR < 6)? how to support both for GCC v4.x and v6.x?
Hi GCC developers, As ChangeLog-2014 mentioned: Remove support for if_marked and param_is about ggc, so I migrate to GCC v6.x, for example: #if (GCC_MAJOR < 6) // FIXME: gengtype not support macro? //static GTY((if_marked("tree2int_marked_p"), param_is(struct tree2int))) //htab_t intCache; #else struct intCacheHasher : ggc_cache_ptr_hash { static inline hashval_t hash(tree2int *t2i) { return tree_map_base_hash(t2i->base); } static inline bool equal(tree2int *a, tree2int *b) { return a->base.from == b->base.from; } static int keep_cache_entry(tree2int *&t2i) { return ggc_marked_p(t2i->base.from); } }; static GTY((cache)) hash_table *intCache; #endif $ gcc-6.3.0/build/gcc/build/gengtype -r gcc-6.3.0/build/gcc/gtype.state -P /tmp/gt-cache-6.3.inc Input.cpp but it still parse the deprecated if_marked and param_is for GCC v4.x, please give me some hint, thanks a lot! -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi David, Thanks for your kind response! 在 2017年07月10日 22:16, David Malcolm 写道: On Sat, 2017-07-08 at 15:50 +0800, Leslie Zhai wrote: Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! Trevor [CCed] removed it 2014-12-10 in r218558 (eb06b2519a361b7784b1807115fcb3dea0226035) in the commit: "remove gengtype support for param_is use_param, if_marked and splay tree allocators" The patch was here: https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02965.html where he talks about plugin migration. Hope this is helpful yes, it is very helpful :) thank you very much! Dave -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
在 2017年07月10日 22:16, David Malcolm 写道: On Sat, 2017-07-08 at 15:50 +0800, Leslie Zhai wrote: Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! Trevor [CCed] removed it 2014-12-10 in r218558 (eb06b2519a361b7784b1807115fcb3dea0226035) in the commit: "remove gengtype support for param_is use_param, if_marked and splay tree allocators" The patch was here: https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02965.html where he talks about plugin migration. Some plugins may need to add extra GGC root tables, e.g. to handle their own @code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the extra root table (of type @code{struct -ggc_root_tab*}) as @code{user_data}. Plugins that want to use the -@code{if_marked} hash table option can add the extra GGC cache tables generated -by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with -a null callback and the extra cache table (of type @code{struct ggc_cache_tab*}) -as @code{user_data}. Running the @code{gengtype -p @var{source-dir} -@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables. +ggc_root_tab*}) as @code{user_data}. Running the + @code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...} +utility generates these extra root tables. After diff gcc-6.3.0/gcc/testsuite/gcc.dg/plugin and gcc-4.8.0/gcc/testsuite/gcc.dg/plugin then migrate to GCC v6.x like this: // Register our garbage collector roots. #if GCC_MAJOR < 6 register_callback(plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL, #else register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, #endif const_cast(gt_ggc_rc__gt_cache_h)); and Trevor talks more about GTY((if_marked(XXX), param_is(XXX))) htab_t migrate to GTY((cache)) hash_table such as: #if (GCC_MAJOR < 6) // FIXME: gengtype not support macro? static GTY((if_marked("tree2int_marked_p"), param_is(struct tree2int))) htab_t intCache; #else struct intCacheHasher : ggc_cache_ptr_hash { static inline hashval_t hash(tree2int *t2i) { return tree_map_base_hash(&t2i->base); } static inline bool equal(tree2int *a, tree2int *b) { return a->base.from == b->base.from; } }; static GTY((cache)) hash_table *intCache; #endif But I have no idea why gengtype does not support macro? https://gcc.gnu.org/ml/gcc/2017-07/msg00045.html it just ignored #if (GCC_MAJOR < 6) still parse GTY((if_marked(XXX), param_is(XXX))) htab_t but not GTY((cache)) hash_table... please give me some hint, thanks a lot! Hope this is helpful Dave -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi David, Thanks for your kind response! 在 2017年07月11日 21:25, David Malcolm 写道: On Tue, 2017-07-11 at 10:50 +0800, Leslie Zhai wrote: 在 2017年07月10日 22:16, David Malcolm 写道: On Sat, 2017-07-08 at 15:50 +0800, Leslie Zhai wrote: Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! Trevor [CCed] removed it 2014-12-10 in r218558 (eb06b2519a361b7784b1807115fcb3dea0226035) in the commit: "remove gengtype support for param_is use_param, if_marked and splay tree allocators" The patch was here: https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02965.html where he talks about plugin migration. Some plugins may need to add extra GGC root tables, e.g. to handle their own @code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the extra root table (of type @code{struct -ggc_root_tab*}) as @code{user_data}. Plugins that want to use the -@code{if_marked} hash table option can add the extra GGC cache tables generated -by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with -a null callback and the extra cache table (of type @code{struct ggc_cache_tab*}) -as @code{user_data}. Running the @code{gengtype -p @var{source-dir} -@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables. +ggc_root_tab*}) as @code{user_data}. Running the + @code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...} +utility generates these extra root tables. After diff gcc-6.3.0/gcc/testsuite/gcc.dg/plugin and gcc-4.8.0/gcc/testsuite/gcc.dg/plugin then migrate to GCC v6.x like this: // Register our garbage collector roots. #if GCC_MAJOR < 6 register_callback(plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL, #else register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, #endif const_cast(gt_ggc_rc__gt_cache_h)); and Trevor talks more about GTY((if_marked(XXX), param_is(XXX))) htab_t migrate to GTY((cache)) hash_table such as: #if (GCC_MAJOR < 6) // FIXME: gengtype not support macro? static GTY((if_marked("tree2int_marked_p"), param_is(struct tree2int))) htab_t intCache; #else struct intCacheHasher : ggc_cache_ptr_hash { static inline hashval_t hash(tree2int *t2i) { return tree_map_base_hash(&t2i->base); } static inline bool equal(tree2int *a, tree2int *b) { return a->base.from == b->base.from; } }; static GTY((cache)) hash_table *intCache; #endif But I have no idea why gengtype does not support macro? https://gcc.gnu.org/ml/gcc/2017-07/msg00045.html it just ignored #if (GCC_MAJOR < 6) still parse GTY((if_marked(XXX), param_is(XXX))) htab_t but not GTY((cache)) hash_table... please give me some hint, thanks a lot! Unfortunately, gengtype is not a full parser for all of C++; IIRC it doesn't have any real support for the preprocessor. Maybe you can work around it in your plugin by providing two different headers, one for GCC_MAJOR < 6, the other for >= 6, and setting up the build so that gengtype is invoked on the correct header. (I know this is ugly, sorry). Alternatively, maybe there's another way to solve this by rethinking the data structure. It seems like you have a hash table of some kind. Does the hash table "own" references to other GC-managed entities, or is it simply referenced *by* other GC-managed entities. Maybe there's I am migrating dragonegg to GCC v6.3 and LLVM v3.9, at first it needs to be built successfully, no warning is better :) but I only migrated part of it, for example: Caching values in GCC trees right now https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Cache.cpp and the relationship might be: GTY((cache)) hash_table *intCache <- Cache::setCachedInteger <- TypeConversion::set_decl_index... When I finished the migration, with the whole view, then I need to rethink the data structure as you suggested. PS: Trevor's email is not available? thanks! another way to represent this data which would sidestep the issue. (I don't know, I'm just speculating). Hope this is helpful Dave -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi Trevor, Thanks for your kind response! 在 2017年07月17日 19:51, Trevor Saunders 写道: On Wed, Jul 12, 2017 at 10:12:03AM +0800, Leslie Zhai wrote: PS: Trevor's email is not available? thanks! Sorry about that, I've left Mozilla and been vacationing for a month, so didn't get to updating MAINTAINERS yet. Here's a patch doing that. Could I use PLUGIN_REGISTER_GGC_ROOTS to take place of PLUGIN_REGISTER_GGC_CACHES? https://gcc.gnu.org/ml/gcc/2017-07/msg00052.html Trev commit ff900f40d23f765fd59047a90a7e3ff18cbcbf5a Author: Trevor Saunders Date: Mon Jul 17 07:44:50 2017 -0400 update my entry in MAINTAINERS ChangeLog: * MAINTAINERS: Update my email address. diff --git a/MAINTAINERS b/MAINTAINERS index a2f24742374..6a314049c42 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -557,7 +557,7 @@ Hariharan Sandanagobalane Iain Sandoe Duncan Sands Sujoy Saraswati -Trevor Saunders +Trevor Saunders Aaron Sawdey Roger Sayle Will Schmidt -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
在 2017年07月19日 04:54, Trevor Saunders 写道: On Tue, Jul 18, 2017 at 03:52:55PM +0800, Leslie Zhai wrote: Hi Trevor, Thanks for your kind response! 在 2017年07月17日 19:51, Trevor Saunders 写道: On Wed, Jul 12, 2017 at 10:12:03AM +0800, Leslie Zhai wrote: PS: Trevor's email is not available? thanks! Sorry about that, I've left Mozilla and been vacationing for a month, so didn't get to updating MAINTAINERS yet. Here's a patch doing that. Could I use PLUGIN_REGISTER_GGC_ROOTS to take place of PLUGIN_REGISTER_GGC_CACHES? https://gcc.gnu.org/ml/gcc/2017-07/msg00052.html If you are ok with your plugin keeping things alive that would otherwise be garbage collected because they are no longer needed sure I think that will work. Though some things are ggc_free()ed and so you might want to be careful touching those things that should be collected but you are keeping alive. Does that help? Very helpful :) thank you so much! Trev Trev commit ff900f40d23f765fd59047a90a7e3ff18cbcbf5a Author: Trevor Saunders Date: Mon Jul 17 07:44:50 2017 -0400 update my entry in MAINTAINERS ChangeLog: * MAINTAINERS: Update my email address. diff --git a/MAINTAINERS b/MAINTAINERS index a2f24742374..6a314049c42 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -557,7 +557,7 @@ Hariharan Sandanagobalane Iain Sandoe Duncan Sands Sujoy Saraswati -Trevor Saunders +Trevor Saunders Aaron Sawdey Roger Sayle Will Schmidt -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
在 2017年07月11日 21:25, David Malcolm 写道: On Tue, 2017-07-11 at 10:50 +0800, Leslie Zhai wrote: 在 2017年07月10日 22:16, David Malcolm 写道: On Sat, 2017-07-08 at 15:50 +0800, Leslie Zhai wrote: Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! Trevor [CCed] removed it 2014-12-10 in r218558 (eb06b2519a361b7784b1807115fcb3dea0226035) in the commit: "remove gengtype support for param_is use_param, if_marked and splay tree allocators" The patch was here: https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02965.html where he talks about plugin migration. Some plugins may need to add extra GGC root tables, e.g. to handle their own @code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the extra root table (of type @code{struct -ggc_root_tab*}) as @code{user_data}. Plugins that want to use the -@code{if_marked} hash table option can add the extra GGC cache tables generated -by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with -a null callback and the extra cache table (of type @code{struct ggc_cache_tab*}) -as @code{user_data}. Running the @code{gengtype -p @var{source-dir} -@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables. +ggc_root_tab*}) as @code{user_data}. Running the + @code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...} +utility generates these extra root tables. After diff gcc-6.3.0/gcc/testsuite/gcc.dg/plugin and gcc-4.8.0/gcc/testsuite/gcc.dg/plugin then migrate to GCC v6.x like this: // Register our garbage collector roots. #if GCC_MAJOR < 6 register_callback(plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL, #else register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, #endif const_cast(gt_ggc_rc__gt_cache_h)); and Trevor talks more about GTY((if_marked(XXX), param_is(XXX))) htab_t migrate to GTY((cache)) hash_table such as: #if (GCC_MAJOR < 6) // FIXME: gengtype not support macro? static GTY((if_marked("tree2int_marked_p"), param_is(struct tree2int))) htab_t intCache; #else struct intCacheHasher : ggc_cache_ptr_hash { static inline hashval_t hash(tree2int *t2i) { return tree_map_base_hash(&t2i->base); } static inline bool equal(tree2int *a, tree2int *b) { return a->base.from == b->base.from; } }; static GTY((cache)) hash_table *intCache; #endif But I have no idea why gengtype does not support macro? https://gcc.gnu.org/ml/gcc/2017-07/msg00045.html it just ignored #if (GCC_MAJOR < 6) still parse GTY((if_marked(XXX), param_is(XXX))) htab_t but not GTY((cache)) hash_table... please give me some hint, thanks a lot! Unfortunately, gengtype is not a full parser for all of C++; IIRC it doesn't have any real support for the preprocessor. Maybe you can work around it in your plugin by providing two different headers, one for GCC_MAJOR < 6, the other for >= 6, and setting up the build so that gengtype is invoked on the correct header. (I know this is ugly, sorry). Right now I am using two different files: such as Cache4.cpp and Cache6.cpp, and there is the same `struct GTY(()) tree2WeakVH` for GCC v4.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Cache4.cpp#L99 also for GCC v6.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Cache6.cpp#L116 then gengtype auto-generated `struct ggc_root_tab` with Cache6.cpp for GCC v6.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/include/dragonegg/gt-cache-6.3.inc#L1257 it is of course different with Cache4.cpp for GCC v4.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/include/dragonegg/gt-cache-4.6.inc#L970 $ gcc -fplugin=/usr/lib64/dragonegg.so hello.c cc1: error: cannot load plugin /usr/lib64/dragonegg.so /usr/lib64/dragonegg.so: undefined symbol: _Z9gt_ggc_mxRP11tree2WeakVH it is my fault! the symbol `_Z9gt_ggc_mxRP11tree2WeakVH` looks like for GCC v4.x, so I migrated the plugin to GCC v6.x wrongly? https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2662 please give me some hint, thanks a lot! Alternatively, maybe there's another way to solve this by rethinking the data structure. It seems like you have a hash table of some kind. Does the hash table "own" references to other GC-managed entities, or is it simply referenced *by* other GC-managed entities. Maybe there's another way to represent this data which would sidestep the issue. (I don't know, I'm just speculating). Hope this is helpful Dave -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ �
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi David, Thanks for your kind response! 在 2017年07月26日 21:43, David Malcolm 写道: On Wed, 2017-07-26 at 15:19 +0800, Leslie Zhai wrote: 在 2017年07月11日 21:25, David Malcolm 写道: On Tue, 2017-07-11 at 10:50 +0800, Leslie Zhai wrote: 在 2017年07月10日 22:16, David Malcolm 写道: On Sat, 2017-07-08 at 15:50 +0800, Leslie Zhai wrote: Hi GCC developers, There was PLUGIN_REGISTER_GGC_CACHES pseudo-events for register_callback in GCC v4.x, but how to migrate it for GCC v6.x? there is no PLUGIN_REGISTER_GGC_CACHES deprecated log in ChangeLog-201X nor git log plugin.h... please give me some hint, thanks a lot! Trevor [CCed] removed it 2014-12-10 in r218558 (eb06b2519a361b7784b1807115fcb3dea0226035) in the commit: "remove gengtype support for param_is use_param, if_marked and splay tree allocators" The patch was here: https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02965.html where he talks about plugin migration. Some plugins may need to add extra GGC root tables, e.g. to handle their own @code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the extra root table (of type @code{struct -ggc_root_tab*}) as @code{user_data}. Plugins that want to use the -@code{if_marked} hash table option can add the extra GGC cache tables generated -by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with -a null callback and the extra cache table (of type @code{struct ggc_cache_tab*}) -as @code{user_data}. Running the @code{gengtype -p @var{source -dir} -@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables. +ggc_root_tab*}) as @code{user_data}. Running the + @code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...} +utility generates these extra root tables. After diff gcc-6.3.0/gcc/testsuite/gcc.dg/plugin and gcc-4.8.0/gcc/testsuite/gcc.dg/plugin then migrate to GCC v6.x like this: // Register our garbage collector roots. #if GCC_MAJOR < 6 register_callback(plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL, #else register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, #endif const_cast(gt_ggc_rc__gt_cache_h)); and Trevor talks more about GTY((if_marked(XXX), param_is(XXX))) htab_t migrate to GTY((cache)) hash_table such as: #if (GCC_MAJOR < 6) // FIXME: gengtype not support macro? static GTY((if_marked("tree2int_marked_p"), param_is(struct tree2int))) htab_t intCache; #else struct intCacheHasher : ggc_cache_ptr_hash { static inline hashval_t hash(tree2int *t2i) { return tree_map_base_hash(&t2i->base); } static inline bool equal(tree2int *a, tree2int *b) { return a->base.from == b->base.from; } }; static GTY((cache)) hash_table *intCache; #endif But I have no idea why gengtype does not support macro? https://gcc.gnu.org/ml/gcc/2017-07/msg00045.html it just ignored #if (GCC_MAJOR < 6) still parse GTY((if_marked(XXX), param_is(XXX))) htab_t but not GTY((cache)) hash_table... please give me some hint, thanks a lot! Unfortunately, gengtype is not a full parser for all of C++; IIRC it doesn't have any real support for the preprocessor. Maybe you can work around it in your plugin by providing two different headers, one for GCC_MAJOR < 6, the other for >= 6, and setting up the build so that gengtype is invoked on the correct header. (I know this is ugly, sorry). Right now I am using two different files: such as Cache4.cpp and Cache6.cpp, and there is the same `struct GTY(()) tree2WeakVH` for GCC v4.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Cache4 .cpp#L99 also for GCC v6.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Cache6 .cpp#L116 then gengtype auto-generated `struct ggc_root_tab` with Cache6.cpp for GCC v6.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/include/dr agonegg/gt-cache-6.3.inc#L1257 it is of course different with Cache4.cpp for GCC v4.x https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/include/dr agonegg/gt-cache-4.6.inc#L970 It looks strange to me that this repository contains these per-gcc -version auto-generated .inc files; aren't these something that should just be created at build time? I am using Fedora, and perhaps no RPM packages provides gengtype: $ dnf repoquery --whatprovides gengtype compare with $ dnf repoquery --whatprovides *libgcc-c-api* gcc-python-plugin-c-api-0:0.15-8.1.fc25.x86_64 ... so I have no idea how to auto-generated them at build time, instead I built GCC v4.6 and v6.3 https://github.com/xiangzhai/dragonegg/wiki/GGC please give me some hint, thanks a lot! Near the end of: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/Makefile I see that a make target that invokes gengtype. I think the best approach is to add logic to that Makefile so that that gengtype invocation either loads Cache4.cpp *or* Cache6.cpp, depend
Re: whereis PLUGIN_REGISTER_GGC_CACHES? how to migrate it for GCC v6.x?
Hi Duncan, Thanks for your kind response! My sincere thanks goes to you, the core developer of llvm-gcc and dragonegg http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf dragonegg release_33 is still able to work happily for GCC v4.6.3 and LLVM v3.3 https://pbs.twimg.com/media/DFtthrTVoAEhnhA.jpg > IIRC I did it this way because to generate these files you need to have theentire GCC sources, while one of the goals of dragonegg was that in order to beable to build dragonegg you should only need to have the gcc headers installed. Yes, it is for the benefit of the dragonegg maintainers, and I built GCC v4.6.3 and v6.3 by myself https://github.com/xiangzhai/dragonegg/wiki/GGC but after GCC v4.x, the API of GCC v5.x, v6.x, v7.x and v8.x (git master branch) had been changed a lot, so I am trying to migrate dragonegg for GCC v6.3 and LLVM v3.9 https://reviews.llvm.org/D35667 could you give me some hint, thanks a lot! -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
pass 'lto_gimple_out' not found, how to migrate it for GCC v6.x?
Hi GCC developers, As ChangeLog-2013 mentioned by Bernd Schmidt: ... pass_ipa_lto_gimple_out ... Remove. Delete. there is no 'pass_ipa_lto_gimple_out' in lto-streamer-out.c any more. then how to migrate it for GCC v6.x? just like this: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2880 to ignore it? or do I need to find other equivalent PASS? please give me some hint, thanks a lot! PS: Thanks for David's hint, I fixed 'undefined symbol gt_ggc_mx(tree2WeakVH*&)' issue, I forgot to add 'for_user' for GTY((XXX))... -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: pass 'lto_gimple_out' not found, how to migrate it for GCC v6.x?
Hi Richard, Thanks for your kind response! 在 2017年07月28日 15:54, Richard Biener 写道: On Fri, Jul 28, 2017 at 6:12 AM, Leslie Zhai wrote: Hi GCC developers, As ChangeLog-2013 mentioned by Bernd Schmidt: ... pass_ipa_lto_gimple_out ... Remove. Delete. there is no 'pass_ipa_lto_gimple_out' in lto-streamer-out.c any more. then how to migrate it for GCC v6.x? just like this: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2880 to ignore it? or do I need to find other equivalent PASS? please give me some hint, thanks a lot! It says // Disable all LTO passes. (for whatever reason). So try just removing this part - the pass is already removed. Yes, I use the macro (GCC_MAJOR < 5) to disable it (just removing this part, to ignore it) https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2884 sorry I am not the original developer of DragonEgg http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf and recently I am learning about GCC plugin and GIMPLE https://reviews.llvm.org/D35667 for converting GIMPLE to LLVM IR, then disable GCC PASS but use LLVM's instead, but I don't have the whole view of it, I need to deepin to it more :) please Duncan answer your question about 'for whatever reason', thanks! Richard. PS: Thanks for David's hint, I fixed 'undefined symbol gt_ggc_mx(tree2WeakVH*&)' issue, I forgot to add 'for_user' for GTY((XXX))... -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
How to migrate struct rtl_opt_pass to class for GCC v6.x?
Hi GCC developers, As ChangeLog-2013 mentioned: 2013-08-05 David Malcolm This is the automated part of the conversion of passes from C structs to C++ classes. ... * auto-inc-dec.c (pass_inc_dec): Convert from a global struct to a subclass of rtl_opt_pass along with... so I migrate struct rtl_opt_pass: https://github.com/llvm-mirror/dragonegg/blob/master/src/Backend.cpp#L1731 static struct rtl_opt_pass pass_rtl_emit_function = { { RTL_PASS, "rtl_emit_function", /* name */ #if (GCC_MINOR > 7) OPTGROUP_NONE, /* optinfo_flags */ #endif NULL, /* gate */ rtl_emit_function, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ TODO_ggc_collect /* todo_flags_finish */ } }; to GCC v6.x C++ classes' style: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2072 const pass_data pass_data_rtl_emit_function = { RTL_PASS, /* type */ "rtl_emit_function", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ 0, /* todo_flags_start */ 0, /* todo_flags_finish */ }; class pass_rtl_emit_function : public rtl_opt_pass { public: pass_rtl_emit_function(gcc::context *ctxt) : rtl_opt_pass(pass_data_rtl_emit_function, ctxt) {} unsigned int execute(function *) { return rtl_emit_function(); } opt_pass *clone() { return this; } }; GCC v4.6 will call the callback `rtl_emit_function`, but GCC v6.x will not, did I forget something? is there some options need to be set? please give me some hint, thanks a lot! PS: GCC v6.x *call* the callback `rtl_emit_function` https://github.com/xiangzhai/dragonball/blob/master/tests/plugin.cpp#L67 in this testcase, I will check the source code about register_callback, rtl_opt_pass, and opt_pass. -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ @
Re: How to migrate struct rtl_opt_pass to class for GCC v6.x?
/opt/gcc-6.3/bin/gcc -fplugin=./dragonegg.so test/hello.c -wrapper gdb,--args GNU gdb (GDB) Fedora 7.12.1-48.fc25 ... Reading symbols from /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1...done. (gdb) b /data/project/xiangzhai/gcc-6.3.0/gcc/passes.c:2288 Breakpoint 1 at 0x91b8d4: file ../../gcc/passes.c, line 2288. (gdb) r Starting program: /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1 -quiet -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux-gnu/6.3.0/plugin test/hello.c -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux-gnu/6.3.0/plugin -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -fplugin=./dragonegg.so -o /tmp/cco7mKtB.s ... Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c7b730) at ../../gcc/passes.c:2288 warning: Source file is more recent than executable. 2288 current_pass = pass; (gdb) p pass $1 = (opt_pass *) 0x1c7b730 (gdb) p current_pass $2 = (opt_pass *) 0x0 (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p current_pass $3 = (opt_pass *) 0x1c7b730 (gdb) p gate_status $4 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) p gate_status $5 = false (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p gate_status $6 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) p gate_status $7 = true (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) n 2298 if (!gate_status) (gdb) p gate_status $8 = true (gdb) n ... (gdb) n 2336 todo_after = pass->execute (cfun); <--- gcc called execute hook? (gdb) p todo_after $9 = 0 (gdb) n 2338 if (todo_after & TODO_discard_function) (gdb) p todo_after $10 = 0 (gdb) 2336 todo_after = pass->execute (cfun); <--- gcc called execute hook? but why not dragonegg https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2103 在 2017年08月03日 11:24, Leslie Zhai 写道: Hi GCC developers, As ChangeLog-2013 mentioned: 2013-08-05 David Malcolm This is the automated part of the conversion of passes from C structs to C++ classes. ... * auto-inc-dec.c (pass_inc_dec): Convert from a global struct to a subclass of rtl_opt_pass along with... so I migrate struct rtl_opt_pass: https://github.com/llvm-mirror/dragonegg/blob/master/src/Backend.cpp#L1731 static struct rtl_opt_pass pass_rtl_emit_function = { { RTL_PASS, "rtl_emit_function", /* name */ #if (GCC_MINOR > 7) OPTGROUP_NONE, /* optinfo_flags */ #endif NULL, /* gate */ rtl_emit_function, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ TODO_ggc_collect /* todo_flags_finish */ } }; to GCC v6.x C++ classes' style: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2072 const pass_data pass_data_rtl_emit_function = { RTL_PASS, /* type */ "rtl_emit_function", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ 0, /* todo_flags_start */ 0, /* todo_flags_finish */ }; class pass_rtl_emit_function : public rtl_opt_pass { public: pass_rtl_emit_function(gcc::context *ctxt) : rtl_opt_pass(pass_data_rtl_emit_function, ctxt) {} unsigned int execute(function *) { return rtl_emit_function(); } opt_pass *clone() { return this; } }; GCC v4.6 will call the callback `rtl_emit_function`, but GCC v6.x will not, did I forget something? is there some options need to be set? please give me some hint, thanks a lot! PS: GCC v6.x *call* the callback `rtl_emit_function` https://github.com/xiangzhai/dragonball/blob/master/tests/plugin.cpp#L67 in this testcase, I will check the source code about register_callback, rtl_opt_pass, and opt_pass. -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: How to migrate struct rtl_opt_pass to class for GCC v6.x?
Hi David, Thanks for your kind response! 在 2017年08月03日 21:54, David Malcolm 写道: On Thu, 2017-08-03 at 17:21 +0800, Leslie Zhai wrote: /opt/gcc-6.3/bin/gcc -fplugin=./dragonegg.so test/hello.c -wrapper gdb,--args GNU gdb (GDB) Fedora 7.12.1-48.fc25 ... Reading symbols from /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1...done. (gdb) b /data/project/xiangzhai/gcc-6.3.0/gcc/passes.c:2288 Breakpoint 1 at 0x91b8d4: file ../../gcc/passes.c, line 2288. (gdb) r Starting program: /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1 -quiet -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux- gnu/6.3.0/plugin test/hello.c -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux- gnu/6.3.0/plugin -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -fplugin=./dragonegg.so -o /tmp/cco7mKtB.s ... Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c7b730) at ../../gcc/passes.c:2288 warning: Source file is more recent than executable. This warning is somewhat unnerving; have you updated the source code for the compiler since you last recompiled it? The warning disappeared after recompiled GCC v6.3 2288 current_pass = pass; (gdb) p pass $1 = (opt_pass *) 0x1c7b730 (gdb) p current_pass $2 = (opt_pass *) 0x0 (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p current_pass $3 = (opt_pass *) 0x1c7b730 (gdb) p gate_status $4 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) p gate_status $5 = false (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p gate_status $6 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) p gate_status $7 = true (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) n 2298 if (!gate_status) (gdb) p gate_status $8 = true (gdb) n ... (gdb) n 2336 todo_after = pass->execute (cfun); <--- gcc called execute hook? Try "step" here rather than "n" for "next"; that way you can see exactly what is being called. I had a hunch that you might be running into the default implementation of opt_pass::execute, which is a no-op. opt_pass::execute used to take "void", but was changed to take a "function *" in r209482 (aka 65b0537f9e9741318f7c8e738b6dd3b8f82f58b5) on 2014-04-17. If you're using a >= C++11 compiler, you might want to try adding "final override" to the execute method of your pass to ensure that it's an override of the execute virtual function. We have macros "FINAL" and "OVERRIDE" for this in recent versions of gcc. Add as your suggestion. https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2110 Is this definitely the correct pass? What does (gdb) p *pass print? Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c7b730) at ../../gcc/passes.c:2288 2288 current_pass = pass; ... (gdb) p pass->name $1 = 0x11a2369 "*warn_unused_result" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86270) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $2 = 0x1181b98 "*diagnose_omp_blocks" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c862d0) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $3 = 0x119d740 "*diagnose_tm_blocks" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86330) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $4 = 0x1181bad "omplower" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86390) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $5 = 0x11be968 "lower" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c863f0) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $6 = 0x119d738 "tmlower" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86450) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $7 = 0x11a711e "ehopt" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c864b0) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $8 = 0x119b9cf "eh" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86510) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gdb) p pass->name $9 = 0x11972bb "cfg" (gdb) c Continuing. Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c86570) at ../../gcc/passes.c:2288 2288 current_pass = pass; (gd
How to migrate POINTER_TYPE_OVERFLOW_UNDEFINED for GCC v8.x?
Hi GCC developers, As ChangeLog mentioned: 2017-08-01 Bin Cheng * tree.h (POINTER_TYPE_OVERFLOW_UNDEFINED): Delete. Then how to migrate it for GCC v8.x? for example: Constant *Result = POINTER_TYPE_OVERFLOW_UNDEFINED ? A : B; migrated to Constant *Result = A; because there was a patch 'Make pointer overflow always undefined and remove the macro' https://patchwork.ozlabs.org/patch/792677/ please give me some hint, thanks a lot! -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: How to migrate POINTER_TYPE_OVERFLOW_UNDEFINED for GCC v8.x?
Hi Bin, Thanks for your kind response! 在 2017年08月04日 15:45, Bin.Cheng 写道: On Fri, Aug 4, 2017 at 8:00 AM, Leslie Zhai wrote: Hi GCC developers, As ChangeLog mentioned: 2017-08-01 Bin Cheng * tree.h (POINTER_TYPE_OVERFLOW_UNDEFINED): Delete. Then how to migrate it for GCC v8.x? for example: Constant *Result = POINTER_TYPE_OVERFLOW_UNDEFINED ? A : B; migrated to Constant *Result = A; Yes, basically this is what I did in the patch: simply assuming TRUE and simplifying the expression. I migrated to GCC v8.x now https://github.com/xiangzhai/dragonegg/commit/d78389c502f5a06b21fcf1a1590e44451e59f461 thanks for your patch's hint :) it can't work for GCC v8.x, even though compiled without error, but able to work for GCC v4.6 and v4.8, I am stuck at rtl_opt_pass https://gcc.gnu.org/ml/gcc/2017-08/msg00045.html hope I can figure it out the root cause. Thanks, bin because there was a patch 'Make pointer overflow always undefined and remove the macro' https://patchwork.ozlabs.org/patch/792677/ please give me some hint, thanks a lot! -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: How to migrate struct rtl_opt_pass to class for GCC v6.x?
在 2017年08月03日 17:21, Leslie Zhai 写道: /opt/gcc-6.3/bin/gcc -fplugin=./dragonegg.so test/hello.c -wrapper gdb,--args GNU gdb (GDB) Fedora 7.12.1-48.fc25 ... Reading symbols from /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1...done. (gdb) b /data/project/xiangzhai/gcc-6.3.0/gcc/passes.c:2288 Breakpoint 1 at 0x91b8d4: file ../../gcc/passes.c, line 2288. (gdb) r Starting program: /opt/gcc-6.3/libexec/gcc/x86_64-redhat-linux-gnu/6.3.0/cc1 -quiet -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux-gnu/6.3.0/plugin test/hello.c -iplugindir=/opt/gcc-6.3/lib/gcc/x86_64-redhat-linux-gnu/6.3.0/plugin -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -fplugin=./dragonegg.so -o /tmp/cco7mKtB.s ... Breakpoint 1, execute_one_pass (pass=pass@entry=0x1c7b730) at ../../gcc/passes.c:2288 warning: Source file is more recent than executable. 2288 current_pass = pass; (gdb) p pass $1 = (opt_pass *) 0x1c7b730 (gdb) p current_pass $2 = (opt_pass *) 0x0 (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p current_pass $3 = (opt_pass *) 0x1c7b730 (gdb) p gate_status $4 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) p gate_status $5 = false (gdb) n 2292 gate_status = pass->gate (cfun); (gdb) p gate_status $6 = false (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) p gate_status $7 = true (gdb) n 2293 gate_status = override_gate_status (pass, current_function_decl, gate_status); (gdb) n 2296 invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status); (gdb) n 2298 if (!gate_status) (gdb) p gate_status $8 = true (gdb) n ... (gdb) n 2336 todo_after = pass->execute (cfun); <--- gcc called execute hook? (gdb) p todo_after $9 = 0 (gdb) n 2338 if (todo_after & TODO_discard_function) (gdb) p todo_after $10 = 0 (gdb) 2336 todo_after = pass->execute (cfun); <--- gcc called execute hook? but why not dragonegg https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2103 在 2017年08月03日 11:24, Leslie Zhai 写道: Hi GCC developers, As ChangeLog-2013 mentioned: 2013-08-05 David Malcolm This is the automated part of the conversion of passes from C structs to C++ classes. ... * auto-inc-dec.c (pass_inc_dec): Convert from a global struct to a subclass of rtl_opt_pass along with... so I migrate struct rtl_opt_pass: https://github.com/llvm-mirror/dragonegg/blob/master/src/Backend.cpp#L1731 static struct rtl_opt_pass pass_rtl_emit_function = { { RTL_PASS, "rtl_emit_function", /* name */ #if (GCC_MINOR > 7) OPTGROUP_NONE, /* optinfo_flags */ #endif NULL, /* gate */ rtl_emit_function, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ TODO_ggc_collect /* todo_flags_finish */ } }; to GCC v6.x C++ classes' style: https://github.com/xiangzhai/dragonegg/blob/gcc-6_3-branch/src/Backend.cpp#L2072 const pass_data pass_data_rtl_emit_function = { RTL_PASS, /* type */ "rtl_emit_function", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */ 0, /* properties_provided */ PROP_ssa | PROP_trees, /* properties_destroyed */ 0, /* todo_flags_start */ 0, /* todo_flags_finish */ }; class pass_rtl_emit_function : public rtl_opt_pass { public: pass_rtl_emit_function(gcc::context *ctxt) : rtl_opt_pass(pass_data_rtl_emit_function, ctxt) {} unsigned int execute(function *) { return rtl_emit_function(); } opt_pass *clone() { return this; } }; GCC v4.6 will call the callback `rtl_emit_function`, but GCC v6.x will not, did I forget something? is there some options need to be set? please give me some hint, thanks a lot! PS: GCC v6.x *call* the callback `rtl_emit_function` https://github.com/xiangzhai/dragonball/blob/master/tests/plugin.cpp#L67 in this testcase, I will check the source code about register_callback, rtl_opt_pass, and opt_pass. I found it! with -flto option,
How to migrate ggc_alloc_XXX for GCC v8.x (git-20170816)?
Hi GCC developers, GCC v4.6's gengtype will auto-generate Allocators for known structs and unions, for example: ggc_alloc_tree2WeakVH for tree2WeakVH https://github.com/xiangzhai/dragonegg/blob/master/include/dragonegg/gt-cache-4.6.inc#L24 but gengtype will not auto-generate ggc_alloc_XXX for GCC v6.x or v8.x (git-20170816), for example: struct GTY((for_user)) tree2WeakVH https://github.com/xiangzhai/dragonegg/blob/master/include/dragonegg/gt-cache-8.0.inc#L1284 As ChangeLog-2014 mentioned: 2014-05-17 Trevor Saunders ... (ggc_alloc): Install the type's destructor as the finalizer if it might do something. Please give me some hint about ggc_alloc migration, thanks a lot! -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: How to migrate ggc_alloc_XXX for GCC v8.x (git-20170816)?
Hi Trevor, Thanks for your kind response! 在 2017年08月16日 20:02, Trevor Saunders 写道: On Wed, Aug 16, 2017 at 05:32:10PM +0800, Leslie Zhai wrote: Hi GCC developers, GCC v4.6's gengtype will auto-generate Allocators for known structs and unions, for example: ggc_alloc_tree2WeakVH for tree2WeakVH https://github.com/xiangzhai/dragonegg/blob/master/include/dragonegg/gt-cache-4.6.inc#L24 but gengtype will not auto-generate ggc_alloc_XXX for GCC v6.x or v8.x (git-20170816), for example: struct GTY((for_user)) tree2WeakVH https://github.com/xiangzhai/dragonegg/blob/master/include/dragonegg/gt-cache-8.0.inc#L1284 As ChangeLog-2014 mentioned: 2014-05-17 Trevor Saunders ... (ggc_alloc): Install the type's destructor as the finalizer if it might do something. Please give me some hint about ggc_alloc migration, thanks a lot! if you look at the patches they convert ggc_alloc_foo to ggc_alloc and you should do the same. Thanks for your hint! I do the same :) https://github.com/xiangzhai/dragonegg/blob/master/src/Cache.cpp#L255 PS: how to find the relative patch for the ChangeLog's item? I use Google, for example: (ggc_alloc): Install the type's destructor as the finalizer if it might do something. Trev -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/ -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
Re: Locating a commit from its ChangeLog entry (was Re: How to migrate ggc_alloc_XXX for GCC v8.x (git-20170816)?)
在 2017年08月17日 23:10, David Malcolm 写道: On Thu, 2017-08-17 at 09:52 +0800, Leslie Zhai wrote: Hi Trevor, Thanks for your kind response! 在 2017年08月16日 20:02, Trevor Saunders 写道: On Wed, Aug 16, 2017 at 05:32:10PM +0800, Leslie Zhai wrote: Hi GCC developers, GCC v4.6's gengtype will auto-generate Allocators for known structs and unions, for example: ggc_alloc_tree2WeakVH for tree2WeakVH https: //github.com/xiangzhai/dragonegg/blob/master/include/dragonegg/gt -cache-4.6.inc#L24 but gengtype will not auto-generate ggc_alloc_XXX for GCC v6.x or v8.x (git-20170816), for example: struct GTY((for_user)) tree2WeakVH h ttps://github.com/xiangzhai/dragonegg/blob/master/include/dragone gg/gt-cache-8.0.inc#L1284 As ChangeLog-2014 mentioned: 2014-05-17 Trevor Saunders ... (ggc_alloc): Install the type's destructor as the finalizer if it might do something. Please give me some hint about ggc_alloc migration, thanks a lot! if you look at the patches they convert ggc_alloc_foo to ggc_alloc and you should do the same. Thanks for your hint! I do the same :) https://github.com/xiangzhai/dragonegg/blob/master/src/Cache.cpp#L255 PS: how to find the relative patch for the ChangeLog's item? I use Google, for example: (ggc_alloc): Install the type's destructor as the finalizer if it might do something. Another way is to use "git blame" on the ChangeLog to find the commit that added the ChangeLog entry. For "archived" ChangeLog files like "ChangeLog-2014" that will just tell you which commit moved all of the entries for that years ChangeLog entries to "ChangeLog-2014", so you can use "git log": git log gcc/ChangeLog-2014 to identify the commit that archived the ChangeLog: commit e64e0023b9a6796858262f8fd38005a08d234d82 Author: green Date: Thu Jan 1 15:43:47 2015 + Roll ChangeLog file. Limit offsets to 16 bits for moxie. Once you have that commit you can use "^" to find the prior state of the tree, and then use git blame: git blame e64e0023b9a6796858262f8fd38005a08d234d82^ gcc/ChangeLog Thanks for your hint! and then search for the text of interest: 9296020474 (tbsaunde 2014-05-17 23:15:55 + 38073) 2014-05-17 Trevor Saunders 9296020474 (tbsaunde 2014-05-17 23:15:55 + 38074) 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38075) * ggc-common.c (ggc_internal_cleared_alloc): Adjust. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38076) * ggc-none.c (ggc_internal_alloc): Assert if a finalizer is passed. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38077) (ggc_internal_cleared_alloc): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38078) * ggc-page.c (finalizer): New class. b540cb16c9 (uros 2014-05-18 07:24:24 + 38079) (vec_finalizer): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38080) (globals::finalizers): New member. b540cb16c9 (uros 2014-05-18 07:24:24 + 38081) (globals::vec_finalizers): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38082) (ggc_internal_alloc): Record the finalizer if any for the block bei 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38083) allocated. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38084) (ggc_handle_finalizers): New function. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38085) (ggc_collect): Call ggc_handle_finalizers. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38086) * ggc.h (ggc_internal_alloc): Add arguments to allow installing a 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38087) finalizer. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38088) (ggc_internal_cleared_alloc): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38089) (finalize): New function. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38090) (need_finalization_p): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38091) (ggc_alloc): Install the type's destructor as the finalizer if it 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38092) might do something. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38093) (ggc_cleared_alloc): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38094) (ggc_vec_alloc): Likewise. 92f06184bb (tbsaunde 2014-05-17 23:08:00 + 38095) (ggc_cleared_vec_alloc): Likewise. which identifies the commit as 92f06184bb. "git show 92f06184bb" shows the commit you're looking for, and contains this line: git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210568 138bc75d-0d04-0410-961f-82ee72b054a4 from which you can see (if you need to) that the SVN commit was r210568. Dave -- Regards, Leslie Zhai - a LLVM developer https://reviews.llvm.org/p/xiangzhai/
DragonEgg for GCC v8.x and LLVM v6.x is just able to work
Hi LLVM and GCC developers, My sincere thanks will goto: * Duncan, the core developer of llvm-gcc and dragonegg http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf * David, the innovator and developer of GCC https://dmalcolm.fedorapeople.org/gcc/global-state/requirements.html and others who give me kind response for teaching me patiently and carefully about how to migrate GCC v4.8.x to GCC v8.x (git-20170818) DragonEgg has been migrated to GCC v8.x and LLVM v6.x (svn-r311142), but also able to work for GCC v4.8.x and LLVM v3.3 https://reviews.llvm.org/D35667 and it is just able to work now, for example: CC=/opt/gcc-git/bin/gcc LC=/opt/llvm-svn/bin/llvm-config export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$($LC --libdir) GCC=$CC LLVM_CONFIG=$LC ENABLE_LLVM_PLUGINS=1 DRAGONEGG_DEBUG=1 make -j4 $CC -fplugin=./dragonegg.so \ -fplugin-arg-dragonegg-debug-pass-arguments \ -ftime-report \ -fverbose-asm \ -fplugin-arg-dragonegg-enable-gcc-optzns \ -fplugin-arg-dragonegg-emit-ir \ -S \ test/hello.c \ -wrapper gdb,--args hello.s (LLVM IR, the extension name is not important) ; ModuleID = 'test/hello.c' source_filename = "test/hello.c" target triple = "x86_64-redhat-linux" module asm "\09.ident\09\22GCC: (GNU) 6.4.1 20170727 (Red Hat 6.4.1-1) LLVM: 3.9.1\22" @__func__.2210 = internal local_unnamed_addr constant [4 x i8] c"foo\00" @.cst = private local_unnamed_addr constant [24 x i8] c"DEBUG: %s, line %d: %s\0A\00", align 8 @.cst.1 = private local_unnamed_addr constant [13 x i8] c"test/hello.c\00", align 8 @.cst.2 = private local_unnamed_addr constant [12 x i8] c"Leslie Zhai\00", align 8 @.cst.3 = private local_unnamed_addr constant [20 x i8] c"%s: Hello World %d\0A\00", align 8 ; Function Attrs: nounwind uwtable define void @foo(...) unnamed_addr #0 { entry: %"ssa point" = bitcast i32 0 to i32 br label %"" "": ; preds = %entry %0 = call i32 (i8*, ...) @printf(i8* noalias getelementptr inbounds ([24 x i8], [24 x i8]* @.cst, i64 0, i64 0), [13 x i8]* @.cst.1, i32 4, [4 x i8]* @__func__.2210) #1 br label %return return: ; preds = %"" ret void } declare i32 @printf(i8*, ...) ; Function Attrs: nounwind uwtable define i32 @main(i32 %argc, i8** %argv) unnamed_addr #0 { entry: %argc_addr = alloca i32, align 4 %argv_addr = alloca i8**, align 8 %n = alloca i32 %s = alloca i8* %"" = alloca i32 %"alloca point" = bitcast i32 0 to i32 store i32 %argc, i32* %argc_addr, align 1 store i8** %argv, i8*** %argv_addr, align 1 %"ssa point" = bitcast i32 0 to i32 br label %"" "": ; preds = %entry %0 = call i32 (i8*, ...) @printf(i8* noalias getelementptr inbounds ([20 x i8], [20 x i8]* @.cst.3, i64 0, i64 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.cst.2, i64 0, i64 0), i32 1) #1 br label %"" "": ; preds = %"" store i32 0, i32* %"", align 1 br label %return return: ; preds = %"" %1 = load i32, i32* %"", align 4 ret i32 %1 } attributes #0 = { nounwind uwtable "no-frame-pointer-elim-non-leaf"="true" } attributes #1 = { nounwind } !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIE Level", i32 2} $ llc hello.s .text .file"hello.s" # Start of file scope inline assembly .ident"GCC: (GNU) 6.4.1 20170727 (Red Hat 6.4.1-1) LLVM: 3.9.1" # End of file scope inline assembly .globlfoo .p2align4, 0x90 .typefoo,@function foo:# @foo .cfi_startproc # BB#0: # %entry pushq%rbp .Ltmp0: .cfi_def_cfa_offset 16 .Ltmp1: .cfi_offset %rbp, -16 movq%rsp, %rbp .Ltmp2: .cfi_def_cfa_register %rbp movl$.L.cst, %edi movl$.L.cst.1, %esi movl$4, %edx movl$__func__.2210, %ecx xorl%eax, %eax callqprintf popq%rbp retq .Lfunc_end0: .sizefoo, .Lfunc_end0-foo .cfi_endproc .globlmain .p2align4, 0x90 .typemain,@function main: # @main .cfi_startproc # BB#0: # %entry pushq%rbp .Ltmp3: .cfi_def_cfa_offset 16 .Ltmp4: .cfi_offset %rbp, -16 movq%rsp, %rbp .Ltmp5: .cfi_def_cfa_register %rbp subq$32, %rsp movl%edi, -8(%rbp) movq%rsi, -16(%rbp) movl$.L.cst.3, %edi movl$.L.cst.2,
Re: DragonEgg for GCC v8.x and LLVM v6.x is just able to work
Hi LLVM and GCC developers, LLVM China http://www.llvm.org.cn forked DragonEgg https://github.com/LLVM-China/dragonegg because: * Some subprojects are impractical or uninteresting to relicense (e.g. llvm-gcc and dragonegg). These will be split off from the LLVM project (e.g. to separate Github projects), allowing interested people to continue their development elsewhere. http://lists.llvm.org/pipermail/llvm-dev/2017-August/116266.html * There are a lot of issues https://github.com/xiangzhai/dragonegg/issues so I need smarter developers' help. 在 2017年08月21日 11:31, Leslie Zhai 写道: Hi LLVM and GCC developers, My sincere thanks will goto: * Duncan, the core developer of llvm-gcc and dragonegg http://llvm.org/devmtg/2009-10/Sands_LLVMGCCPlugin.pdf * David, the innovator and developer of GCC https://dmalcolm.fedorapeople.org/gcc/global-state/requirements.html and others who give me kind response for teaching me patiently and carefully about how to migrate GCC v4.8.x to GCC v8.x (git-20170818) DragonEgg has been migrated to GCC v8.x and LLVM v6.x (svn-r311142), but also able to work for GCC v4.8.x and LLVM v3.3 https://reviews.llvm.org/D35667 and it is just able to work now, for example: CC=/opt/gcc-git/bin/gcc LC=/opt/llvm-svn/bin/llvm-config export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$($LC --libdir) GCC=$CC LLVM_CONFIG=$LC ENABLE_LLVM_PLUGINS=1 DRAGONEGG_DEBUG=1 make -j4 $CC -fplugin=./dragonegg.so \ -fplugin-arg-dragonegg-debug-pass-arguments \ -ftime-report \ -fverbose-asm \ -fplugin-arg-dragonegg-enable-gcc-optzns \ -fplugin-arg-dragonegg-emit-ir \ -S \ test/hello.c \ -wrapper gdb,--args hello.s (LLVM IR, the extension name is not important) ; ModuleID = 'test/hello.c' source_filename = "test/hello.c" target triple = "x86_64-redhat-linux" module asm "\09.ident\09\22GCC: (GNU) 6.4.1 20170727 (Red Hat 6.4.1-1) LLVM: 3.9.1\22" @__func__.2210 = internal local_unnamed_addr constant [4 x i8] c"foo\00" @.cst = private local_unnamed_addr constant [24 x i8] c"DEBUG: %s, line %d: %s\0A\00", align 8 @.cst.1 = private local_unnamed_addr constant [13 x i8] c"test/hello.c\00", align 8 @.cst.2 = private local_unnamed_addr constant [12 x i8] c"Leslie Zhai\00", align 8 @.cst.3 = private local_unnamed_addr constant [20 x i8] c"%s: Hello World %d\0A\00", align 8 ; Function Attrs: nounwind uwtable define void @foo(...) unnamed_addr #0 { entry: %"ssa point" = bitcast i32 0 to i32 br label %"" "": ; preds = %entry %0 = call i32 (i8*, ...) @printf(i8* noalias getelementptr inbounds ([24 x i8], [24 x i8]* @.cst, i64 0, i64 0), [13 x i8]* @.cst.1, i32 4, [4 x i8]* @__func__.2210) #1 br label %return return: ; preds = %"" ret void } declare i32 @printf(i8*, ...) ; Function Attrs: nounwind uwtable define i32 @main(i32 %argc, i8** %argv) unnamed_addr #0 { entry: %argc_addr = alloca i32, align 4 %argv_addr = alloca i8**, align 8 %n = alloca i32 %s = alloca i8* %"" = alloca i32 %"alloca point" = bitcast i32 0 to i32 store i32 %argc, i32* %argc_addr, align 1 store i8** %argv, i8*** %argv_addr, align 1 %"ssa point" = bitcast i32 0 to i32 br label %"" "": ; preds = %entry %0 = call i32 (i8*, ...) @printf(i8* noalias getelementptr inbounds ([20 x i8], [20 x i8]* @.cst.3, i64 0, i64 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.cst.2, i64 0, i64 0), i32 1) #1 br label %"" "": ; preds = %"" store i32 0, i32* %"", align 1 br label %return return: ; preds = %"" %1 = load i32, i32* %"", align 4 ret i32 %1 } attributes #0 = { nounwind uwtable "no-frame-pointer-elim-non-leaf"="true" } attributes #1 = { nounwind } !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIE Level", i32 2} $ llc hello.s .text .file"hello.s" # Start of file scope inline assembly .ident"GCC: (GNU) 6.4.1 20170727 (Red Hat 6.4.1-1) LLVM: 3.9.1" # End of file scope inline assembly .globlfoo .p2align4, 0x90 .typefoo,@function foo:# @foo .cfi_startproc # BB#0: # %entry pushq%rbp .Ltmp0: .cfi_def_cfa_offset 16 .Ltmp1: .cfi_offset %rbp, -16 movq%rsp, %rbp .Ltmp2: .cfi_def_cfa_register %rbp movl$.L.cst, %edi movl$.L.cst.1, %esi movl$4, %edx movl$__f
Re: Assigning the result of a function call to a variable in the Gfortran frontend
在 2017年09月05日 14:14, Tobias Grosser 写道: Hi Leslie, I copied you in this thread as you currently worked quite a bit with dragonegg and we are currently trying to generate metadata that makes it easier to reason about multi-dimensional fortran arrays. Best, Tobias On Mon, Sep 4, 2017, at 23:06, (IIIT) Siddharth Bhat wrote: Hello, I've been hacking on the Gfortran frontend to change array index expressions to function calls, so that I can inspect them later on in the pipeline. I go from Fortran -> LLVM IR (through dragonegg) where I will look at the function call nodes. However, I'm not able to generate correct IR for this. I can create function call, but I am unable to assign the return value of a function call to a variable here. Here's a link to my experiments here: It includes a patch, a test file and the GIMPLE output <https://gist.github.com/bollu/999184bdb3d0f1569ee0fd0a351689e3#file-m-gimple-L24> I rebase the patch for GCC v8.x at first: diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9efb531..73dad6e 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3251,6 +3251,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) if (build_class_array_ref (se, tmp, index)) return; + call_polly_index(&se->pre, index, ar); se->expr = gfc_build_array_ref (tmp, index, decl); } @@ -3335,6 +3336,24 @@ build_array_ref (tree desc, tree offset, tree decl, tree vptr) return tmp; } +// See: gfc_call_malloc +static tree call_polly_index(stmtblock_t *parent_block, tree *original_index, +gfc_array_ref *ar) { + tree fncall, var, result; + stmtblock_t block; + + var = gfc_create_var(gfc_array_index_type, "pollyindex"); + gfc_init_block (&block); + + fncall = build_call_expr_loc(input_location, gfor_fndecl_polly_array_index, 0); + gfc_add_modify(&block, var, fold_convert(gfc_array_index_type, fncall)); + result = gfc_finish_block (&block); + gfc_add_expr_to_block(parent_block, result); + return var; + + // return var; +} + /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or component diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 74d8606..28ddcfd 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -95,6 +95,7 @@ static int seen_ieee_symbol; /* Function declarations for builtin library functions. */ +tree gfor_fndecl_polly_array_index; tree gfor_fndecl_pause_numeric; tree gfor_fndecl_pause_string; tree gfor_fndecl_stop_numeric; @@ -3495,6 +3496,14 @@ gfc_build_builtin_function_decls (void) /* ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1; + + printf("building polly_array_index function decl...\n"); + gfor_fndecl_polly_array_index = gfc_build_library_function_decl ( +get_identifier (PREFIX("polly_array_index")), +gfc_array_index_type, 0); + TREE_THIS_VOLATILE (gfor_fndecl_polly_array_index) = 1; + printf("built polly_array_index function decl...\n"); + gfor_fndecl_pause_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("pause_numeric")), void_type_node, 1, gfc_int4_type_node); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index d02f347..c8d24ec 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -781,6 +781,7 @@ struct gimplify_omp_ctx; void gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, tree); /* Runtime library function decls. */ +extern GTY(()) tree gfor_fndecl_polly_array_index; extern GTY(()) tree gfor_fndecl_pause_numeric; extern GTY(()) tree gfor_fndecl_pause_string; extern GTY(()) tree gfor_fndecl_stop_numeric; then I will rebuild GCC for investigation. . Help would be very much appreciated! Thanks, Siddharth. -- Sending this from my phone, please excuse any typos! -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Re: Assigning the result of a function call to a variable in the Gfortran frontend
在 2017年09月05日 15:25, Leslie Zhai 写道: 在 2017年09月05日 14:14, Tobias Grosser 写道: Hi Leslie, I copied you in this thread as you currently worked quite a bit with dragonegg and we are currently trying to generate metadata that makes it easier to reason about multi-dimensional fortran arrays. Best, Tobias On Mon, Sep 4, 2017, at 23:06, (IIIT) Siddharth Bhat wrote: Hello, I've been hacking on the Gfortran frontend to change array index expressions to function calls, so that I can inspect them later on in the pipeline. I go from Fortran -> LLVM IR (through dragonegg) where I will look at the function call nodes. However, I'm not able to generate correct IR for this. I can create function call, but I am unable to assign the return value of a function call to a variable here. Here's a link to my experiments here: It includes a patch, a test file and the GIMPLE output <https://gist.github.com/bollu/999184bdb3d0f1569ee0fd0a351689e3#file-m-gimple-L24> I rebase the patch for GCC v8.x at first: diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9efb531..5cf5ba9 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -91,6 +91,8 @@ along with GCC; see the file COPYING3. If not see #include "dependency.h" static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base); +static tree call_polly_index(stmtblock_t *parent_block, tree *original_index, + gfc_array_ref *ar); /* The contents of this structure aren't actually used, just the address. */ static gfc_ss gfc_ss_terminator_var; @@ -3251,7 +3253,13 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) if (build_class_array_ref (se, tmp, index)) return; + printf("TIMSTAMP: %s - %s\n", __DATE__, __TIME__); + printf("==\n"); + + printf("# 1. index(new):\n"); + call_polly_index(&se->pre, &index, ar); se->expr = gfc_build_array_ref (tmp, index, decl); + printf("==\n"); } @@ -3335,6 +3343,22 @@ build_array_ref (tree desc, tree offset, tree decl, tree vptr) return tmp; } +// See: gfc_call_malloc +static tree call_polly_index(stmtblock_t *parent_block, tree */*original_index*/, +gfc_array_ref */*ar*/) { + tree fncall, var, result; + stmtblock_t block; + + var = gfc_create_var(gfc_array_index_type, "pollyindex"); + gfc_init_block (&block); + + fncall = build_call_expr_loc(input_location, gfor_fndecl_polly_array_index, 0); + gfc_add_modify(&block, var, fold_convert(gfc_array_index_type, fncall)); + result = gfc_finish_block (&block); + gfc_add_expr_to_block(parent_block, result); + return var; +} + /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or component diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 74d8606..28ddcfd 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -95,6 +95,7 @@ static int seen_ieee_symbol; /* Function declarations for builtin library functions. */ +tree gfor_fndecl_polly_array_index; tree gfor_fndecl_pause_numeric; tree gfor_fndecl_pause_string; tree gfor_fndecl_stop_numeric; @@ -3495,6 +3496,14 @@ gfc_build_builtin_function_decls (void) /* ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1; + + printf("building polly_array_index function decl...\n"); + gfor_fndecl_polly_array_index = gfc_build_library_function_decl ( +get_identifier (PREFIX("polly_array_index")), +gfc_array_index_type, 0); + TREE_THIS_VOLATILE (gfor_fndecl_polly_array_index) = 1; + printf("built polly_array_index function decl...\n"); + gfor_fndecl_pause_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("pause_numeric")), void_type_node, 1, gfc_int4_type_node); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index d02f347..c8d24ec 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -781,6 +781,7 @@ struct gimplify_omp_ctx; void gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, tree); /* Runtime library function decls. */ +extern GTY(()) tree gfor_fndecl_polly_array_index; extern GTY(()) tree gfor_fndecl_pause_numeric; extern GTY(()) tree gfor_fndecl_pause_string; extern GTY(()) tree gfor_fndecl_stop_numeric; diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9efb531..73dad6e 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3251,6 +3251,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) if (build_class_array_ref (se, tmp, index)) return; + call_polly_index(&se->pre, index, ar); se->expr = gfc_build_array_ref (tmp, index, decl); } @@ -3335,6 +3336,24 @@ build_array_re
Re: Assigning the result of a function call to a variable in the Gfortran frontend
Hi Tobias, You are welcome! 在 2017年09月06日 13:14, Tobias Grosser 写道: Thank you leslie! Best, Tobias On Wed, Sep 6, 2017, at 05:25, Leslie Zhai wrote: 在 2017年09月05日 15:25, Leslie Zhai 写道: 在 2017年09月05日 14:14, Tobias Grosser 写道: Hi Leslie, I copied you in this thread as you currently worked quite a bit with dragonegg and we are currently trying to generate metadata that makes it easier to reason about multi-dimensional fortran arrays. Best, Tobias On Mon, Sep 4, 2017, at 23:06, (IIIT) Siddharth Bhat wrote: Hello, I've been hacking on the Gfortran frontend to change array index expressions to function calls, so that I can inspect them later on in the pipeline. I go from Fortran -> LLVM IR (through dragonegg) where I will look at the function call nodes. However, I'm not able to generate correct IR for this. I can create function call, but I am unable to assign the return value of a function call to a variable here. Here's a link to my experiments here: It includes a patch, a test file and the GIMPLE output <https://gist.github.com/bollu/999184bdb3d0f1569ee0fd0a351689e3#file-m-gimple-L24> I rebase the patch for GCC v8.x at first: diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9efb531..5cf5ba9 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -91,6 +91,8 @@ along with GCC; see the file COPYING3. If not see #include "dependency.h" static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base); +static tree call_polly_index(stmtblock_t *parent_block, tree *original_index, + gfc_array_ref *ar); /* The contents of this structure aren't actually used, just the address. */ static gfc_ss gfc_ss_terminator_var; @@ -3251,7 +3253,13 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) if (build_class_array_ref (se, tmp, index)) return; + printf("TIMSTAMP: %s - %s\n", __DATE__, __TIME__); + printf("==\n"); + + printf("# 1. index(new):\n"); + call_polly_index(&se->pre, &index, ar); se->expr = gfc_build_array_ref (tmp, index, decl); + printf("==\n"); } @@ -3335,6 +3343,22 @@ build_array_ref (tree desc, tree offset, tree decl, tree vptr) return tmp; } +// See: gfc_call_malloc +static tree call_polly_index(stmtblock_t *parent_block, tree */*original_index*/, +gfc_array_ref */*ar*/) { + tree fncall, var, result; + stmtblock_t block; + + var = gfc_create_var(gfc_array_index_type, "pollyindex"); + gfc_init_block (&block); + + fncall = build_call_expr_loc(input_location, gfor_fndecl_polly_array_index, 0); + gfc_add_modify(&block, var, fold_convert(gfc_array_index_type, fncall)); + result = gfc_finish_block (&block); + gfc_add_expr_to_block(parent_block, result); + return var; +} + /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or component diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 74d8606..28ddcfd 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -95,6 +95,7 @@ static int seen_ieee_symbol; /* Function declarations for builtin library functions. */ +tree gfor_fndecl_polly_array_index; tree gfor_fndecl_pause_numeric; tree gfor_fndecl_pause_string; tree gfor_fndecl_stop_numeric; @@ -3495,6 +3496,14 @@ gfc_build_builtin_function_decls (void) /* ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1; + + printf("building polly_array_index function decl...\n"); + gfor_fndecl_polly_array_index = gfc_build_library_function_decl ( +get_identifier (PREFIX("polly_array_index")), +gfc_array_index_type, 0); + TREE_THIS_VOLATILE (gfor_fndecl_polly_array_index) = 1; + printf("built polly_array_index function decl...\n"); + gfor_fndecl_pause_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("pause_numeric")), void_type_node, 1, gfc_int4_type_node); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index d02f347..c8d24ec 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -781,6 +781,7 @@ struct gimplify_omp_ctx; void gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, tree); /* Runtime library function decls. */ +extern GTY(()) tree gfor_fndecl_polly_array_index; extern GTY(()) tree gfor_fndecl_pause_numeric; extern GTY(()) tree gfor_fndecl_pause_string; extern GTY(()) tree gfor_fndecl_stop_numeric; diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9efb531..73dad6e 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3251,6 +3251,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) if (build_class_a
Re: [llvm-dev] DragonEgg for GCC v8.x and LLVM v6.x is just able to work
Dear Chris, Thanks for your kind response! The motivating of this work: 1. Clang can not build Linux https://bugs.llvm.org/show_bug.cgi?id=22830 and LLVMLinux patch was not be maintained? http://llvm.linuxfoundation.org/index.php/Main_Page 2. Clang analyzer Frontend can not static analysis glibc or Linux https://bugs.llvm.org/show_bug.cgi?id=31017 but analyzer checker is able to find the bugs for KDE :) http://www.leetcode.cn/2016/11/analyzing-code-for-kde-qt-open-source-components.html 3. For leaning GCC plugin, GIMPLE, LLVM IR, GCC PASS, LLVM PASS, CodeGen, etc. from llvm-gcc and dragonegg, thanks for your great job! The usecase for dragonegg: 1. mips64-linux-gnu-gcc (WIP), arm-linux-gnu-gcc and x86 GCC Frontend -> GIMPLE -> LLVM IR -> Assembly or for KLEE 2. GCC Frontend -> GIMPLE -> Clang AST (WIP) I am interested in some other frontend, such as flang-clang https://github.com/flang-compiler/clang/pull/28 and it is glad to learn from other developers :) https://gcc.gnu.org/ml/gcc/2017-09/msg00022.html 在 2017年09月07日 12:10, Chris Lattner 写道: On Sep 4, 2017, at 8:13 PM, Leslie Zhai via llvm-dev wrote: Hi LLVM and GCC developers, LLVM China http://www.llvm.org.cn forked DragonEgg https://github.com/LLVM-China/dragonegg because: * Some subprojects are impractical or uninteresting to relicense (e.g. llvm-gcc and dragonegg). These will be split off from the LLVM project (e.g. to separate Github projects), allowing interested people to continue their development elsewhere. http://lists.llvm.org/pipermail/llvm-dev/2017-August/116266.html * There are a lot of issues https://github.com/xiangzhai/dragonegg/issues so I need smarter developers' help. Hi Leslie, Out of curiosity, what is motivating this work? What is the usecase for dragonegg these days, now that Clang has great C++ support? Are you interested in Ada + LLVM or some other frontend? -Chris -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Register Allocation Graph Coloring algorithm and Others
Hi GCC and LLVM developers, I am learning Register Allocation algorithms and I am clear that: * Unlimited VirtReg (pseudo) -> limited or fixed or alias[1] PhysReg (hard) * Memory (20 - 100 cycles) is expensive than Register (1 cycle), but it has to spill code when PhysReg is unavailable * Folding spill code into instructions, handling register coallescing, splitting live ranges, doing rematerialization, doing shrink wrapping are harder than RegAlloc * LRA and IRA is default Passes in RA for GCC: $ /opt/gcc-git/bin/gcc hello.c DEBUG: ../../gcc/lra.c, lra_init_once, line 2441 DEBUG: ../../gcc/ira-build.c, ira_build, line 3409 * Greedy is default Pass for LLVM But I have some questions, please give me some hint, thanks a lot! * IRA is regional register allocator performing graph coloring on a top-down traversal of nested regions, is it Global? compares with Local LRA * The papers by Briggs and Chaiten contradict[2] themselves when examine the text of the paper vs. the pseudocode provided? * Why interference graph is expensive to build[3]? And I am practicing[4] to use HEA, developed by Dr. Rhydian Lewis, for LLVM firstly. [1] https://reviews.llvm.org/D39712 [2] http://lists.llvm.org/pipermail/llvm-dev/2008-March/012940.html [3] https://github.com/joaotavio/llvm-register-allocator [4] https://github.com/xiangzhai/llvm/tree/avr/include/llvm/CodeGen/GCol -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Re: Register Allocation Graph Coloring algorithm and Others
Hi Vladimir, Thanks for your kind and very detailed response! 在 2017年12月15日 12:40, Vladimir Makarov 写道: On 12/14/2017 10:18 PM, Leslie Zhai wrote: Hi GCC and LLVM developers, I am learning Register Allocation algorithms and I am clear that: * Unlimited VirtReg (pseudo) -> limited or fixed or alias[1] PhysReg (hard) * Memory (20 - 100 cycles) is expensive than Register (1 cycle), but it has to spill code when PhysReg is unavailable It might be much less if memory value is in L1 cache. * Folding spill code into instructions, handling register coallescing, splitting live ranges, doing rematerialization, doing shrink wrapping are harder than RegAlloc RegAlloc is in a wide sense includes all this tasks and more. For some architectures, other tasks like a right live range splitting might be even more important for generated code quality than just better graph coloring. * LRA and IRA is default Passes in RA for GCC: $ /opt/gcc-git/bin/gcc hello.c DEBUG: ../../gcc/lra.c, lra_init_once, line 2441 DEBUG: ../../gcc/ira-build.c, ira_build, line 3409 * Greedy is default Pass for LLVM But I have some questions, please give me some hint, thanks a lot! * IRA is regional register allocator performing graph coloring on a top-down traversal of nested regions, is it Global? compares with Local LRA IRA is a global RA. The description of its initial version can be found https://vmakarov.fedorapeople.org/vmakarov-submission-cgo2008.pdf I am reading this paper at present :) LRA in some way is also global RA but it is a very simplified version of global RA (e.g. LRA does not use conflict graph and its coloring algoritm is closer to priority coloring). LRA does a lot of other very complicated things besides RA, for example instruction selection which is quite specific to GCC machine description. Usually code selection task is a separate pass in other compilers. Generally speaking LRA is more complicated, machine dependent and more buggy than IRA. But fortunately LRA is less complicated than its predecessor so called reload pass. IRA and LRA names have a long history and they do not reflect correctly the current situation. It would be possible to incorporate LRA tasks into IRA, but the final RA would be much slower, even more complicated and hard to maintain and the generated code would be not much better. So to improve RA maintainability, RA is divided on two parts solving a bit different tasks. This is a typical engineering approach. I am debugging by printf to be familiar with LRA and IRA. * The papers by Briggs and Chaiten contradict[2] themselves when examine the text of the paper vs. the pseudocode provided? I don't examine Preston Briggs work so thoroughly. So I can not say that is true. Even so it is natural that there are discrepancy in pseudocode and its description especially for such size description. For me Preston Briggs is famous for his introduction of optimistic coloring. * Why interference graph is expensive to build[3]? That is because it might be N^2 algorithm. There are a lot of publications investigating building conflict graphs and its cost in RAs. And I am practicing[4] to use HEA, developed by Dr. Rhydian Lewis, for LLVM firstly. When I just started to work on RAs very long ago I used about the same approach: a lot of tiny transformations directed by a cost function and using metaheuristics (I also used tabu search as HEA). Nothing good came out of this. Thanks for your lesson! But are there some benchmarks when you used Tabu search as HEA, AntCol, etc. such as https://pbs.twimg.com/media/DRD-kxcUMAAxZec.jpg If you are interesting in RA algorithms and architectures, I'd recommend Michael Matz article ftp://gcc.gnu.org/pub/gcc/summit/2003/Graph%20Coloring%20Register%20Allocation.pdf as a start point. Thanks! I am reading it. [1] https://reviews.llvm.org/D39712 [2] http://lists.llvm.org/pipermail/llvm-dev/2008-March/012940.html [3] https://github.com/joaotavio/llvm-register-allocator [4] https://github.com/xiangzhai/llvm/tree/avr/include/llvm/CodeGen/GCol -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Re: Register Allocation Graph Coloring algorithm and Others
Hi David, Thanks for your teaching! I am a newbie in compiler area, I only learned Compiler Principle in 2002 https://www.leetcode.cn/2017/12/ilove-compiler-principle.html But I like to practice and learn :) https://github.com/xiangzhai/llvm/blob/avr/lib/CodeGen/RegAllocGraphColoring.cpp#L327 because theory is not always correct, or misunderstood by people, so I want to compare solutionByHEA, IRA, Greedy, PBQP and other algorithms. Thanks for your lessons to correct my mistakes, such as memory=bad register=good, and I need to find the answer *when* memory is worse than a register, I am maintaining AVR target, there are 32 general registers, 32K flash, 2K sram http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf so perhaps to MCU, memory might be expensive than register? but what about AMDGPU or VLIW processors? I don't have experienced on them, please teach me. I am reading LLVM's code SpillXXX, LiveRangeXXX, RegisterCoalescer, etc. to get the whole view of CodeGen. I am reading Dr. Rhydian Lewis's book: A Guide to Graph Colouring: Algorithms and Applications http://www.springer.com/us/book/9783319257280 and other papers, even if HEA is not the best solution, I still want to practice and see the benchmark, I am not computing professionals, I am only 34 olds, perhaps I have enough time to waste :) 在 2017年12月19日 00:41, d...@cray.com 写道: Leslie Zhai writes: * Memory (20 - 100 cycles) is expensive than Register (1 cycle), but it has to spill code when PhysReg is unavailable As Vladimir said, the cache makes this kind of analysis much more tricky. It's not necessarily the case that memory=bad and register=good. Since there are tradeoffs involved, one needs to evaluate different strategies to determine *when* memory is worse than a register. It may very well be the case that leaving something in memory frees up a register for something much more important to use it. All of the register allocation algorithms try to determine this kind of thing through various heuristics. Which heuristic is most effective is highly target-dependent. In my experience, changing heuristics can swing performance 20% or more in some cases. Today's processors and memory systems are so complex that 2nd- and even 3rd-order effects become important. It is very, very wrong on today's machines to use # of spills as a metric to determine the "goodness" of an allocation. Determining *what* to spill is much more important than the raw number of spills. Many times I have a seen codes generated with more spills perform much better than the code generated with fewer spills. Almost all of the papers around the time of Chaiten-Briggs used # of spills as the metric. That may have been appropriate at that time but take those results with giant grains of salt today. Of course they are still very good papers for understanding algorithms and heuristics. The best way I know to determine what's best for your target is to run a whole bunch of *real* codes on them, trying different allocation algorithms and heuristics. It is a lot of work, still worthy of a Ph.D. even today. Register allocation is not a "solved" problem and probably never will be as architectures continue to change and become ever more diverse. * Folding spill code into instructions, handling register coallescing, splitting live ranges, doing rematerialization, doing shrink wrapping are harder than RegAlloc Again, as Vladimir said, they are all part of register allocation. Sometimes they are implemented as separate passes but logically they all contribute work to the task of assigning registers as efficiently as possible. And all of them use heuristics. Choosing when and when not to, for example, coalesce can be important. Splitting live ranges is logically the opposite of coalescing. Theoretically one can "undo" a bad coalescing decision by re-splitting the live range but it's usually not that simple as other decisions in the interim can make that tricky if not impossible. It is a delicate balancing act. * The papers by Briggs and Chaiten contradict[2] themselves when examine the text of the paper vs. the pseudocode provided? As others have said, I don't recall any inconsistencies but that doesn't mean there aren't bugs and/or incomplete descriptions open to interpretation. One of my biggest issues with our computer academic culture is that we do not value repeatability. It is virtually impossible to take a paper, implement the algorithm as described (or as best as possible given ambiguity) and obtain the same results. Heck, half my Ph.D. dissertation was dissecting a published paper, examining the sensitivity of the described algorithm to various parts of the described heuristic that were ambiguous. By interpreting the heuristic description in different ways I observed very different results. I
Re: Register Allocation Graph Coloring algorithm and Others
Hi Michael, Thanks for your sharing! I will read the papers as you suggested, and I asked Quantum Computing professionals about solving the NP-complete problem https://github.com/epiqc/ScaffCC/issues/14 but GCC's IRA and LRA proved that there is a solution in SSA form for classical computer. Sorting MachineBasicBlock by frequency firstly is a good idea, and I only experienced some PASS, such as LoopUnroll http://lists.llvm.org/pipermail/llvm-dev/2017-October/118419.html but I will practice your idea in my solutionByHEA https://github.com/xiangzhai/llvm/blob/avr/lib/CodeGen/RegAllocGraphColoring.cpp#L327 I experienced binary translation from X86 to Mips, QEMU is expensive https://www.leetcode.cn/2017/09/tcg-ir-to-llvm-ir.html I will bookmark your JIT engine to my blog :) 在 2017年12月19日 08:07, Michael Clark 写道: Hi Leslie, I suggest adding these 3 papers to your reading list. Register allocation for programs in SSA-form Sebastian Hack, Daniel Grund, and Gerhard Goos http://www.rw.cdl.uni-saarland.de/~grund/papers/cc06-ra_ssa.pdf Simple and Efficient Construction of Static Single Assignment Form Matthias Braun , Sebastian Buchwald , Sebastian Hack , Roland Leißa , Christoph Mallon , and Andreas Zwinkau https://www.info.uni-karlsruhe.de/uploads/publikationen/braun13cc.pdf Optimal register allocation for SSA-form programs in polynomial time Sebastian Hack, Gerhard Goos http://web.cs.ucla.edu/~palsberg/course/cs232/papers/HackGoos-ipl06.pdf A lot of the earlier literature regarding the register allocation problem describes the general graph colouring problem as NP-complete, however previous research in Register Allocation has been in the context of programs that were not in SSA form. i.e. the Chaitin-Briggs paper states that register allocation is NP-complete and proposes an iterative algorithm. If one reads Hack Goos, there is the discovery that programs that are in SSA form have chordal graphs, and the colouring algorithm for chordal graphs can be completed in polynomial time. After the cost of building the interference graph, it is possible to perform register allocation in a single pass. The key is in not modifying the graph. If one has frequency for each basic block, then one can sort basic blocks by frequency, allocating the highest frequency blocks first, and where possible assigning the same physcial register to all virtual registers in each phi node (to avoid copies). At program points where the live set is larger than k, the set of physical registers, one spills the the register that has the largest distance between its next use. At least that is how I am thinking about this problem. I am also a novice with regards to register allocation. I intend to develop a register allocator for use in this JIT engine: rv8: a high performance RISC-V to x86 binary translator Michael Clark, Bruce Hoult https://carrv.github.io/papers/clark-rv8-carrv2017.pdf Our JIT already performs almost twice as fast a QEMU and we are using a static register allocation, and QEMU i believe has a register allocator. We are mapping a 31 register RISC architecture to a 16 register CISC architecture. I have statistics on the current slow-down, and it appears to mainly be L1 accesses to spilled registers. I believe after we have implemented a register allocator in our JIT we will be able to run RISC-V binaries at near native performance on x86-64. In fact given we are performing runtime profile guided optimisation, it may even be possible for some benchmarks to run faster than register allocations that are based on static estimates of loop frequencies. https://anarch128.org/~mclark/rv8-slides.pdf https://rv8.io/bench We’ve still got a long way to go to get to ~1:1 performance for RISC-V on x86-64, but I think it is possible, at least for some codes… Regards, Michael. On 15/12/2017, at 4:18 PM, Leslie Zhai wrote: Hi GCC and LLVM developers, I am learning Register Allocation algorithms and I am clear that: * Unlimited VirtReg (pseudo) -> limited or fixed or alias[1] PhysReg (hard) * Memory (20 - 100 cycles) is expensive than Register (1 cycle), but it has to spill code when PhysReg is unavailable * Folding spill code into instructions, handling register coallescing, splitting live ranges, doing rematerialization, doing shrink wrapping are harder than RegAlloc * LRA and IRA is default Passes in RA for GCC: $ /opt/gcc-git/bin/gcc hello.c DEBUG: ../../gcc/lra.c, lra_init_once, line 2441 DEBUG: ../../gcc/ira-build.c, ira_build, line 3409 * Greedy is default Pass for LLVM But I have some questions, please give me some hint, thanks a lot! * IRA is regional register allocator performing graph coloring on a top-down traversal of nested regions, is it Global? compares with Local LRA * The papers by Briggs and Chaiten contradict[2] themselves when exa
Re: [llvm-dev] Register Allocation Graph Coloring algorithm and Others
Hi Matthias, Thanks for your hint! It is just for learning and practicing for me, just like migrate DragonEgg http://lists.llvm.org/pipermail/llvm-dev/2017-September/117201.html the motivating is for learning from GCC and LLVM developers. 在 2017年12月19日 10:07, Matthias Braun 写道: On Dec 18, 2017, at 9:52 AM, Leslie Zhai via llvm-dev mailto:llvm-...@lists.llvm.org>> wrote: Hi David, Thanks for your teaching! I am a newbie in compiler area, I only learned Compiler Principle in 2002https://www.leetcode.cn/2017/12/ilove-compiler-principle.html But I like to practice and learn :)https://github.com/xiangzhai/llvm/blob/avr/lib/CodeGen/RegAllocGraphColoring.cpp#L327because theory is not always correct, or misunderstood by people, so I want to compare solutionByHEA, IRA, Greedy, PBQP and other algorithms. Just as another tip: - Indeed in my experience: Just implementing some algorithms yourself and comparing them against what existing compilers produce and then figuring out why is the best way to learn about allocators. - Don't just put emphasis on all the different different coloring techniques. In practice it is usually the way you deal register constraints and other target specific coloring constraints, rematerialization and how you get coalescing into the picture. Most regalloc papers don't talk too much about that as it's highly finicky and often target specific. But they do have a huge impact on allocation quality and can make or break any of those algorithms... - Matthias Thanks for your lessons to correct my mistakes, such as memory=bad register=good, and I need to find the answer *when* memory is worse than a register, I am maintaining AVR target, there are 32 general registers, 32K flash, 2K sramhttp://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdfso perhaps to MCU, memory might be expensive than register? but what about AMDGPU or VLIW processors? I don't have experienced on them, please teach me. I am reading LLVM's code SpillXXX, LiveRangeXXX, RegisterCoalescer, etc. to get the whole view of CodeGen. I am reading Dr. Rhydian Lewis's book: A Guide to Graph Colouring: Algorithms and Applicationshttp://www.springer.com/us/book/9783319257280 and other papers, even if HEA is not the best solution, I still want to practice and see the benchmark, I am not computing professionals, I am only 34 olds, perhaps I have enough time to waste :) 在 2017年12月19日 00:41,d...@cray.com <mailto:d...@cray.com>写道: Leslie Zhai mailto:lesliez...@llvm.org.cn>> writes: * Memory (20 - 100 cycles) is expensive than Register (1 cycle), but it has to spill code when PhysReg is unavailable As Vladimir said, the cache makes this kind of analysis much more tricky. It's not necessarily the case that memory=bad and register=good. Since there are tradeoffs involved, one needs to evaluate different strategies to determine *when* memory is worse than a register. It may very well be the case that leaving something in memory frees up a register for something much more important to use it. All of the register allocation algorithms try to determine this kind of thing through various heuristics. Which heuristic is most effective is highly target-dependent. In my experience, changing heuristics can swing performance 20% or more in some cases. Today's processors and memory systems are so complex that 2nd- and even 3rd-order effects become important. It is very, very wrong on today's machines to use # of spills as a metric to determine the "goodness" of an allocation. Determining *what* to spill is much more important than the raw number of spills. Many times I have a seen codes generated with more spills perform much better than the code generated with fewer spills. Almost all of the papers around the time of Chaiten-Briggs used # of spills as the metric. That may have been appropriate at that time but take those results with giant grains of salt today. Of course they are still very good papers for understanding algorithms and heuristics. The best way I know to determine what's best for your target is to run a whole bunch of *real* codes on them, trying different allocation algorithms and heuristics. It is a lot of work, still worthy of a Ph.D. even today. Register allocation is not a "solved" problem and probably never will be as architectures continue to change and become ever more diverse. * Folding spill code into instructions, handling register coallescing, splitting live ranges, doing rematerialization, doing shrink wrapping are harder than RegAlloc Again, as Vladimir said, they are all part of register allocation. Sometimes they are implemented as separate passes but logically they all contribute work to the task of assigning registers as efficiently as possible. And all of them use heuristics. Choosing when and when not to, for
Re: Register Allocation Graph Coloring algorithm and Others
Hi Jakob, Thanks for your kind response! My usecase is for AVR and RISCV targets, and I just want to learn and practice HEA in RA, thanks for your sharing. 在 2017年12月21日 01:25, Jakob Stoklund Olesen 写道: On Dec 18, 2017, at 19:03, Leslie Zhai <mailto:lesliez...@llvm.org.cn>> wrote: Hi Leslie, As others have pointed out, the notion that register allocation is isomorphic to graph coloring is poppycock. There are other important aspects, in particular the placement of spill/fill/copy instructions. The importance of graph coloring relative to spill code placement depends on how many registers you have available. If you are generating code for 32-bit x86 which has only 6-7 general purpose registers, you will have so much spill code and short live ranges that graph coloring doesn’t matter much at all. On the other hand, if you have 32 registers like Chaitin did, you have much less spilling in typical code, and the graph coloring aspect becomes important. Early compilers would keep each local variable in a stack slot, and the register allocation optimization would literally allocate a whole local variable to a register. The C “register” keyword makes sense in that context. Later improvements like copy coalescing and live range splitting meant that multiple local variables could use the same register and a variable could live in different places at different times. It is sometimes useful to take this development to its logical extreme and look at register allocation as a caching problem: The register allocator’s job is to make sure that values are available to the instructions the need them, using the registers as a cache to get the values there in the most efficient way possible. Guo, J., Garzarán, M. J., & Padua, D. (2004). The Power of Belady’s Algorithm in Register Allocation for Long Basic Blocks. In Languages and Compilers for Parallel Computing (Vol. 2958, pp. 374–389). Berlin, Heidelberg: Springer Berlin Heidelberg. http://doi.org/10.1007/978-3-540-24644-2_24 Braun, M., & Hack, S. (2009). Register spilling and live-range splitting for SSA-form programs. International Conference on Compiler Construction. When you look at register allocation that way, the graph coloring aspect almost disappears. The optimum approach is probably somewhere in the middle. A third important aspect is register constraints on individual instructions. Sometimes you almost need a little constraint solver just to figure out a valid register assignment for a single instruction. Preston Briggs dealt with this in his thesis, but it hasn’t gotten as much attention as graph coloring since. Pereira, F. Q., & Palsberg, J. (2008). Register allocation by puzzle solving. Regards, /jakob -- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Re: [llvm-dev] Register Allocation Graph Coloring algorithm and Others
Hi Bruce, Thanks for your sharing! I am porting GlobalISel to RISCV target[1], the highest priority in the TODO list[2], welcome to contribute to lowRISC, if fixed all the issues, then I could try to implement RegAllocGraphColoring in HEA and write great Machine Schedulers. [1] https://github.com/lowRISC/riscv-llvm/issues/19 [2] https://github.com/lowRISC/riscv-llvm/issues 在 2017年12月21日 19:09, Bruce Hoult 写道: So, both AVR and RISC-V are fairly register-rich with usually 32. RV32E only has 16, but that's still a lot better than i386. If you use a lot of 16 bit integers then AVR also only has effectively 16 registers (or a more with a mix of 8 and 16 bit variables). 32 bit integers should be rare in AVR code, but soft float/double variables are common in Arduino code (both are implemented as 32 bits), so you only have room for 8 of those. RISC-V doesn't have any hard constraints on something that *must* go in a certain register, except the usual argument passing/return convention. There is a an advantage to allocating both the data src/dst register and the pointer base register for a load or store from x8-x15 (s0-1,a0-5) as much as possible as this allows the assembler to use a two byte instruction instead of a four byte instruction. I haven't look at AVR in detail for a while, but I seem to recall the top six registers make up three 16 bit pointer registers X,Y,Z. Any of them can be used for (C language) *p, *--p, *p++, only Y&Z can be used for p->foo, and only Z can be used for computed jumps (including function link register) or loading constants from program memory. Also the various multiply instructions take their 8 bit operands from any registers but always produce the 16 bit result in r1:r0. Annoying but nowhere near as bad as i386 as r0 and r1 are not used for anything else. The usual ABI makes r0 a clobber-at-will temp. r1 is supposed to be "always zero", so you need to CLR it after retrieving (or ignoring) the high bits of a multiply result. On Thu, Dec 21, 2017 at 3:44 AM, Leslie Zhai via llvm-dev mailto:llvm-...@lists.llvm.org>> wrote: Hi Jakob, Thanks for your kind response! My usecase is for AVR and RISCV targets, and I just want to learn and practice HEA in RA, thanks for your sharing. 在 2017年12月21日 01:25, Jakob Stoklund Olesen 写道: On Dec 18, 2017, at 19:03, Leslie Zhai mailto:lesliez...@llvm.org.cn> <mailto:lesliez...@llvm.org.cn <mailto:lesliez...@llvm.org.cn>>> wrote: Hi Leslie, As others have pointed out, the notion that register allocation is isomorphic to graph coloring is poppycock. There are other important aspects, in particular the placement of spill/fill/copy instructions. The importance of graph coloring relative to spill code placement depends on how many registers you have available. If you are generating code for 32-bit x86 which has only 6-7 general purpose registers, you will have so much spill code and short live ranges that graph coloring doesn’t matter much at all. On the other hand, if you have 32 registers like Chaitin did, you have much less spilling in typical code, and the graph coloring aspect becomes important. Early compilers would keep each local variable in a stack slot, and the register allocation optimization would literally allocate a whole local variable to a register. The C “register” keyword makes sense in that context. Later improvements like copy coalescing and live range splitting meant that multiple local variables could use the same register and a variable could live in different places at different times. It is sometimes useful to take this development to its logical extreme and look at register allocation as a caching problem: The register allocator’s job is to make sure that values are available to the instructions the need them, using the registers as a cache to get the values there in the most efficient way possible. Guo, J., Garzarán, M. J., & Padua, D. (2004). The Power of Belady’s Algorithm in Register Allocation for Long Basic Blocks. In Languages and Compilers for Parallel Computing (Vol. 2958, pp. 374–389). Berlin, Heidelberg: Springer Berlin Heidelberg. http://doi.org/10.1007/978-3-540-24644-2_24 <http://doi.org/10.1007/978-3-540-24644-2_24> Braun, M., & Hack, S. (2009). Register spilling and live-range splitting for SSA-form programs. International Conference on Compiler Construction. When you look at register allocation that way, the graph coloring aspect almost disappears. The optimum approach is probably
Re: [llvm-dev] GCC 5 and -Wstrict-aliasing in JSON.h
json::Value::as() const [with T = llvm::json::Object]’: /home/loongson/llvm/include/llvm/Support/JSON.h:424:62: required from here /home/loongson/llvm/include/llvm/Support/JSON.h:455:47: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] /home/loongson/llvm/include/llvm/Support/JSON.h: In instantiation of ‘T& llvm::json::Value::as() const [with T = llvm::json::Array]’: /home/loongson/llvm/include/llvm/Support/JSON.h:430:60: required from here /home/loongson/llvm/include/llvm/Support/JSON.h:455:47: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] Hi GCC developers, Thanks for your patch to gcc-7-branch! Could you test to compile LLVM with GCC old versions 4/5/6? Does it need to backport your patch to GCC old version? 1. $ cat punning.cpp template struct aligned_storage { union type { unsigned char __data[_Len]; struct __attribute__((__aligned__((_Align { } __align; }; }; aligned_storage::type storage; int main() { *reinterpret_cast(&storage) = 42; } 2. Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/mips64el-redhat-linux/4.9.3/lto-wrapper Target: mips64el-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-arch=loongson3a --enable-languages=c,c++,objc,obj-c++,fortran,go,lto --enable-plugin --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/cloog-install --enable-gnu-indirect-function --with-long-double-128 --build=mips64el-redhat-linux Thread model: posix gcc version 4.9.3 20150626 (Red Hat 4.9.3-8) (GCC) 在 2018年08月09日 04:31, Kim Gräsman via llvm-dev 写道: Hello, For the IWYU project, we have a buildbot on Ubuntu 16.04 and its bundled GCC (which I think is some GCC 5 variant). We're getting a number of -Wstrict-aliasing warnings from JSON.h on this line: https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/JSON.h#L455 I'm not sure if GCC has a point here but GCC 7.2 does not complain, so I'm going to guess no. Would you consider patches to disable -Wstrict-aliasing wholesale for GCC 5 and older? But it is *no* warning when bootstrap with LLVM toolchain, and Sam should test it before code review https://reviews.llvm.org/D45753 - Kim ___ LLVM Developers mailing list llvm-...@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -- Regards, Leslie Zhai
Re: [llvm-dev] GCC 5 and -Wstrict-aliasing in JSON.h
Hi Jonathan, Thanks for your response! So workaround for Kim's issue is bootstrap old version LLVM with GCC 4/5 to build old clang, then bootstrap latest LLVM with old clang. 在 2018年08月09日 17:16, Jonathan Wakely 写道: On Thu, 9 Aug 2018 at 03:09, Leslie Zhai wrote: Could you test to compile LLVM with GCC old versions 4/5/6? Does it need to backport your patch to GCC old version? GCC versions before 6.4 are not supported, so no backports will happen to 4.x or 5 releases and I doubt anybody's going to routinely test anything with them. If there's a bug in GCC 4.9.3 that you can't work around then you should upgrade to a supported release (or use a distribution that provides support for older releases). -- Regards, Leslie Zhai
Re: [llvm-dev] GCC 5 and -Wstrict-aliasing in JSON.h
Hi Sam, Thanks for your response! Please review it, thanks a lot! A patch by Loongson! diff --git a/include/llvm/Support/JSON.h b/include/llvm/Support/JSON.h index da3c5ea..fd60b40 100644 --- a/include/llvm/Support/JSON.h +++ b/include/llvm/Support/JSON.h @@ -452,7 +452,10 @@ private: new (reinterpret_cast(Union.buffer)) T(std::forward(V)...); } template T &as() const { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" return *reinterpret_cast(Union.buffer); +#pragma GCC diagnostic pop } template 在 2018年08月09日 19:25, Sam McCall 写道: Author of the problematic code here. Thanks everyone, and sorry to have caused difficulty! Obviously if there really is something illegal here we should fix it in LLVM, but it looks like this warning is a false positive (anyone disagree?) False positive! Still if there's a simple source-level workaround, or we can suppress the warning with a #pragma, I'd be happy to do that. GCC 4.9.3 is a supported compiler for LLVM and the more configurations we build cleanly in, the better. If this is a useful direction, could someone with an affected environment send me a small patch? I don't have the right setup to verify myself. I test it for mips64el built with gcc-4-branch: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/mips64el-redhat-linux/4.9.3/lto-wrapper Target: mips64el-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-arch=loongson3a --enable-languages=c,c++,objc,obj-c++,fortran,go,lto --enable-plugin --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/cloog-install --enable-gnu-indirect-function --with-long-double-128 --build=mips64el-redhat-linux Thread model: posix gcc version 4.9.3 20150626 (Red Hat 4.9.3-8) (GCC) Cheers, Sam -- Regards, Leslie Zhai
[MIPS] hsdis need non-executable PT_GNU_STACK support
Hi all, hsdis PrintLIRWithAssembly failed to work for mips64el after upgraded to jdk8u181-b13. http://mail.openjdk.java.net/pipermail/jdk8u-dev/2018-August/007753.html The root cause is the patch [MIPS] Enable non-executable PT_GNU_STACK support, contributed by Faraz in 2016 February, had not been merged by GCC toolchain upstream. https://gcc.gnu.org/ml/gcc-patches/2016-02/msg00444.html And Maciej also need to increase `MAJOR_VERSION` to check whether or not support IFUNC, unfortunately still not merged by upstream. https://sourceware.org/ml/libc-alpha/2016-12/msg00856.html But I would apply the patch and rebuild gcc-8.1, binutils-gdb-2.30, glibc-2.27, to support Faraz, Joseph and Maciej :) Thanks for your great job! 在 2018年08月14日 14:15, Florian Weimer 写道: On 08/14/2018 04:08 AM, Leslie Zhai wrote: But workaround for mips64el's PrintLIRWithAssembly is adding -Wl,-z,noexecstack linking flag, strangely X86 does *not* need such flag, so I am investigating the root cause. MIPS soft-float apparently needs an executable stack: <https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html> <https://sourceware.org/ml/libc-alpha/2016-01/msg00719.html> This could be why the toolchain does not specify a non-executable stack by default. Florian -- Regards, Leslie Zhai
Re: [MIPS] hsdis need non-executable PT_GNU_STACK support
Hi Joseph, Thanks for your response! hsdis is just able to workaround when linking with -Wl,-z,noexecstack flag, and my environment: $ uname -a Linux localhost.localdomain 3.10.84-19.fc21.loongson.2.mips64el #1 SMP PREEMPT Fri Jul 6 18:47:47 CST 2018 mips64 mips64 mips64 GNU/Linux $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/mips64el-redhat-linux/4.9.3/lto-wrapper Target: mips64el-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-arch=loongson3a --enable-languages=c,c++,objc,obj-c++,fortran,go,lto --enable-plugin --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.3/obj-mips64el-redhat-linux/cloog-install --enable-gnu-indirect-function --with-long-double-128 --build=mips64el-redhat-linux Thread model: posix gcc version 4.9.3 20150626 (Red Hat 4.9.3-8) (GCC) $ ld -v GNU ld version 2.24 $ rpm -q glibc glibc-2.20-15.fc21.loongson.10.mips64el But I want to find out the root cause, I have no idea whether or not kernel supported ELF MIPS_GNU_STACK: + /* Flag to indicate that non-executable stack supported by kernel. +Ref: arch/mips/include/asm/elf.h in kernel sources. */ +#define AV_FLAGS_MIPS_GNU_STACK(1 << 24) https://sourceware.org/ml/libc-alpha/2016-01/msg00568.html But what is the status of kernel and toolchain for X86? Why it is *not* able to reproduce the hsdis issue for X86? And I can prepare the test environment with the latest kernel and toolchain applied with your patch. Please give me some suggestion to support your job, thanks a lot! 在 2018年08月14日 17:43, Joseph Myers 写道: On Tue, 14 Aug 2018, Leslie Zhai wrote: The root cause is the patch [MIPS] Enable non-executable PT_GNU_STACK support, contributed by Faraz in 2016 February, had not been merged by GCC toolchain upstream. https://gcc.gnu.org/ml/gcc-patches/2016-02/msg00444.html Was there a non-RFC GCC patch posting? RFC means you're looking for comments with a view to producing later patch versions, not for an actual review with a view to getting that version of the changes checked in. As noted in <https://sourceware.org/ml/libc-alpha/2016-12/msg00853.html> you'll need a non-RFC glibc patch posting, with architecture-independent and MIPS-specific parts split out, and with comments pointing to the upstream releases of kernel, GCC, binutils with relevant support. -- Regards, Leslie Zhai