added optimization module
[libfirm] / ir / be / ia32 / ia32_optimize.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "irnode.h"
6 #include "irprog_t.h"
7 #include "ircons.h"
8 #include "firm_types.h"
9
10 #include "ia32_new_nodes.h"
11 #include "bearch_ia32_t.h"
12
13 /**
14  * creates a unique ident by adding a number to a tag
15  *
16  * @param tag   the tag string, must contain a %d if a number
17  *              should be added
18  */
19 static ident *unique_id(const char *tag)
20 {
21   static unsigned id = 0;
22   char str[256];
23
24   snprintf(str, sizeof(str), tag, ++id);
25   return new_id_from_str(str);
26 }
27
28
29
30 /**
31  * Transforms a SymConst.
32  *
33  * @param mod     the debug module
34  * @param block   the block the new node should belong to
35  * @param node    the ir SymConst node
36  * @param mode    mode of the SymConst
37  * @return the created ia32 Const node
38  */
39 static ir_node *gen_SymConst(ia32_transform_env_t *env) {
40         ir_node  *cnst;
41         dbg_info *dbg   = env->dbg;
42         ir_mode  *mode  = env->mode;
43         ir_graph *irg   = env->irg;
44         ir_node  *block = env->block;
45
46         if (mode_is_float(mode)) {
47                 cnst = new_rd_ia32_fConst(dbg, irg, block, mode);
48
49         }
50         else {
51                 cnst = new_rd_ia32_Const(dbg, irg, block, mode);
52         }
53
54         set_ia32_Const_attr(cnst, env->irn);
55         return cnst;
56 }
57
58 /**
59  * Transforms a Const.
60  *
61  * @param mod     the debug module
62  * @param block   the block the new node should belong to
63  * @param node    the ir Const node
64  * @param mode    mode of the Const
65  * @return the created ia32 Const node
66  */
67 static ir_node *gen_Const(ia32_transform_env_t *env) {
68         ir_node *cnst;
69         entity  *ent;
70         ir_type *tp;
71         symconst_symbol sym;
72         dbg_info *dbg   = env->dbg;
73         ir_mode  *mode  = env->mode;
74         ir_graph *irg   = env->irg;
75         ir_node  *block = env->block;
76         ir_node  *node  = env->irn;
77
78         if (mode_is_float(mode)) {
79                 tp  = get_Const_type(node);
80                 if (tp == firm_unknown_type) {
81                         tp = new_type_primitive(unique_id("tp_ia32_float_%u"), mode);
82                 }
83
84                 ent = new_entity(get_glob_type(), unique_id("ia32FloatCnst_%u"), tp);
85
86                 set_entity_ld_ident(ent, get_entity_ident(ent));
87                 set_entity_visibility(ent, visibility_local);
88                 set_entity_variability(ent, variability_constant);
89                 set_entity_allocation(ent, allocation_static);
90
91                 set_atomic_ent_value(ent, node);
92
93                 sym.entity_p = ent;
94
95                 cnst = new_rd_SymConst(dbg, irg, block, sym, symconst_addr_ent);
96                 env->irn = cnst;
97                 cnst = gen_SymConst(env);
98         }
99         else {
100                 cnst = new_rd_ia32_Const(dbg, irg, block, mode);
101                 set_ia32_Const_attr(cnst, node);
102         }
103
104         return cnst;
105 }
106
107
108
109 /**
110  * Transforms (all) Const's into ia32_Const and places them in the
111  * block where they are used (or in the cfg-pred Block in case of Phi's)
112  */
113 void ia32_place_consts(ir_node *irn, void *env) {
114         ia32_code_gen_t      *cg = env;
115         ia32_transform_env_t  tenv;
116         ir_mode              *mode;
117         ir_node              *pred, *cnst;
118         int                   i;
119         opcode                opc;
120
121         if (is_Block(irn))
122                 return;
123
124         mode = get_irn_mode(irn);
125
126         tenv.arch_env = cg->arch_env;
127         tenv.block    = get_nodes_block(irn);
128         tenv.cg       = cg;
129         tenv.irg      = cg->irg;
130         tenv.mod      = firm_dbg_register("ir.be.ia32.optimize");
131
132         /* Loop over all predecessors and check for Sym/Const nodes */
133         for (i = 0; i < get_irn_arity(irn); i++) {
134                 pred      = get_irn_n(irn, i);
135                 cnst      = NULL;
136                 opc       = get_irn_opcode(pred);
137                 tenv.irn  = pred;
138                 tenv.mode = get_irn_mode(pred);
139                 tenv.dbg  = get_irn_dbg_info(pred);
140
141                 /* If it's a Phi, then we need to create the */
142                 /* new Const in it's predecessor block       */
143                 if (is_Phi(irn)) {
144                         tenv.block = get_Block_cfgpred_block(get_nodes_block(irn), i);
145                 }
146
147                 switch (opc) {
148                         case iro_Const:
149                                 cnst = gen_Const(&tenv);
150                                 break;
151                         case iro_SymConst:
152                                 cnst = gen_SymConst(&tenv);
153                                 break;
154                         default:
155                                 break;
156                 }
157
158                 /* if we found a const, then set it */
159                 if (cnst) {
160                         set_irn_n(irn, i, cnst);
161                 }
162         }
163 }