- integrate CONST_WANTED with nocode_wanted - expr_const() checks VT_NONCONST
Unified · Split
| @@ -1421,7 +1421,6 @@ ST_DATA SValue *vtop; · 1420 unmodified lines | |||
| 1421 | ST_DATA int rsym, anon_sym, ind, loc; | 1421 | ST_DATA int rsym, anon_sym, ind, loc; |
| 1422 | ST_DATA char debug_modes; | 1422 | ST_DATA char debug_modes; |
| 1423 | 1423 | ||
| 1424 | ST_DATA int const_wanted; /* true if constant wanted */ | ||
| 1425 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ | 1424 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ |
| 1426 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | 1425 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| 1427 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | 1426 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ |
| @@ -51,15 +51,24 @@ ST_DATA SValue *vtop; · 50 unmodified lines | |||
| 51 | static SValue _vstack[1 + VSTACK_SIZE]; | 51 | static SValue _vstack[1 + VSTACK_SIZE]; |
| 52 | #define vstack (_vstack + 1) | 52 | #define vstack (_vstack + 1) |
| 53 | 53 | ||
| 54 | ST_DATA int const_wanted; /* true if constant wanted */ | ||
| 55 | ST_DATA int nocode_wanted; /* no code generation wanted */ | 54 | ST_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 0x20000000 | 59 | #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 | |||
| 63 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | 72 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| 64 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | 73 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ |
| 65 | ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ | 74 | ST_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 | else | 2420 | 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_I386 | 2428 | #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 (not | 2491 | /* 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 generate | 2502 | /* 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 compilers | 2506 | /* 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_BCHECK | 2973 | #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 to | 2975 | /* 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. */ |
| 6533 | static void expr_const1(void) | 6541 | static 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(); |