00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <string.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include "types.h"
00029 #include "ast_util.h"
00030 #include "ast_optimizations.h"
00031 #include "parse_making_ast.h"
00032 #include "verilog_bison.h"
00033 #include "verilog_bison_user_defined.h"
00034 #include "util.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 info_ast_visit_t *reduceAST_traverse_node(ast_node_t *node, ast_node_t *from, int position_idx);
00046
00047
00048
00049 void optimizations_on_AST(ast_node_t *top)
00050 {
00051
00052 cleanup_hard_blocks();
00053 reduceAST_traverse_node(top, NULL, -1);
00054 }
00055
00056
00057
00058
00059 info_ast_visit_t *reduceAST_traverse_node(ast_node_t *node, ast_node_t *from, int position_idx)
00060 {
00061 int i;
00062 info_ast_visit_t *node_details = NULL;
00063 info_ast_visit_t **children_info = NULL;
00064 short free_myself = FALSE;
00065
00066 if (node == NULL)
00067 {
00068
00069 return NULL;
00070 }
00071 else
00072 {
00073 switch(node->type)
00074 {
00075 default:
00076 break;
00077 }
00078
00079
00080 children_info = (info_ast_visit_t**)malloc(sizeof(info_ast_visit_t*)*node->num_children);
00081
00082
00083 for (i = 0; i < node->num_children; i++)
00084 {
00085
00086 children_info[i] = reduceAST_traverse_node(node->children[i], node, i);
00087 }
00088
00089
00090 switch(node->type)
00091 {
00092 default:
00093 break;
00094 }
00095
00096
00097 for (i = 0; i < node->num_children; i++)
00098 {
00099 if(children_info[i] != NULL)
00100 free(children_info[i]);
00101 }
00102 if (children_info != NULL)
00103 free(children_info);
00104
00105 if (free_myself == TRUE)
00106
00107 free_child_in_tree(from, position_idx);
00108 }
00109
00110 return node_details;
00111 }
00112
00113
00114
00115
00116 info_ast_visit_t *constantFold(ast_node_t *node)
00117 {
00118 int i;
00119 info_ast_visit_t *node_details = NULL;
00120 info_ast_visit_t **children_info = NULL;
00121 short free_myself = FALSE;
00122
00123 if (node == NULL)
00124 {
00125
00126 return NULL;
00127 }
00128 else
00129 {
00130 switch(node->type)
00131 {
00132 case NUMBERS:
00133
00134
00135
00136 node_details = (info_ast_visit_t*)calloc(1, sizeof(info_ast_visit_t));
00137 oassert(node_details);
00138
00139
00140 switch (node->types.number.base)
00141 {
00142 case(DEC):
00143 if (node_details->value != -1)
00144 {
00145 node_details->is_constant = TRUE;
00146 node_details->value = node->types.number.value;
00147 }
00148 break;
00149 case(HEX):
00150 if (node_details->value != -1)
00151 {
00152 node_details->is_constant = TRUE;
00153 node_details->value = node->types.number.value;
00154 }
00155 break;
00156 case(OCT):
00157 if (node_details->value != -1)
00158 {
00159 node_details->is_constant = TRUE;
00160 node_details->value = node->types.number.value;
00161 }
00162 break;
00163 case(BIN):
00164 if (node_details->value != -1)
00165 {
00166 node_details->is_constant = TRUE;
00167 node_details->value = node->types.number.value;
00168 }
00169 break;
00170 case(LONG_LONG):
00171 node_details->is_constant = TRUE;
00172 node_details->value = node->types.number.value;
00173 break;
00174 }
00175
00176 if (node_details->is_constant == TRUE)
00177 {
00178
00179 node_details->me = node;
00180 node_details->from = NULL;
00181 }
00182 else
00183 {
00184 free(node_details);
00185 node_details = NULL;
00186 }
00187 break;
00188 default:
00189 break;
00190 }
00191
00192
00193 children_info = (info_ast_visit_t**)malloc(sizeof(info_ast_visit_t*)*node->num_children);
00194
00195
00196 for (i = 0; i < node->num_children; i++)
00197 {
00198
00199 children_info[i] = constantFold(node->children[i]);
00200 }
00201
00202
00203 switch(node->type)
00204 {
00205 case UNARY_OPERATION:
00206 if ((children_info[0] != NULL)
00207 && (children_info[0]->is_constant == TRUE))
00208 {
00209
00210 long long new_value;
00211 short is_reduction = TRUE;
00212
00213 ast_node_t *new_node;
00214
00215
00216 switch (node->types.operation.op)
00217 {
00218 case LOGICAL_NOT:
00219 new_value = !children_info[0]->value;
00220 break;
00221 case BITWISE_NOT:
00222 new_value = ~children_info[0]->value;
00223 break;
00224 case MINUS:
00225 new_value = -children_info[0]->value;
00226 break;
00227 default:
00228 is_reduction = FALSE;
00229 }
00230
00231 if (is_reduction == TRUE)
00232 {
00233 node_details = (info_ast_visit_t*)calloc(1, sizeof(info_ast_visit_t));
00234
00235 node_details->is_constant_folded = TRUE;
00236 node_details->me = node;
00237
00238
00239 new_node = create_tree_node_long_long_number(new_value, node->line_number, node->file_number);
00240
00241
00242 free_myself = TRUE;
00243
00244
00245 node_details->from = new_node;
00246 }
00247 }
00248 break;
00249 case BINARY_OPERATION:
00250 if ((children_info[0] != NULL)
00251 && (children_info[1] != NULL)
00252 && (children_info[0]->is_constant == TRUE)
00253 && (children_info[1]->is_constant == TRUE))
00254 {
00255
00256 long long new_value;
00257 short is_reduction = TRUE;
00258
00259 ast_node_t *new_node;
00260
00261
00262 switch (node->types.operation.op)
00263 {
00264 case ADD:
00265 new_value = children_info[0]->value + children_info[1]->value;
00266 break;
00267 case MINUS:
00268 new_value = children_info[0]->value - children_info[1]->value;
00269 break;
00270 case MULTIPLY:
00271 new_value = children_info[0]->value * children_info[1]->value;
00272 break;
00273 case BITWISE_XOR:
00274 new_value = children_info[0]->value ^ children_info[1]->value;
00275 break;
00276 case BITWISE_XNOR:
00277 new_value = ~(children_info[0]->value ^ children_info[1]->value);
00278 break;
00279 case BITWISE_AND:
00280 new_value = children_info[0]->value & children_info[1]->value;
00281 break;
00282 case BITWISE_NAND:
00283 new_value = ~(children_info[0]->value & children_info[1]->value);
00284 break;
00285 case BITWISE_OR:
00286 new_value = children_info[0]->value | children_info[1]->value;
00287 break;
00288 case BITWISE_NOR:
00289 new_value = ~(children_info[0]->value | children_info[1]->value);
00290 break;
00291 case SL:
00292 new_value = children_info[0]->value << children_info[1]->value;
00293 break;
00294 case SR:
00295 new_value = children_info[0]->value >> children_info[1]->value;
00296 break;
00297 case LOGICAL_AND:
00298 new_value = children_info[0]->value && children_info[1]->value;
00299 break;
00300 case LOGICAL_OR:
00301 new_value = children_info[0]->value || children_info[1]->value;
00302 break;
00303 default:
00304 is_reduction = FALSE;
00305 }
00306
00307 if (is_reduction == TRUE)
00308 {
00309 node_details = (info_ast_visit_t*)calloc(1, sizeof(info_ast_visit_t));
00310
00311 node_details->is_constant_folded = TRUE;
00312 node_details->me = node;
00313
00314
00315 new_node = create_tree_node_long_long_number(new_value, node->line_number, node->file_number);
00316
00317
00318 free_myself = TRUE;
00319
00320
00321 node_details->from = new_node;
00322 }
00323 }
00324 break;
00325 default:
00326 break;
00327 }
00328
00329
00330 for (i = 0; i < node->num_children; i++)
00331 {
00332 if(children_info[i] != NULL)
00333 free(children_info[i]);
00334 }
00335 if (children_info != NULL)
00336 free(children_info);
00337
00338 if (free_myself == TRUE)
00339
00340 free_ast_node(node);
00341 }
00342
00343 return node_details;
00344 }