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
14211421 ST_DATA int rsym, anon_sym, ind, loc;
14221422 ST_DATA char debug_modes;
14231423
1424−ST_DATA int const_wanted; /* true if constant wanted */
14251424 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
14261425 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
14271426 ST_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
5151 static SValue _vstack[1 + VSTACK_SIZE];
5252 #define vstack (_vstack + 1)
5353
54−ST_DATA int const_wanted; /* true if constant wanted */
5554 ST_DATA int nocode_wanted; /* no code generation wanted */
56−#define unevalmask 0xffff /* unevaluated subexpression */
5755 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
5856 #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) ... */
5959 #define CODE_OFF_BIT 0x20000000
6060 #define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= CODE_OFF_BIT)
6161 #define CODE_ON() (nocode_wanted &= ~CODE_OFF_BIT)
6262
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+
6372 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
6473 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
6574 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
375384 funcname = "";
376385 func_ind = -1;
377386 anon_sym = SYM_FIRST_ANOM;
378− const_wanted = 0;
379387 nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */
380388 local_scope = 0;
381389 debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;
@@ -2274,10 +2282,10 @@ static void gen_opic(int op) · 1892 unmodified lines
22742282 int t2 = v2->type.t & VT_BTYPE;
22752283 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
22762284 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2277− int nonconst = (v1->r | v2->r) & VT_NONCONST;
22782285 uint64_t l1 = c1 ? v1->c.i : 0;
22792286 uint64_t l2 = c2 ? v2->c.i : 0;
22802287 int shm = (t1 == VT_LLONG) ? 63 : 31;
2288+ int r;
22812289
22822290 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
22832291 l1 = ((uint32_t)l1 |
@@ -2302,7 +2310,7 @@ static void gen_opic(int op) · 18 unmodified lines
23022310 case TOK_UMOD:
23032311 /* if division by zero, generate explicit division */
23042312 if (l2 == 0) {
2305− if (const_wanted && !(nocode_wanted & unevalmask))
2313+ if (CONST_WANTED && !NOEVAL_WANTED)
23062314 tcc_error("division by zero in constant");
23072315 goto general_case;
23082316 }
@@ -2339,9 +2347,9 @@ static void gen_opic(int op) · 30 unmodified lines
23392347 l1 = ((uint32_t)l1 |
23402348 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
23412349 v1->c.i = l1;
2350+ v1->r |= v2->r & VT_NONCONST;
23422351 vtop--;
23432352 } else {
2344− nonconst = VT_NONCONST;
23452353 /* if commutative ops, put c2 as constant */
23462354 if (c1 && (op == '+' || op == '&' || op == '^' ||
23472355 op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
@@ -2349,14 +2357,12 @@ static void gen_opic(int op) · 1 unmodified line
23492357 c2 = c1; //c = c1, c1 = c2, c2 = c;
23502358 l2 = l1; //l = l1, l1 = l2, l2 = l;
23512359 }
2352− if (!const_wanted &&
2353− c1 && ((l1 == 0 &&
2360+ if (c1 && ((l1 == 0 &&
23542361 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
23552362 (l1 == -1 && op == TOK_SAR))) {
23562363 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2357− vtop--;
2358− } else if (!const_wanted &&
2359− c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2364+ vpop();
2365+ } else if (c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
23602366 (op == '|' &&
23612367 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
23622368 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
@@ -2393,8 +2399,8 @@ static void gen_opic(int op) · 30 unmodified lines
23932399 }
23942400 goto general_case;
23952401 } else if (c2 && (op == '+' || op == '-') &&
2396− (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2397− || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2402+ (r = vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM),
2403+ r == (VT_CONST | VT_SYM) || r == VT_LOCAL)) {
23982404 /* symbol + constant case */
23992405 if (op == '-')
24002406 l2 = -l2;
@@ -2414,9 +2420,9 @@ static void gen_opic(int op) · 13 unmodified lines
24142420 else
24152421 gen_opi(op);
24162422 }
2423+ if (vtop->r == VT_CONST)
2424+ vtop->r |= VT_NONCONST; /* is const, but only by optimization */
24172425 }
2418− if (vtop->r == VT_CONST)
2419− vtop->r |= nonconst;
24202426 }
24212427
24222428 #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
@@ -2484,7 +2490,7 @@ static void gen_opif(int op) · 61 unmodified lines
24842490 }
24852491 /* NOTE: we only do constant propagation if finite number (not
24862492 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)
24882494 goto general_case;
24892495 switch(op) {
24902496 case '+': f1 += f2; break;
@@ -2495,7 +2501,7 @@ static void gen_opif(int op) · 4 unmodified lines
24952501 union { float f; unsigned u; } x1, x2, y;
24962502 /* If not in initializer we need to potentially generate
24972503 FP exceptions at runtime, otherwise we want to fold. */
2498− if (!const_wanted)
2504+ if (!CONST_WANTED)
24992505 goto general_case;
25002506 /* the run-time result of 0.0/0.0 on x87, also of other compilers
25012507 when used to compile the f1 /= f2 below, would be -nan */
@@ -2965,7 +2971,7 @@ redo: · 463 unmodified lines
29652971 vpush_type_size(pointed_type(&vtop[-1].type), &align);
29662972 gen_op('*');
29672973 #ifdef CONFIG_TCC_BCHECK
2968− if (tcc_state->do_bounds_check && !const_wanted) {
2974+ if (tcc_state->do_bounds_check && !CONST_WANTED) {
29692975 /* if bounded pointers, we generate a special code to
29702976 test bounds */
29712977 if (op == '-') {
@@ -5533,7 +5539,7 @@ ST_FUNC void unary(void) · 2561 unmodified lines
55335539 }
55345540 } else if (tok == '{') {
55355541 int saved_nocode_wanted = nocode_wanted;
5536− if (const_wanted && !(nocode_wanted & unevalmask))
5542+ if (CONST_WANTED && !NOEVAL_WANTED)
55375543 expect("constant");
55385544 if (0 == local_scope)
55395545 tcc_error("statement expression outside of function");
@@ -5848,17 +5854,19 @@ ST_FUNC void unary(void) · 308 unmodified lines
58485854 int has_match = 0;
58495855 int learn = 0;
58505856 TokenString *str = NULL;
5851− int saved_const_wanted = const_wanted;
5857+ int saved_nocode_wanted = nocode_wanted;
5858+ nocode_wanted &= ~CONST_WANTED_MASK;
58525859
5853− next();
5860+ next();
58545861 skip('(');
5855− const_wanted = 0;
58565862 expr_type(&controlling_type, expr_eq);
58575863 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
58585864 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
58595865 mk_pointer(&controlling_type);
5860− const_wanted = saved_const_wanted;
5861− for (;;) {
5866+
5867+ nocode_wanted = saved_nocode_wanted;
5868+
5869+ for (;;) {
58625870 learn = 0;
58635871 skip(',');
58645872 if (tok == TOK_DEFAULT) {
@@ -6532,11 +6540,9 @@ ST_FUNC void gexpr(void) · 667 unmodified lines
65326540 /* parse a constant expression and return value in vtop. */
65336541 static void expr_const1(void)
65346542 {
6535− const_wanted++;
6536− nocode_wanted += unevalmask + 1;
6543+ nocode_wanted += CONST_WANTED_BIT;
65376544 expr_cond();
6538− nocode_wanted -= unevalmask + 1;
6539− const_wanted--;
6545+ nocode_wanted -= CONST_WANTED_BIT;
65406546 }
65416547
65426548 /* parse an integer constant and return its value. */
@@ -6544,7 +6550,7 @@ static inline int64_t expr_const64(void) · 1 unmodified line
65446550 {
65456551 int64_t c;
65466552 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)
65486554 expect("constant expression");
65496555 c = vtop->c.i;
65506556 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