libFirm 1.20
libfirm/irhooks.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
00003  *
00004  * This file is part of libFirm.
00005  *
00006  * This file may be distributed and/or modified under the terms of the
00007  * GNU General Public License version 2 as published by the Free Software
00008  * Foundation and appearing in the file LICENSE.GPL included in the
00009  * packaging of this file.
00010  *
00011  * Licensees holding valid libFirm Professional Edition licenses may use
00012  * this file in accordance with the libFirm Commercial License.
00013  * Agreement provided with the Software.
00014  *
00015  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00017  * PURPOSE.
00018  */
00019 
00025 #ifndef FIRM_IR_IRHOOKS_H
00026 #define FIRM_IR_IRHOOKS_H
00027 
00028 #include "irop.h"
00029 #include "irnode.h"
00030 #include "irgraph.h"
00031 #include "begin.h"
00032 
00036 typedef enum {
00037     HOOK_OPT_DEAD_BLOCK,  
00038     HOOK_OPT_STG,         
00039     HOOK_OPT_IFSIM,       
00040     HOOK_OPT_CONST_EVAL,  
00041     HOOK_OPT_ALGSIM,      
00042     HOOK_OPT_PHI,         
00043     HOOK_OPT_SYNC,        
00044     HOOK_OPT_WAW,         
00045     HOOK_OPT_WAR,         
00046     HOOK_OPT_RAW,         
00047     HOOK_OPT_RAR,         
00048     HOOK_OPT_RC,          
00049     HOOK_OPT_TUPLE,       
00050     HOOK_OPT_ID,          
00051     HOOK_OPT_CSE,         
00052     HOOK_OPT_STRENGTH_RED,
00053     HOOK_OPT_ARCH_DEP,    
00054     HOOK_OPT_REASSOC,     
00055     HOOK_OPT_POLY_CALL,   
00056     HOOK_OPT_IF_CONV,     
00057     HOOK_OPT_FUNC_CALL,   
00058     HOOK_OPT_CONFIRM,     
00059     HOOK_OPT_CONFIRM_C,   
00060     HOOK_OPT_CONFIRM_E,   
00061     HOOK_OPT_EXC_REM,     
00062     HOOK_OPT_NORMALIZE,   
00063     HOOK_LOWERED,         
00064     HOOK_BACKEND,         
00065     HOOK_OPT_LAST
00066 } hook_opt_kind;
00067 
00069 typedef enum if_result_t {
00070     IF_RESULT_SUCCESS         = 0,  
00071     IF_RESULT_SIDE_EFFECT     = 1,  
00072     IF_RESULT_SIDE_EFFECT_PHI = 2,  
00073     IF_RESULT_TOO_DEEP        = 3,  
00074     IF_RESULT_BAD_CF          = 4,  
00075     IF_RESULT_DENIED          = 5,  
00076     IF_RESULT_LAST
00077 } if_result_t;
00078 
00082 typedef void (generic_func)(void);
00083 
00087 typedef struct hook_entry {
00089     union {
00091         void (*_hook_new_ir_op)(void *context, ir_op *op);
00092 
00094         void (*_hook_free_ir_op)(void *context, ir_op *op);
00095 
00097         void (*_hook_new_node)(void *context, ir_graph *graph, ir_node *node);
00098 
00100         void (*_hook_set_irn_n)(void *context, ir_node *src,
00101                                 int pos, ir_node *tgt, ir_node *old_tgt);
00102 
00104         void (*_hook_replace)(void *context, ir_node *old_node, ir_node *new_node);
00105 
00107         void (*_hook_turn_into_id)(void *context, ir_node *node);
00108 
00110         void (*_hook_normalize)(void *context, ir_node *node);
00111 
00114         void (*_hook_new_graph)(void *context, ir_graph *irg, ir_entity *ent);
00115 
00117         void (*_hook_free_graph)(void *context, ir_graph *irg);
00118 
00120         void (*_hook_irg_walk)(void *context, ir_graph *irg, generic_func *pre, generic_func *post);
00121 
00123         void (*_hook_irg_walk_blkwise)(void *context, ir_graph *irg, generic_func *pre, generic_func *post);
00124 
00126         void (*_hook_irg_block_walk)(void *context, ir_graph *irg, ir_node *node, generic_func *pre, generic_func *post);
00127 
00129         void (*_hook_merge_nodes)(void *context, ir_node **new_node_array, int new_num_entries,
00130                                   ir_node **old_node_array, int old_num_entries, hook_opt_kind opt);
00131 
00133         void (*_hook_reassociate)(void *context, int start);
00134 
00136         void (*_hook_lower)(void *context, ir_node *node);
00137 
00139         void (*_hook_inline)(void *context, ir_node *call, ir_graph *irg);
00140 
00142         void (*_hook_tail_rec)(void *context, ir_graph *irg, int n_calls);
00143 
00145         void (*_hook_strength_red)(void *context, ir_graph *irg, ir_node *node);
00146 
00148         void (*_hook_dead_node_elim)(void *context, ir_graph *irg, int start);
00149 
00151         void (*_hook_dead_node_elim_subst)(void *context, ir_graph *irg, ir_node *old, ir_node *nw);
00152 
00154         void (*_hook_if_conversion)(void *context, ir_graph *irg, ir_node *phi, int pos, ir_node *mux, if_result_t reason);
00155 
00157         void (*_hook_func_call)(void *context, ir_graph *irg, ir_node *call);
00158 
00160         void (*_hook_arch_dep_replace_mul_with_shifts)(void *context, ir_node *irn);
00161 
00163         void (*_hook_arch_dep_replace_division_by_const)(void *context, ir_node *irn);
00164 
00166         void (*_hook_new_mode)(void *context, ir_mode *mode);
00167 
00169         void (*_hook_new_entity)(void *context, ir_entity *ent);
00170 
00172         void (*_hook_new_type)(void *context, ir_type *tp);
00173 
00175         void (*_hook_node_info)(void *context, FILE *f, const ir_node *n);
00176     } hook; 
00179     void *context;
00180 
00182     struct hook_entry *next;
00183 } hook_entry_t;
00184 
00188 typedef enum {
00189     hook_new_ir_op,            
00190     hook_free_ir_op,           
00191     hook_new_node,             
00192     hook_set_irn_n,            
00193     hook_replace,              
00194     hook_turn_into_id,         
00195     hook_normalize,            
00196     hook_new_graph,            
00197     hook_free_graph,           
00198     hook_irg_walk,             
00199     hook_irg_walk_blkwise,     
00200     hook_irg_block_walk,       
00201     hook_merge_nodes,          
00202     hook_reassociate,          
00203     hook_lower,                
00204     hook_inline,               
00205     hook_tail_rec,             
00206     hook_strength_red,         
00207     hook_dead_node_elim,       
00208     hook_dead_node_elim_subst, 
00209     hook_if_conversion,        
00210     hook_func_call,            
00212     hook_arch_dep_replace_mul_with_shifts,
00214     hook_arch_dep_replace_division_by_const,
00215     hook_new_mode,             
00216     hook_new_entity,           
00217     hook_new_type,             
00218     hook_node_info,            
00219     hook_last                  
00220 } hook_type_t;
00221 
00228 FIRM_API void register_hook(hook_type_t hook, hook_entry_t *entry);
00229 
00236 FIRM_API void unregister_hook(hook_type_t hook, hook_entry_t *entry);
00237 
00239 FIRM_API hook_entry_t *hooks[hook_last];
00240 
00245 #define hook_exec(what, args) do {           \
00246   hook_entry_t *_p;                          \
00247   for (_p = hooks[what]; _p; _p = _p->next){ \
00248     void *hook_ctx_ = _p->context;           \
00249     _p->hook._##what args;                   \
00250   }                                          \
00251 } while (0)
00252 
00254 #define hook_new_ir_op(op)                hook_exec(hook_new_ir_op, (hook_ctx_, op))
00255 
00256 #define hook_free_ir_op(op)               hook_exec(hook_free_ir_op, (hook_ctx_, op))
00257 
00258 #define hook_new_node(graph, node)        hook_exec(hook_new_node, (hook_ctx_, graph, node))
00259 
00260 #define hook_set_irn_n(src, pos, tgt, old_tgt) \
00261   hook_exec(hook_set_irn_n, (hook_ctx_, src, pos, tgt, old_tgt))
00262 
00263 #define hook_replace(old, nw)             hook_exec(hook_replace, (hook_ctx_, old, nw))
00264 
00265 #define hook_turn_into_id(node)           hook_exec(hook_turn_into_id, (hook_ctx_, node))
00266 
00267 #define hook_normalize(node)              hook_exec(hook_normalize, (hook_ctx_, node))
00268 
00269 #define hook_new_graph(irg, ent)          hook_exec(hook_new_graph, (hook_ctx_, irg, ent))
00270 
00271 #define hook_free_graph(irg)              hook_exec(hook_free_graph, (hook_ctx_, irg))
00272 
00273 #define hook_irg_walk(irg, pre, post)     hook_exec(hook_irg_walk, (hook_ctx_, irg, pre, post))
00274 
00275 #define hook_irg_walk_blkwise(irg, pre, post) \
00276   hook_exec(hook_irg_walk_blkwise, (hook_ctx_, irg, pre, post))
00277 
00278 #define hook_irg_block_walk(irg, node, pre, post) \
00279   hook_exec(hook_irg_block_walk, (hook_ctx_, irg, node, pre, post))
00280 
00281 #define hook_merge_nodes(new_node_array, new_num_entries, old_node_array, old_num_entries, opt) \
00282   hook_exec(hook_merge_nodes, (hook_ctx_, new_node_array, new_num_entries, old_node_array, old_num_entries, opt))
00283 
00284 #define hook_reassociate(start)           hook_exec(hook_reassociate, (hook_ctx_, start))
00285 
00286 #define hook_lower(node)                  hook_exec(hook_lower, (hook_ctx_, node))
00287 
00288 #define hook_inline(call, irg)            hook_exec(hook_inline, (hook_ctx_, call, irg))
00289 
00290 #define hook_tail_rec(irg, n_calls)       hook_exec(hook_tail_rec, (hook_ctx_, irg, n_calls))
00291 
00292 #define hook_strength_red(irg, node) \
00293   hook_exec(hook_strength_red, (hook_ctx_, irg, node))
00294 
00295 #define hook_dead_node_elim(irg, start)   hook_exec(hook_dead_node_elim, (hook_ctx_, irg, start))
00296 
00297 #define hook_dead_node_elim_subst(irg, old, nw) \
00298    hook_exec(hook_dead_node_elim_subst, (hook_ctx_, irg, old, nw))
00299 
00300 #define hook_if_conversion(irg, phi, pos, mux, reason) \
00301   hook_exec(hook_if_conversion, (hook_ctx_, irg, phi, pos, mux, reason))
00302 
00303 #define hook_func_call(irg, call) \
00304   hook_exec(hook_func_call, (hook_ctx_, irg, call))
00305 
00306 #define hook_arch_dep_replace_mul_with_shifts(irn) \
00307   hook_exec(hook_arch_dep_replace_mul_with_shifts, (hook_ctx_, irn))
00308 
00309 #define hook_arch_dep_replace_division_by_const(irn) \
00310   hook_exec(hook_arch_dep_replace_division_by_const, (hook_ctx_, irn))
00311 
00312 #define hook_new_mode(mode)               hook_exec(hook_new_mode, (hook_ctx_, mode))
00313 
00314 #define hook_new_entity(ent)              hook_exec(hook_new_entity, (hook_ctx_, ent))
00315 
00316 #define hook_new_type(tp)                 hook_exec(hook_new_type, (hook_ctx_, tp))
00317 
00318 #define hook_node_info(F, node)           hook_exec(hook_node_info, (hook_ctx_, F, node))
00319 
00320 #include "end.h"
00321 
00322 #endif