History

about CONST_WANTED & VT_NONCONST

- integrate CONST_WANTED with nocode_wanted - expr_const() checks VT_NONCONST

grischka committed 3 years ago

Commit 0ec3a401 parent bb93bf82 files · +35 −30Browse files

Unified · Split

2 files
  1. tcc.h +0 −1
  2. tccgen.c +35 −29
tcc.h+0−1
@@ -1421,7 +1421,6 @@ ST_DATA SValue *vtop; · 1420 unmodified lines
1421ST_DATA int rsym, anon_sym, ind, loc;1421ST_DATA int rsym, anon_sym, ind, loc;
1422ST_DATA char debug_modes;1422ST_DATA char debug_modes;
1423 1423
1424ST_DATA int const_wanted; /* true if constant wanted */
1425ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */1424ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
1426ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */1425ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
1427ST_DATA CType func_vt; /* current function return type (used by return instruction) */1426ST_DATA CType func_vt; /* current function return type (used by return instruction) */
tccgen.c+35−29
@@ -51,15 +51,24 @@ ST_DATA SValue *vtop; · 50 unmodified lines
51static SValue _vstack[1 + VSTACK_SIZE];51static SValue _vstack[1 + VSTACK_SIZE];
52#define vstack (_vstack + 1)52#define vstack (_vstack + 1)
53 53
54ST_DATA int const_wanted; /* true if constant wanted */
55ST_DATA int nocode_wanted; /* no code generation wanted */54ST_DATA int nocode_wanted; /* no code generation wanted */
56#define unevalmask 0xffff /* unevaluated subexpression */
57#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */55#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
58#define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */56#define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */
57
58/* no code output after unconditional jumps such as with if (0) ... */
59#define CODE_OFF_BIT 0x2000000059#define CODE_OFF_BIT 0x20000000
60#define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= CODE_OFF_BIT)60#define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= CODE_OFF_BIT)
61#define CODE_ON() (nocode_wanted &= ~CODE_OFF_BIT)61#define CODE_ON() (nocode_wanted &= ~CODE_OFF_BIT)
62 62
63/* no code output when parsing sizeof()/typeof() etc. (using nocode_wanted++/--) */
64#define NOEVAL_MASK 0x0000FFFF
65#define NOEVAL_WANTED (nocode_wanted & NOEVAL_MASK)
66
67/* no code output when parsing constant expressions */
68#define CONST_WANTED_BIT 0x00010000
69#define CONST_WANTED_MASK 0x0FFF0000
70#define CONST_WANTED (nocode_wanted & CONST_WANTED_MASK)
71
63ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */72ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
64ST_DATA CType func_vt; /* current function return type (used by return instruction) */73ST_DATA CType func_vt; /* current function return type (used by return instruction) */
65ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */74ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
@@ -375,7 +384,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 309 unmodified lines
375 funcname = "";384 funcname = "";
376 func_ind = -1;385 func_ind = -1;
377 anon_sym = SYM_FIRST_ANOM;386 anon_sym = SYM_FIRST_ANOM;
378 const_wanted = 0;
379 nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */387 nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */
380 local_scope = 0;388 local_scope = 0;
381 debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;389 debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;
@@ -2274,10 +2282,10 @@ static void gen_opic(int op) · 1892 unmodified lines
2274 int t2 = v2->type.t & VT_BTYPE;2282 int t2 = v2->type.t & VT_BTYPE;
2275 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;2283 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2276 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;2284 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2277 int nonconst = (v1->r | v2->r) & VT_NONCONST;
2278 uint64_t l1 = c1 ? v1->c.i : 0;2285 uint64_t l1 = c1 ? v1->c.i : 0;
2279 uint64_t l2 = c2 ? v2->c.i : 0;2286 uint64_t l2 = c2 ? v2->c.i : 0;
2280 int shm = (t1 == VT_LLONG) ? 63 : 31;2287 int shm = (t1 == VT_LLONG) ? 63 : 31;
2288 int r;
2281 2289
2282 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))2290 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2283 l1 = ((uint32_t)l1 |2291 l1 = ((uint32_t)l1 |
@@ -2302,7 +2310,7 @@ static void gen_opic(int op) · 18 unmodified lines
2302 case TOK_UMOD:2310 case TOK_UMOD:
2303 /* if division by zero, generate explicit division */2311 /* if division by zero, generate explicit division */
2304 if (l2 == 0) {2312 if (l2 == 0) {
2305 if (const_wanted && !(nocode_wanted & unevalmask))2313 if (CONST_WANTED && !NOEVAL_WANTED)
2306 tcc_error("division by zero in constant");2314 tcc_error("division by zero in constant");
2307 goto general_case;2315 goto general_case;
2308 }2316 }
@@ -2339,9 +2347,9 @@ static void gen_opic(int op) · 30 unmodified lines
2339 l1 = ((uint32_t)l1 |2347 l1 = ((uint32_t)l1 |
2340 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));2348 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2341 v1->c.i = l1;2349 v1->c.i = l1;
2350 v1->r |= v2->r & VT_NONCONST;
2342 vtop--;2351 vtop--;
2343 } else {2352 } else {
2344 nonconst = VT_NONCONST;
2345 /* if commutative ops, put c2 as constant */2353 /* if commutative ops, put c2 as constant */
2346 if (c1 && (op == '+' || op == '&' || op == '^' || 2354 if (c1 && (op == '+' || op == '&' || op == '^' ||
2347 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {2355 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
@@ -2349,14 +2357,12 @@ static void gen_opic(int op) · 1 unmodified line
2349 c2 = c1; //c = c1, c1 = c2, c2 = c;2357 c2 = c1; //c = c1, c1 = c2, c2 = c;
2350 l2 = l1; //l = l1, l1 = l2, l2 = l;2358 l2 = l1; //l = l1, l1 = l2, l2 = l;
2351 }2359 }
2352 if (!const_wanted &&2360 if (c1 && ((l1 == 0 &&
2353 c1 && ((l1 == 0 &&
2354 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||2361 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2355 (l1 == -1 && op == TOK_SAR))) {2362 (l1 == -1 && op == TOK_SAR))) {
2356 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */2363 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2357 vtop--;2364 vpop();
2358 } else if (!const_wanted &&2365 } else if (c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2359 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2360 (op == '|' &&2366 (op == '|' &&
2361 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||2367 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2362 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {2368 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
@@ -2393,8 +2399,8 @@ static void gen_opic(int op) · 30 unmodified lines
2393 }2399 }
2394 goto general_case;2400 goto general_case;
2395 } else if (c2 && (op == '+' || op == '-') &&2401 } else if (c2 && (op == '+' || op == '-') &&
2396 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))2402 (r = vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM),
2397 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {2403 r == (VT_CONST | VT_SYM) || r == VT_LOCAL)) {
2398 /* symbol + constant case */2404 /* symbol + constant case */
2399 if (op == '-')2405 if (op == '-')
2400 l2 = -l2;2406 l2 = -l2;
@@ -2414,9 +2420,9 @@ static void gen_opic(int op) · 13 unmodified lines
2414 else2420 else
2415 gen_opi(op);2421 gen_opi(op);
2416 }2422 }
2423 if (vtop->r == VT_CONST)
2424 vtop->r |= VT_NONCONST; /* is const, but only by optimization */
2417 }2425 }
2418 if (vtop->r == VT_CONST)
2419 vtop->r |= nonconst;
2420}2426}
2421 2427
2422#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I3862428#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
@@ -2484,7 +2490,7 @@ static void gen_opif(int op) · 61 unmodified lines
2484 }2490 }
2485 /* NOTE: we only do constant propagation if finite number (not2491 /* NOTE: we only do constant propagation if finite number (not
2486 NaN or infinity) (ANSI spec) */2492 NaN or infinity) (ANSI spec) */
2487 if (!(ieee_finite(f1) || !ieee_finite(f2)) && !const_wanted)2493 if (!(ieee_finite(f1) || !ieee_finite(f2)) && !CONST_WANTED)
2488 goto general_case;2494 goto general_case;
2489 switch(op) {2495 switch(op) {
2490 case '+': f1 += f2; break;2496 case '+': f1 += f2; break;
@@ -2495,7 +2501,7 @@ static void gen_opif(int op) · 4 unmodified lines
2495 union { float f; unsigned u; } x1, x2, y;2501 union { float f; unsigned u; } x1, x2, y;
2496 /* If not in initializer we need to potentially generate2502 /* If not in initializer we need to potentially generate
2497 FP exceptions at runtime, otherwise we want to fold. */2503 FP exceptions at runtime, otherwise we want to fold. */
2498 if (!const_wanted)2504 if (!CONST_WANTED)
2499 goto general_case;2505 goto general_case;
2500 /* the run-time result of 0.0/0.0 on x87, also of other compilers2506 /* the run-time result of 0.0/0.0 on x87, also of other compilers
2501 when used to compile the f1 /= f2 below, would be -nan */2507 when used to compile the f1 /= f2 below, would be -nan */
@@ -2965,7 +2971,7 @@ redo: · 463 unmodified lines
2965 vpush_type_size(pointed_type(&vtop[-1].type), &align);2971 vpush_type_size(pointed_type(&vtop[-1].type), &align);
2966 gen_op('*');2972 gen_op('*');
2967#ifdef CONFIG_TCC_BCHECK2973#ifdef CONFIG_TCC_BCHECK
2968 if (tcc_state->do_bounds_check && !const_wanted) {2974 if (tcc_state->do_bounds_check && !CONST_WANTED) {
2969 /* if bounded pointers, we generate a special code to2975 /* if bounded pointers, we generate a special code to
2970 test bounds */2976 test bounds */
2971 if (op == '-') {2977 if (op == '-') {
@@ -5533,7 +5539,7 @@ ST_FUNC void unary(void) · 2561 unmodified lines
5533 }5539 }
5534 } else if (tok == '{') {5540 } else if (tok == '{') {
5535 int saved_nocode_wanted = nocode_wanted;5541 int saved_nocode_wanted = nocode_wanted;
5536 if (const_wanted && !(nocode_wanted & unevalmask))5542 if (CONST_WANTED && !NOEVAL_WANTED)
5537 expect("constant");5543 expect("constant");
5538 if (0 == local_scope)5544 if (0 == local_scope)
5539 tcc_error("statement expression outside of function");5545 tcc_error("statement expression outside of function");
@@ -5848,17 +5854,19 @@ ST_FUNC void unary(void) · 308 unmodified lines
5848 int has_match = 0;5854 int has_match = 0;
5849 int learn = 0;5855 int learn = 0;
5850 TokenString *str = NULL;5856 TokenString *str = NULL;
5851 int saved_const_wanted = const_wanted;5857 int saved_nocode_wanted = nocode_wanted;
5858 nocode_wanted &= ~CONST_WANTED_MASK;
5852 5859
5853 next();5860 next();
5854 skip('(');5861 skip('(');
5855 const_wanted = 0;
5856 expr_type(&controlling_type, expr_eq);5862 expr_type(&controlling_type, expr_eq);
5857 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);5863 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
5858 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)5864 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
5859 mk_pointer(&controlling_type);5865 mk_pointer(&controlling_type);
5860 const_wanted = saved_const_wanted;5866
5861 for (;;) {5867 nocode_wanted = saved_nocode_wanted;
5868
5869 for (;;) {
5862 learn = 0;5870 learn = 0;
5863 skip(',');5871 skip(',');
5864 if (tok == TOK_DEFAULT) {5872 if (tok == TOK_DEFAULT) {
@@ -6532,11 +6540,9 @@ ST_FUNC void gexpr(void) · 667 unmodified lines
6532/* parse a constant expression and return value in vtop. */6540/* parse a constant expression and return value in vtop. */
6533static void expr_const1(void)6541static void expr_const1(void)
6534{6542{
6535 const_wanted++;6543 nocode_wanted += CONST_WANTED_BIT;
6536 nocode_wanted += unevalmask + 1;
6537 expr_cond();6544 expr_cond();
6538 nocode_wanted -= unevalmask + 1;6545 nocode_wanted -= CONST_WANTED_BIT;
6539 const_wanted--;
6540}6546}
6541 6547
6542/* parse an integer constant and return its value. */6548/* parse an integer constant and return its value. */
@@ -6544,7 +6550,7 @@ static inline int64_t expr_const64(void) · 1 unmodified line
6544{6550{
6545 int64_t c;6551 int64_t c;
6546 expr_const1();6552 expr_const1();
6547 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)6553 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM | VT_NONCONST)) != VT_CONST)
6548 expect("constant expression");6554 expect("constant expression");
6549 c = vtop->c.i;6555 c = vtop->c.i;
6550 vpop();6556 vpop();

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