History

a lot simpler VLA code

seyko committed 11 years ago

Commit 999274c1 parent fca58734 files · +33 −94Browse files

Unified · Split

4 files
  1. i386-gen.c +0 −4
  2. tcc.h +0 −6
  3. tccgen.c +33 −80
  4. x86_64-gen.c +0 −4
i386-gen.c+0−4
@@ -1126,11 +1126,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 1125 unmodified lines
11261126 /* We align to 16 bytes rather than align */
11271127 /* and ~15, %esp */
11281128 o(0xf0e483);
1129− /* mov %esp, r */
1130− o(0x89);
1131− o(0xe0 | r);
11321129 vpop();
1133− vset(type, r, 0);
11341130 #endif
11351131 }
11361132
tcc.h+0−6
@@ -464,12 +464,6 @@ typedef struct DLLReference { · 463 unmodified lines
464464 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
465465 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
466466
467−#define VLA_SP_LOC_SET 0x01 /* Location of SP on stack has been allocated */
468−#define VLA_SP_SAVED 0x02 /* SP has been saved to slot already */
469−#define VLA_NEED_NEW_FRAME 0x04 /* Needs new frame for next VLA */
470−#define VLA_IN_SCOPE 0x08 /* One or more VLAs are in scope */
471−#define VLA_SCOPE_FLAGS (VLA_SP_SAVED|VLA_NEED_NEW_FRAME|VLA_IN_SCOPE) /* Flags which are saved and restored upon entering and exiting a block */
472−
473467 /* stored in 'Sym.c' field */
474468 #define FUNC_NEW 1 /* ansi function prototype */
475469 #define FUNC_OLD 2 /* old function prototype */
tccgen.c+33−80
@@ -55,10 +55,9 @@ ST_DATA Sym *define_stack; · 54 unmodified lines
5555 ST_DATA Sym *global_label_stack;
5656 ST_DATA Sym *local_label_stack;
5757
58−ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
58+ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
5959 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60−ST_DATA int *vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61−ST_DATA int vla_flags; /* VLA_* flags */
60+ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
6261
6362 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
6463
@@ -87,7 +86,8 @@ static int decl0(int l, int is_for_loop_init); · 22 unmodified lines
8786 static void expr_eq(void);
8887 static void unary_type(CType *type);
8988 static void vla_runtime_type_size(CType *type, int *a);
90−static void vla_sp_save(void);
89+static void vla_sp_restore(void);
90+static void vla_sp_restore_root(void);
9191 static int is_compatible_parameter_types(CType *type1, CType *type2);
9292 static void expr_type(CType *type);
9393 ST_FUNC void vpush64(int ty, unsigned long long v);
@@ -2223,14 +2223,15 @@ ST_FUNC void vla_runtime_type_size(CType *type, int *a) · 2129 unmodified lines
22232223 }
22242224 }
22252225
2226−static void vla_sp_save(void) {
2227− if (!(vla_flags & VLA_SP_LOC_SET)) {
2228− *vla_sp_loc = (loc -= PTR_SIZE);
2229− vla_flags |= VLA_SP_LOC_SET;
2226+static void vla_sp_restore(void) {
2227+ if (vlas_in_scope) {
2228+ gen_vla_sp_restore(vla_sp_loc);
22302229 }
2231− if (!(vla_flags & VLA_SP_SAVED)) {
2232− gen_vla_sp_save(*vla_sp_loc);
2233− vla_flags |= VLA_SP_SAVED;
2230+}
2231+
2232+static void vla_sp_restore_root(void) {
2233+ if (vlas_in_scope) {
2234+ gen_vla_sp_restore(vla_sp_root_loc);
22342235 }
22352236 }
22362237
@@ -4794,10 +4795,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 2557 unmodified lines
47944795 } else if (tok == TOK_WHILE) {
47954796 next();
47964797 d = ind;
4797− if (vla_flags & VLA_IN_SCOPE) {
4798− gen_vla_sp_restore(*vla_sp_loc);
4799− vla_flags |= VLA_NEED_NEW_FRAME;
4800− }
4798+ vla_sp_restore();
48014799 skip('(');
48024800 gexpr();
48034801 skip(')');
@@ -4809,7 +4807,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 5 unmodified lines
48094807 gsym_addr(b, d);
48104808 } else if (tok == '{') {
48114809 Sym *llabel;
4812− int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags, *orig_vla_sp_loc;
4810+ int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
48134811
48144812 next();
48154813 /* record local declaration stack position */
@@ -4819,15 +4817,6 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 3 unmodified lines
48194817 scope_stack_bottom = frame_bottom;
48204818 llabel = local_label_stack;
48214819
4822− /* save VLA state */
4823− block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4824− if (saved_vla_sp_loc != &vla_sp_root_loc)
4825− vla_sp_loc = &block_vla_sp_loc;
4826− orig_vla_sp_loc = vla_sp_loc;
4827−
4828− saved_vla_flags = vla_flags;
4829− vla_flags |= VLA_NEED_NEW_FRAME;
4830−
48314820 /* handle local labels declarations */
48324821 if (tok == TOK_LABEL) {
48334822 next();
@@ -4877,13 +4866,11 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 43 unmodified lines
48774866 sym_pop(&local_stack, s);
48784867
48794868 /* Pop VLA frames and restore stack pointer if required */
4880− if (saved_vla_sp_loc != &vla_sp_root_loc)
4881− *saved_vla_sp_loc = block_vla_sp_loc;
4882− if (vla_sp_loc != orig_vla_sp_loc) {
4883− gen_vla_sp_restore(*saved_vla_sp_loc);
4869+ if (vlas_in_scope > saved_vlas_in_scope) {
4870+ vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
4871+ vla_sp_restore();
48844872 }
4885− vla_sp_loc = saved_vla_sp_loc;
4886− vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4873+ vlas_in_scope = saved_vlas_in_scope;
48874874
48884875 next();
48894876 } else if (tok == TOK_RETURN) {
@@ -4964,13 +4951,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 74 unmodified lines
49644951 /* compute jump */
49654952 if (!csym)
49664953 tcc_error("cannot continue");
4967− if (vla_flags & VLA_IN_SCOPE) {
4968− /* If VLAs are in use, save the current stack pointer and
4969− reset the stack pointer to what it was at function entry
4970− (label will restore stack pointer in inner scopes) */
4971− vla_sp_save();
4972− gen_vla_sp_restore(vla_sp_root_loc);
4973− }
4954+ vla_sp_restore_root();
49744955 *csym = gjmp(*csym);
49754956 next();
49764957 skip(';');
@@ -4993,10 +4974,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 16 unmodified lines
49934974 skip(';');
49944975 d = ind;
49954976 c = ind;
4996− if (vla_flags & VLA_IN_SCOPE) {
4997− gen_vla_sp_restore(*vla_sp_loc);
4998− vla_flags |= VLA_NEED_NEW_FRAME;
4999− }
4977+ vla_sp_restore();
50004978 a = 0;
50014979 b = 0;
50024980 if (tok != ';') {
@@ -5007,10 +4985,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 4 unmodified lines
50074985 if (tok != ')') {
50084986 e = gjmp(0);
50094987 c = ind;
5010− if (vla_flags & VLA_IN_SCOPE) {
5011− gen_vla_sp_restore(*vla_sp_loc);
5012− vla_flags |= VLA_NEED_NEW_FRAME;
5013− }
4988+ vla_sp_restore();
50144989 gexpr();
50154990 vpop();
50164991 gjmp_addr(d);
@@ -5029,10 +5004,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 12 unmodified lines
50295004 a = 0;
50305005 b = 0;
50315006 d = ind;
5032− if (vla_flags & VLA_IN_SCOPE) {
5033− gen_vla_sp_restore(*vla_sp_loc);
5034− vla_flags |= VLA_NEED_NEW_FRAME;
5035− }
5007+ vla_sp_restore();
50365008 block(&a, &b, case_sym, def_sym, case_reg, 0);
50375009 skip(TOK_WHILE);
50385010 skip('(');
@@ -5130,14 +5102,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 91 unmodified lines
51305102 if (s->r == LABEL_DECLARED)
51315103 s->r = LABEL_FORWARD;
51325104 }
5133− /* label already defined */
5134− if (vla_flags & VLA_IN_SCOPE) {
5135− /* If VLAs are in use, save the current stack pointer and
5136− reset the stack pointer to what it was at function entry
5137− (label will restore stack pointer in inner scopes) */
5138− vla_sp_save();
5139− gen_vla_sp_restore(vla_sp_root_loc);
5140− }
5105+ vla_sp_restore_root();
51415106 if (s->r & LABEL_FORWARD)
51425107 s->jnext = gjmp(s->jnext);
51435108 else
@@ -5153,12 +5118,6 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 9 unmodified lines
51535118 b = is_label();
51545119 if (b) {
51555120 /* label case */
5156− if (vla_flags & VLA_IN_SCOPE) {
5157− /* save/restore stack pointer across label
5158− this is a no-op when combined with the load immediately
5159− after the label unless we arrive via goto */
5160− vla_sp_save();
5161− }
51625121 s = label_find(b);
51635122 if (s) {
51645123 if (s->r == LABEL_DEFINED)
@@ -5169,10 +5128,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 4 unmodified lines
51695128 s = label_push(&global_label_stack, b, LABEL_DEFINED);
51705129 }
51715130 s->jnext = ind;
5172− if (vla_flags & VLA_IN_SCOPE) {
5173− gen_vla_sp_restore(*vla_sp_loc);
5174− vla_flags |= VLA_NEED_NEW_FRAME;
5175− }
5131+ vla_sp_restore();
51765132 /* we accept this, but it is a mistake */
51775133 block_after_label:
51785134 if (tok == '}') {
@@ -5476,20 +5432,17 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 297 unmodified lines
54765432 int a;
54775433
54785434 /* save current stack pointer */
5479− if (vla_flags & VLA_NEED_NEW_FRAME) {
5480− vla_sp_save();
5481− vla_flags = VLA_IN_SCOPE;
5482− vla_sp_loc = &vla_sp_loc_tmp;
5435+ if (vlas_in_scope == 0) {
5436+ if (vla_sp_root_loc == -1)
5437+ vla_sp_root_loc = (loc -= PTR_SIZE);
5438+ gen_vla_sp_save(vla_sp_root_loc);
54835439 }
54845440
54855441 vla_runtime_type_size(type, &a);
54865442 gen_vla_alloc(type, a);
5487− vla_flags = VLA_IN_SCOPE;
5488− vla_sp_save();
5489− vset(type, VT_LOCAL|VT_LVAL, c);
5490− vswap();
5491− vstore();
5492− vpop();
5443+ gen_vla_sp_save(c);
5444+ vla_sp_loc = c;
5445+ vlas_in_scope++;
54935446 } else if (type->t & VT_ARRAY) {
54945447 s = type->ref;
54955448 n = s->c;
@@ -6072,8 +6025,8 @@ static void gen_function(Sym *sym) · 576 unmodified lines
60726025 funcname = get_tok_str(sym->v, NULL);
60736026 func_ind = ind;
60746027 /* Initialize VLA state */
6075− vla_sp_loc = &vla_sp_root_loc;
6076− vla_flags = VLA_NEED_NEW_FRAME;
6028+ vla_sp_loc = -1;
6029+ vla_sp_root_loc = -1;
60776030 /* put debug symbol */
60786031 if (tcc_state->do_debug)
60796032 put_func_debug(sym);
x86_64-gen.c+0−4
@@ -2240,11 +2240,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2239 unmodified lines
22402240 /* We align to 16 bytes rather than align */
22412241 /* and ~15, %rsp */
22422242 o(0xf0e48348);
2243− /* mov %rsp, r */
2244− o(0x8948);
2245− o(0xe0 | REG_VALUE(r));
22462243 vpop();
2247− vset(type, r, 0);
22482244 #endif
22492245 }
22502246

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