00001 # include "parm.h"
00002 # include <stdio.h>
00003 # include <string.h>
00004
00005 # include "stree/ststructs.mh"
00006
00007 extern char str_code_buf[];
00008
00009 extern boolean Tflag;
00010
00011 # define MAXINLINELEN 400
00012
00013
00014
00015 int number_of_c();
00016
00017
00018
00019
00020 void find_inline(fc)
00021 NODE * fc;
00022 {
00023 NODE * fsig = fc -> signature;
00024 NODE * body = fc -> fc_body;
00025 int code_len = 0;
00026 char * code;
00027 int n_percents = 0;
00028 NODE * p;
00029 int i;
00030
00031 # ifdef DEBUG
00032 if (fc -> kind != FUNCCONSTR) {
00033 dbgmsg("find_inline: bad function construction\n");
00034 }
00035 # endif
00036 # ifdef VERBOSE
00037 printf("find_inline: %s\n", fc -> fc_code_label);
00038 # endif
00039 if (fsig -> fsig_inline_code != NIL) return;
00040 if (body -> kind == EXTERNDEF) {
00041 sprintf(str_code_buf,
00042 "\tmovl\t$0x%%X,r11\n\tcalls\t$%d,%s\n\tpushl\tr0",
00043 length(fsig -> fsig_param_list),
00044 body -> ext_name);
00045 fsig -> fsig_inline_code = (char *) malloc(strlen(str_code_buf) + 1);
00046 strcpy(fsig -> fsig_inline_code, str_code_buf);
00047 # ifdef VERBOSE
00048 printf("Generated inline code for external function\n");
00049 # endif
00050 return;
00051 }
00052 if (Tflag) {
00053
00054 return;
00055 }
00056
00057 p = body;
00058 while (p -> kind == APPLICATION &&
00059 length(p -> ap_args) == 1 &&
00060 first(p -> ap_args) -> kind == APPLICATION) {
00061 if ((code = p -> ap_operator -> signature -> fsig_inline_code)
00062 == NIL) {
00063 return;
00064 }
00065 code_len += strlen(code);
00066 n_percents += number_of_c(code, '%');
00067 p = first(p -> ap_args);
00068 }
00069 if (p -> kind == APPLICATION &&
00070 length(p -> ap_args) == length(fsig -> fsig_param_list) &&
00071 (code = p -> ap_operator -> signature -> fsig_inline_code) != NIL &&
00072 code_len + strlen(code) <= MAXINLINELEN &&
00073 n_percents + number_of_c(code,'%') <= 2) {
00074 map2lists(r, p -> ap_args, s,
00075 fsig -> fsig_param_list, {
00076 if (r -> kind != LETTERID || !is_declared_by(r, s)) {
00077 return;
00078 }
00079 });
00080 } else {
00081 return;
00082 }
00083
00084
00085 str_code_buf[0] = '\0';
00086 for (p = body; p != NIL && p -> kind != LETTERID;
00087 p = is_empty(p -> ap_args)? NIL : first(p -> ap_args)) {
00088 int len;
00089 int old_len = strlen(str_code_buf);
00090
00091 code = p -> ap_operator -> signature -> fsig_inline_code;
00092 len = strlen(code) + 1;
00093
00094 str_code_buf[len + old_len] = '\0';
00095 for (i = old_len - 1; i >= 0; i--) {
00096 str_code_buf[i+len] = str_code_buf[i];
00097 }
00098
00099 strcpy(str_code_buf, code);
00100 str_code_buf[len-1] = '\n';
00101 }
00102 fsig -> fsig_inline_code = (char *) malloc(strlen(str_code_buf) + 1);
00103
00104 strcpy(fsig -> fsig_inline_code, str_code_buf);
00105 return;
00106 }
00107
00108
00109
00110 number_of_c(s,c)
00111 char *s;
00112 char c;
00113 {
00114 char *p = s;
00115 char *q;
00116 int result = 0;
00117
00118 while ((q = (char *)index(p, c)) != 0) {
00119 p = q + 1;
00120 result ++;
00121 }
00122 return(result);
00123 }