stage3/flow_control_analysis.cc
changeset 459 01f6664bf8c5
parent 457 67d8b07bac22
child 463 fafa9abc166e
equal deleted inserted replaced
458:587884880be6 459:01f6664bf8c5
   111 
   111 
   112 /* set to 1 to see debug info during execution */
   112 /* set to 1 to see debug info during execution */
   113 static int debug = 0;
   113 static int debug = 0;
   114 
   114 
   115 flow_control_analysis_c::flow_control_analysis_c(symbol_c *ignore) {
   115 flow_control_analysis_c::flow_control_analysis_c(symbol_c *ignore) {
       
   116   prev_il_instruction = NULL;
       
   117   curr_il_instruction = NULL;
   116 }
   118 }
   117 
   119 
   118 flow_control_analysis_c::~flow_control_analysis_c(void) {
   120 flow_control_analysis_c::~flow_control_analysis_c(void) {
   119 }
   121 }
   120 
   122 
   125 /************************************/
   127 /************************************/
   126 /*********************/
   128 /*********************/
   127 /* B 1.5.1 Functions */
   129 /* B 1.5.1 Functions */
   128 /*********************/
   130 /*********************/
   129 void *flow_control_analysis_c::visit(function_declaration_c *symbol) {
   131 void *flow_control_analysis_c::visit(function_declaration_c *symbol) {
   130 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
   132 	search_il_label = new search_il_label_c(symbol);
   131 	if (debug) printf("Doing flow control analysis in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
   133 	if (debug) printf("Doing flow control analysis in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
   132 	symbol->function_body->accept(*this);
   134 	symbol->function_body->accept(*this);
   133 	delete search_varfb_instance_type;
   135 	delete search_il_label;
   134 	search_varfb_instance_type = NULL;
   136 	search_il_label = NULL;
   135 	return NULL;
   137 	return NULL;
   136 }
   138 }
   137 
   139 
   138 /***************************/
   140 /***************************/
   139 /* B 1.5.2 Function blocks */
   141 /* B 1.5.2 Function blocks */
   140 /***************************/
   142 /***************************/
   141 void *flow_control_analysis_c::visit(function_block_declaration_c *symbol) {
   143 void *flow_control_analysis_c::visit(function_block_declaration_c *symbol) {
   142 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
   144 	search_il_label = new search_il_label_c(symbol);
   143 	if (debug) printf("Doing flow control analysis in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
   145 	if (debug) printf("Doing flow control analysis in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
   144 	symbol->fblock_body->accept(*this);
   146 	symbol->fblock_body->accept(*this);
   145 	delete search_varfb_instance_type;
   147 	delete search_il_label;
   146 	search_varfb_instance_type = NULL;
   148 	search_il_label = NULL;
   147 	return NULL;
   149 	return NULL;
   148 }
   150 }
   149 
   151 
   150 /********************/
   152 /********************/
   151 /* B 1.5.3 Programs */
   153 /* B 1.5.3 Programs */
   152 /********************/
   154 /********************/
   153 void *flow_control_analysis_c::visit(program_declaration_c *symbol) {
   155 void *flow_control_analysis_c::visit(program_declaration_c *symbol) {
   154 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
   156 	search_il_label = new search_il_label_c(symbol);
   155 	if (debug) printf("Doing flow control analysis in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
   157 	if (debug) printf("Doing flow control analysis in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
   156 	symbol->function_block_body->accept(*this);
   158 	symbol->function_block_body->accept(*this);
   157 	delete search_varfb_instance_type;
   159 	delete search_il_label;
   158 	search_varfb_instance_type = NULL;
   160 	search_il_label = NULL;
   159 	return NULL;
   161 	return NULL;
   160 }
   162 }
   161 
   163 
   162 
   164 
   163 /********************************/
   165 /********************************/
   179 // SYM_LIST(instruction_list_c)
   181 // SYM_LIST(instruction_list_c)
   180 void *flow_control_analysis_c::visit(instruction_list_c *symbol) {
   182 void *flow_control_analysis_c::visit(instruction_list_c *symbol) {
   181 	for(int i = 0; i < symbol->n; i++) {
   183 	for(int i = 0; i < symbol->n; i++) {
   182 		prev_il_instruction = NULL;
   184 		prev_il_instruction = NULL;
   183 		if (i > 0) prev_il_instruction = symbol->elements[i-1];
   185 		if (i > 0) prev_il_instruction = symbol->elements[i-1];
   184 		symbol->elements[i]->accept(*this);
   186 		curr_il_instruction = symbol->elements[i];
       
   187 		curr_il_instruction->accept(*this);
       
   188 		curr_il_instruction = NULL;
   185 	}
   189 	}
   186 	return NULL;
   190 	return NULL;
   187 }
   191 }
   188 
   192 
   189 /* | label ':' [il_incomplete_instruction] eol_list */
   193 /* | label ':' [il_incomplete_instruction] eol_list */
   190 // SYM_REF2(il_instruction_c, label, il_instruction)
   194 // SYM_REF2(il_instruction_c, label, il_instruction)
   191 // void *visit(instruction_list_c *symbol);
   195 // void *visit(instruction_list_c *symbol);
   192 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
   196 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
   193 	symbol->prev_il_instruction.push_back(prev_il_instruction);
   197 	if (NULL != prev_il_instruction)
   194 	/* TODO: handle labels correctly!
   198 		symbol->prev_il_instruction.push_back(prev_il_instruction);
   195 	 *
   199 
   196 	 *      Don't forget to handle multiple consecutive lables too!
   200 	/* check if it is an il_expression_c, or a JMP[C[N]] and if so, handle it correctly */
   197 	 *        label2:
       
   198 	 *        label3:
       
   199 	 *        label4:
       
   200 	 *                LD I
       
   201 	 */
       
   202 	/* NOTE: the following recursive call will mess up the value in the
       
   203 	 *       this->prev_il_instruction variable, so be sure not to use it
       
   204 	 *       after the return of symbol->il_instruction->accept(*this);
       
   205 	 */
       
   206 	/* check if it is an il_expression_c, and if so, handle it correctly */
       
   207 	if (NULL != symbol->il_instruction)
   201 	if (NULL != symbol->il_instruction)
   208 		symbol->il_instruction->accept(*this);
   202 		symbol->il_instruction->accept(*this);
   209 	return NULL;
   203 	return NULL;
   210 }
   204 }
   211 
   205 
   212 
   206 
   213 #if 0
   207 
       
   208 /* | il_simple_operator [il_operand] */
       
   209 // SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
       
   210 // void *flow_control_analysis_c::visit(il_simple_operation_c *symbol)
       
   211 
       
   212 
       
   213 
   214 /* | function_name [il_operand_list] */
   214 /* | function_name [il_operand_list] */
   215 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   215 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   216 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   216 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   217 void *flow_control_analysis_c::visit(il_function_call_c *symbol) {
   217 // void *flow_control_analysis_c::visit(il_function_call_c *symbol) 
   218 	return NULL;
   218 
   219 }
       
   220 #endif
       
   221 
   219 
   222 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   220 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   223 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   221 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   224 void *flow_control_analysis_c::visit(il_expression_c *symbol) {
   222 void *flow_control_analysis_c::visit(il_expression_c *symbol) {
   225 	if(NULL == symbol->simple_instr_list) 
   223 	if(NULL == symbol->simple_instr_list) 
   226 		/* nothing to do... */
   224 		/* nothing to do... */
   227 		return NULL;
   225 		return NULL;
   228   
   226   
       
   227 	symbol_c *save_prev_il_instruction = prev_il_instruction;
   229 	prev_il_instruction = symbol->il_operand;
   228 	prev_il_instruction = symbol->il_operand;
   230 	symbol->simple_instr_list->accept(*this);
   229 	symbol->simple_instr_list->accept(*this);
   231 	return NULL;
   230 	prev_il_instruction = save_prev_il_instruction;
   232 }
   231 	return NULL;
   233 
   232 }
   234 
   233 
   235 #if 0
   234 
       
   235 /*  il_jump_operator label */
       
   236 // SYM_REF2(il_jump_operation_c, il_jump_operator, label)
       
   237 void *flow_control_analysis_c::visit(il_jump_operation_c *symbol) {
       
   238   /* search for the il_instruction_c containing the label */
       
   239   il_instruction_c *destination = search_il_label->find_label(symbol->label);
       
   240 
       
   241   /* TODO: for JMP and RET (unconditional) instructions, make sure the next IL instruction does not point back! */
       
   242   /* add, to that il_instruction's list of prev_il_intsructions, the curr_il_instruction */
       
   243   if (NULL != destination)
       
   244     destination->prev_il_instruction.push_back(curr_il_instruction);
       
   245   return NULL;
       
   246 }
       
   247 
       
   248 
   236 /*   il_call_operator prev_declared_fb_name
   249 /*   il_call_operator prev_declared_fb_name
   237  * | il_call_operator prev_declared_fb_name '(' ')'
   250  * | il_call_operator prev_declared_fb_name '(' ')'
   238  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
   251  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
   239  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
   252  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
   240  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   253  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   241  */
   254  */
   242 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
   255 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
   243 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   256 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   244 void *flow_control_analysis_c::visit(il_fb_call_c *symbol) {
   257 // void *flow_control_analysis_c::visit(il_fb_call_c *symbol)
   245 	return NULL;
       
   246 }
       
   247 
   258 
   248 
   259 
   249 /* | function_name '(' eol_list [il_param_list] ')' */
   260 /* | function_name '(' eol_list [il_param_list] ')' */
   250 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
   261 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
   251 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
   262 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
   252 void *flow_control_analysis_c::visit(il_formal_funct_call_c *symbol) {
   263 // void *flow_control_analysis_c::visit(il_formal_funct_call_c *symbol)
   253 	return NULL;
   264 
   254 }
       
   255 #endif
       
   256 
   265 
   257 
   266 
   258 //  void *visit(il_operand_list_c *symbol);
   267 //  void *visit(il_operand_list_c *symbol);
   259 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
   268 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
   260 	for(int i = 0; i < symbol->n; i++) {
   269 	for(int i = 0; i < symbol->n; i++) {
   266 }
   275 }
   267 
   276 
   268 
   277 
   269 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   278 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   270 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
   279 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
   271 	symbol->prev_il_instruction.push_back(prev_il_instruction);
   280 	if (NULL != prev_il_instruction)
       
   281 		symbol->prev_il_instruction.push_back(prev_il_instruction);
   272 	return NULL;
   282 	return NULL;
   273 }
   283 }
   274 
   284 
   275 
   285 
   276 /*
   286 /*
   279     void *visit(il_param_out_assignment_c *symbol);
   289     void *visit(il_param_out_assignment_c *symbol);
   280  */
   290  */
   281 
   291 
   282 
   292 
   283 
   293 
       
   294 
       
   295 /*******************/
       
   296 /* B 2.2 Operators */
       
   297 /*******************/
       
   298 // void *visit(   LD_operator_c *symbol);
       
   299 // void *visit(  LDN_operator_c *symbol);
       
   300 // void *visit(   ST_operator_c *symbol);
       
   301 // void *visit(  STN_operator_c *symbol);
       
   302 // void *visit(  NOT_operator_c *symbol);
       
   303 // void *visit(    S_operator_c *symbol);
       
   304 // void *visit(    R_operator_c *symbol);
       
   305 // void *visit(   S1_operator_c *symbol);
       
   306 // void *visit(   R1_operator_c *symbol);
       
   307 // void *visit(  CLK_operator_c *symbol);
       
   308 // void *visit(   CU_operator_c *symbol);
       
   309 // void *visit(   CD_operator_c *symbol);
       
   310 // void *visit(   PV_operator_c *symbol);
       
   311 // void *visit(   IN_operator_c *symbol);
       
   312 // void *visit(   PT_operator_c *symbol);
       
   313 // void *visit(  AND_operator_c *symbol);
       
   314 // void *visit(   OR_operator_c *symbol);
       
   315 // void *visit(  XOR_operator_c *symbol);
       
   316 // void *visit( ANDN_operator_c *symbol);
       
   317 // void *visit(  ORN_operator_c *symbol);
       
   318 // void *visit( XORN_operator_c *symbol);
       
   319 // void *visit(  ADD_operator_c *symbol);
       
   320 // void *visit(  SUB_operator_c *symbol);
       
   321 // void *visit(  MUL_operator_c *symbol);
       
   322 // void *visit(  DIV_operator_c *symbol);
       
   323 // void *visit(  MOD_operator_c *symbol);
       
   324 // void *visit(   GT_operator_c *symbol);
       
   325 // void *visit(   GE_operator_c *symbol);
       
   326 // void *visit(   EQ_operator_c *symbol);
       
   327 // void *visit(   LT_operator_c *symbol);
       
   328 // void *visit(   LE_operator_c *symbol);
       
   329 // void *visit(   NE_operator_c *symbol);
       
   330 // void *visit(  CAL_operator_c *symbol);
       
   331 // void *visit( CALC_operator_c *symbol);
       
   332 // void *visit(CALCN_operator_c *symbol);
       
   333 // void *visit(  RET_operator_c *symbol);
       
   334 // void *visit( RETC_operator_c *symbol);
       
   335 // void *visit(RETCN_operator_c *symbol);
       
   336 // void *visit(  JMP_operator_c *symbol);
       
   337 // void *visit( JMPC_operator_c *symbol);
       
   338 // void *visit(JMPCN_operator_c *symbol);
       
   339 
       
   340 /* Symbol class handled together with function call checks */
       
   341 // void *visit(il_assign_operator_c *symbol, variable_name);
       
   342 /* Symbol class handled together with function call checks */
       
   343 // void *visit(il_assign_operator_c *symbol, option, variable_name);
       
   344