C:/Users/Dennis/src/lang/russell.orig/src/pass5d/is_int_const.c

Go to the documentation of this file.
00001 /* Determine whether an expressions is obviously a mchine integer */
00002 /* constant.  Used to implement a very simple version of constant */
00003 /* propagation.                                                   */
00004 # define DEBUG DEBUG
00005 # include "parm.h"
00006 # include <stdio.h>
00007 # include "stree/ststructs.mh"
00008 # include "codegen.h"
00009 # include "pass4/sigs.h"
00010 # include "pass3/is_local.h"
00011 
00012 extern int yydebug;
00013 extern int yynerrs;
00014 
00015 extern FILE * unparse_file;
00016 
00017 extern char str_code_buf[];
00018 
00019 long int_const_val;
00020 
00021 extern NODE * id_Integer;   /* The built-in integer type */
00022 
00023 extern NODE * id_plus;
00024 
00025 extern NODE * id_times;
00026 
00027 char * Int_string_code;
00028 char * Int_add_code;
00029 char * Int_mul_code;
00030 
00031 static int is_initialized = 0;
00032 
00033 boolean is_int_const1();
00034 
00035 /* Initialize the above */
00036 void is_const_init()
00037 {
00038     NODE * ld = id_Integer -> id_last_definition;
00039     NODE * tsig;
00040     NODE * plus_sig;
00041     NODE * times_sig;
00042 
00043     is_initialized = 1;
00044     if (ld -> kind == DECLARATION) {
00045         tsig = ld -> decl_signature;
00046     } else if (ld -> kind == PARAMETER) {
00047         tsig = ld -> par_signature;
00048     } else {
00049         dbgmsg("is_const_init: bad built-in integer type\n");
00050     }
00051     Int_string_code = tsig -> ts_string_code;
00052     if (Int_string_code == NIL) {
00053         fprintf(stderr, "Warning: no integer string code\n");
00054         Int_string_code = "X";  /* pointer distinguishable from */
00055                                 /* everything else.             */
00056     }
00057     plus_sig = getcomp(tsig, id_plus, NIL, NIL, NIL, NIL, FALSE);
00058     times_sig = getcomp(tsig, id_times, NIL, NIL, NIL, NIL, FALSE);
00059     Int_add_code = plus_sig -> fsig_inline_code;
00060     Int_mul_code = times_sig -> fsig_inline_code;
00061     if (Int_add_code == NIL) {
00062         fprintf(stderr, "Warning: no integer addition code\n");
00063         Int_add_code = "X";  /* pointer distinguishable from */
00064                              /* everything else.             */
00065     }
00066     if (Int_mul_code == NIL) {
00067         fprintf(stderr, "Warning: no integer multiplication code\n");
00068         Int_mul_code = "X";  /* pointer distinguishable from */
00069                              /* everything else.             */
00070     }
00071 }
00072 
00073 /* Determine whether the expression p is known to be an integer constant */
00074 /* If so, set int_const_val to the value.                                */
00075 /* Returns FALSE if p can involve a side effect.                         */
00076 /* Unlike int_value, we make no assumptions about expression signatures  */
00077 boolean is_int_const(p)
00078 NODE *p;
00079 {
00080     if (!is_initialized) {
00081         is_const_init();
00082     }
00083     if (!has_sig(p)) { return(FALSE); }
00084     if (p -> signature -> kind == VALSIGNATURE) {
00085         return(is_int_const1(p));
00086     } else {
00087         return(FALSE);
00088     }
00089 }
00090 
00091 boolean is_int_const1(p)
00092 NODE *p;
00093 {
00094     NODE * decl;
00095     boolean result;
00096 
00097     switch(p -> kind) {
00098         case LETTERID:
00099         case OPRID:
00100             decl = p -> id_last_definition;
00101             
00102             if (decl == NIL /* selection */
00103                 || decl -> kind != DECLARATION
00104                 || (decl -> decl_special & NOT_DECL_CONST)) {
00105                 return(FALSE);
00106             }
00107             if (decl -> decl_special & DECL_CONST) {
00108                 int_const_val = decl -> decl_const_val;
00109                 return(TRUE);
00110             }
00111             if (decl -> post_num >= p -> post_num) {
00112                 /* Dont follow recursive declarations. */
00113                 return(FALSE);
00114             }
00115             result = is_int_const1(p -> id_last_definition -> decl_denotation);
00116             /* Remember for next time */
00117                 if (result) {
00118                     decl -> decl_special |= DECL_CONST;
00119                     decl -> decl_const_val = int_const_val;
00120                 } else {
00121                     decl -> decl_special |= NOT_DECL_CONST;
00122                 }
00123             return(result);
00124         case UQSTR:
00125             if (p -> sel_type -> signature -> ts_string_code
00126                 == Int_string_code) {
00127                 int_const_val = atoi(p -> str_string);
00128                 return(TRUE);
00129             } else {
00130                 return(FALSE);
00131             }
00132         case APPLICATION:
00133             {
00134                 NODE * op_sig = p -> ap_operator -> signature;
00135                 NODE * args = p -> ap_args;
00136                 long l_arg, r_arg;
00137 
00138                 switch(special_tp(op_sig -> fsig_special)) {
00139                     case IDENTITY:
00140                         return(is_int_const1(first(args)));
00141                     case ENUM_ELEMENT:
00142                     case ENUM_CARD:
00143                         int_const_val = special_val(op_sig -> fsig_special);
00144                         return(TRUE);
00145                 }
00146                 if (op_sig -> fsig_inline_code == Int_add_code) {
00147                     if (!is_int_const1(first(args))) { return(FALSE); }
00148                     l_arg = int_const_val;
00149                     if (!is_int_const1(second(args))) { return(FALSE); }
00150                     r_arg = int_const_val;
00151                     int_const_val = l_arg + r_arg;
00152                     return(TRUE);
00153                 } else if (op_sig -> fsig_inline_code == Int_mul_code) {
00154                     if (!is_int_const1(first(args))) { return(FALSE); }
00155                     l_arg = int_const_val;
00156                     if (!is_int_const1(second(args))) { return(FALSE); }
00157                     r_arg = int_const_val;
00158                     int_const_val = l_arg * r_arg;
00159                     return(TRUE);
00160                 } else {
00161                     return(FALSE);
00162                 }
00163             }
00164         default:
00165             return(FALSE);
00166     }
00167 }

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4