History

optimize the generated code when save_reg is required

Before this patch, save_reg can't reuse the temporary local variable created before to save register. It may consume a lot of stack memory. this patch make save_reg reuse the temporary local variable.

Pursuer committed 7 years ago

Commit b3b685d1 parent 0c313f41 file · +63 −3Browse files

Unified · Split

tccgen.c+63−3
@@ -70,6 +70,14 @@ ST_DATA struct switch_t { · 69 unmodified lines
70 int def_sym; /* default symbol */70 int def_sym; /* default symbol */
71} *cur_switch; /* current switch */71} *cur_switch; /* current switch */
72 72
73#define MAX_TEMP_LOCAL_VARIABLE_NUMBER 0x4
74/*list of temporary local variables on the stack in current function. */
75ST_DATA struct temp_local_variable {
76 int location; //offset on stack. Svalue.c.i
77 short size;
78 short align;
79} arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
80short nb_temp_local_vars;
73/* ------------------------------------------------------------------------- */81/* ------------------------------------------------------------------------- */
74 82
75static void gen_cast(CType *type);83static void gen_cast(CType *type);
@@ -97,6 +105,8 @@ static int gvtst(int inv, int t); · 21 unmodified lines
97static void gen_inline_functions(TCCState *s);105static void gen_inline_functions(TCCState *s);
98static void skip_or_save_block(TokenString **str);106static void skip_or_save_block(TokenString **str);
99static void gv_dup(void);107static void gv_dup(void);
108static int get_temp_local_var(int size,int align);
109static void clear_temp_local_var_list();
100 110
101ST_INLN int is_float(int t)111ST_INLN int is_float(int t)
102{112{
@@ -1033,10 +1043,10 @@ ST_FUNC void save_reg_upstack(int r, int n) · 930 unmodified lines
1033 type = &int_type;1043 type = &int_type;
1034#endif1044#endif
1035 size = type_size(type, &align);1045 size = type_size(type, &align);
1036 loc = (loc - size) & -align;1046 l=get_temp_local_var(size,align);
1037 sv.type.t = type->t;1047 sv.type.t = type->t;
1038 sv.r = VT_LOCAL | VT_LVAL;1048 sv.r = VT_LOCAL | VT_LVAL;
1039 sv.c.i = loc;1049 sv.c.i = l;
1040 store(r, &sv);1050 store(r, &sv);
1041#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)1051#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1042 /* x86 specific: need to pop fp register ST0 if saved */1052 /* x86 specific: need to pop fp register ST0 if saved */
@@ -1051,7 +1061,6 @@ ST_FUNC void save_reg_upstack(int r, int n) · 8 unmodified lines
1051 store(p->r2, &sv);1061 store(p->r2, &sv);
1052 }1062 }
1053#endif1063#endif
1054 l = loc;
1055 saved = 1;1064 saved = 1;
1056 }1065 }
1057 /* mark that stack entry as being saved on the stack */1066 /* mark that stack entry as being saved on the stack */
@@ -1134,6 +1143,56 @@ ST_FUNC int get_reg(int rc) · 76 unmodified lines
1134 return -1;1143 return -1;
1135}1144}
1136 1145
1146/* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1147static int get_temp_local_var(int size,int align){
1148 int i;
1149 struct temp_local_variable *temp_var;
1150 int found_var;
1151 SValue *p;
1152 int r;
1153 char free;
1154 char found;
1155 found=0;
1156 for(i=0;i<nb_temp_local_vars;i++){
1157 temp_var=&arr_temp_local_vars[i];
1158 if(temp_var->size<size||align!=temp_var->align){
1159 continue;
1160 }
1161 /*check if temp_var is free*/
1162 free=1;
1163 for(p=vstack;p<=vtop;p++) {
1164 r=p->r&VT_VALMASK;
1165 if(r==VT_LOCAL||r==VT_LLOCAL){
1166 if(p->c.i==temp_var->location){
1167 free=0;
1168 break;
1169 }
1170 }
1171 }
1172 if(free){
1173 found_var=temp_var->location;
1174 found=1;
1175 break;
1176 }
1177 }
1178 if(!found){
1179 loc = (loc - size) & -align;
1180 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
1181 temp_var=&arr_temp_local_vars[i];
1182 temp_var->location=loc;
1183 temp_var->size=size;
1184 temp_var->align=align;
1185 nb_temp_local_vars++;
1186 }
1187 found_var=loc;
1188 }
1189 return found_var;
1190}
1191
1192static void clear_temp_local_var_list(){
1193 nb_temp_local_vars=0;
1194}
1195
1137/* move register 's' (of type 't') to 'r', and flush previous value of r to memory1196/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1138 if needed */1197 if needed */
1139static void move_reg(int r, int s, int t)1198static void move_reg(int r, int s, int t)
@@ -7169,6 +7228,7 @@ static void gen_function(Sym *sym) · 6029 unmodified lines
7169 gfunc_prolog(&sym->type);7228 gfunc_prolog(&sym->type);
7170 local_scope = 0;7229 local_scope = 0;
7171 rsym = 0;7230 rsym = 0;
7231 clear_temp_local_var_list();
7172 block(NULL, NULL, 0);7232 block(NULL, NULL, 0);
7173 if (!(nocode_wanted & 0x20000000)7233 if (!(nocode_wanted & 0x20000000)
7174 && ((func_vt.t & VT_BTYPE) == VT_INT)7234 && ((func_vt.t & VT_BTYPE) == VT_INT)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t