From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-sparse@vger.kernel.org
Cc: chriscli@google.com, torvalds@linux-foundation.org,
zxh@xh-zhang.com, ben.dooks@codethink.co.uk,
dan.carpenter@linaro.org, rf@opensource.cirrus.com
Subject: [PATCH 5/6] saner collect_arg() code generation
Date: Tue, 31 Mar 2026 09:07:28 +0100 [thread overview]
Message-ID: <20260331080729.1378613-5-viro@zeniv.linux.org.uk> (raw)
In-Reply-To: <20260331080729.1378613-1-viro@zeniv.linux.org.uk>
1) gently coax gcc code generator away from screwing the bitfields
handling it is so keen to do - pass struct position from the caller
by value, with .newline already cleared (with inlined helper that
does trimming), do *not* let collect_arg() see that it's always
setting ->pos.newline to 0 (otherwise the FPOS tries to peel the damn
thing apart, turning mask-then-or into a bleeding horror).
2) get rid of 'vararg' checks for commas by changing the way we
keep track of nesting parentheses - instead of
number of '(' - number of ')'
use
2 * number of '(' - 2 * number of ')' + vararg
That still recognizes the closing parenthesis of argument list
(counter gets negative there, vararg or no vararg) and it does
recognize an argument-terminating comma without having to look
at 'vararg' - just check if counter is zero.
Reduces spills nicely.
3) do *not* use eof_token() as loop termination condition, compare
token_type() with TOKEN_EOF instead. Yes, it's faster to compare
the pointer with constant instead, but it is *not* going to match
that unless we have an unterminated argument list and we are going
to check for TOKEN_STREAM{BEGIN,END} immediately afterwards anyway,
with the same "leave the loop now" on match, so these checks combine
nicely.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
pre-process.c | 44 ++++++++++++++++++++++++++------------------
1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/pre-process.c b/pre-process.c
index e62d6379..a368b9ed 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -255,42 +255,41 @@ static void expand_list(struct token **list)
static void preprocessor_line(struct stream *stream, struct token **line);
-static struct token *collect_arg(struct token *prev, bool vararg, const struct position *pos)
+static struct token *collect_arg(struct token *prev, bool vararg, struct position pos)
{
struct stream *stream = input_streams + prev->pos.stream;
struct token **p = &prev->next;
struct token *next;
- int nesting = 0;
+ int nesting = vararg;
- while (!eof_token(next = scan_next(p))) {
+ while (1) {
+ next = scan_next(p);
+ if (token_type(next) == TOKEN_STREAMBEGIN ||
+ token_type(next) == TOKEN_STREAMEND ||
+ token_type(next) == TOKEN_EOF)
+ break;
if (token_type(next) == TOKEN_DIRECTIVE) {
preprocessor_line(stream, p);
__free_token(next); /* Free the '#' token */
continue;
}
- switch (token_type(next)) {
- case TOKEN_STREAMEND:
- case TOKEN_STREAMBEGIN:
- *p = &eof_token_entry;
- return next;
- }
if (false_nesting) {
*p = next->next;
__free_token(next);
continue;
}
if (match_op(next, '(')) {
- nesting++;
+ nesting += 2;
} else if (match_op(next, ')')) {
- if (!nesting--)
+ if ((nesting -= 2) < 0)
break;
- } else if (match_op(next, ',') && !nesting && !vararg) {
+ } else if (match_op(next, ',') && !nesting) {
break;
}
- next->pos.stream = pos->stream;
- next->pos.line = pos->line;
- next->pos.pos = pos->pos;
- next->pos.newline = 0;
+ next->pos.stream = pos.stream;
+ next->pos.line = pos.line;
+ next->pos.pos = pos.pos;
+ next->pos.newline = pos.newline;
p = &next->next;
}
*p = &eof_token_entry;
@@ -305,6 +304,15 @@ struct arg {
struct token *arg[3];
};
+static inline struct position location(const struct position *p)
+{
+ return (struct position) {
+ .stream = p->stream,
+ .line = p->line,
+ .pos = p->pos
+ };
+}
+
static int collect_arguments(struct token *what, int fixed, bool vararg, struct arg *args)
{
struct token *start = scan_next(&what->next);
@@ -317,7 +325,7 @@ static int collect_arguments(struct token *what, int fixed, bool vararg, struct
if (!match_op(start, '('))
return 0;
for (commas = 0; commas < fixed; commas++) {
- next = collect_arg(start, false, &what->pos);
+ next = collect_arg(start, false, location(&what->pos));
if (token_type(next) != TOKEN_SPECIAL)
goto Eclosing;
args[commas + 1].arg[ARG_QUOTED] = start->next;
@@ -329,7 +337,7 @@ static int collect_arguments(struct token *what, int fixed, bool vararg, struct
start = next;
}
if (commas == fixed) {
- next = collect_arg(start, true, &what->pos);
+ next = collect_arg(start, true, location(&what->pos));
if (token_type(next) != TOKEN_SPECIAL)
goto Eclosing;
v = start->next;
--
2.47.3
next prev parent reply other threads:[~2026-03-31 8:04 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1771930766.git.dan.carpenter@linaro.org>
2026-02-24 11:07 ` [PATCH] sparse: add support for __VA_OPT__ Dan Carpenter
2026-02-24 11:16 ` Ben Dooks
2026-02-24 11:56 ` Dan Carpenter
2026-02-24 12:42 ` Richard Fitzgerald
2026-02-24 13:15 ` Ben Dooks
2026-02-25 2:39 ` Chris Li
2026-02-25 3:36 ` Al Viro
2026-02-25 5:29 ` [RFC PATCH] pre-process: add __VA_OPT__ support Eric Zhang
2026-02-25 6:40 ` Al Viro
2026-02-25 7:27 ` Al Viro
2026-02-25 8:14 ` Eric Zhang
2026-02-25 22:18 ` Al Viro
2026-02-26 7:29 ` Al Viro
2026-03-16 6:56 ` Al Viro
2026-03-16 7:03 ` [PATCH 01/21] split copy() into "need to copy" and "can move in place" cases Al Viro
2026-03-16 7:03 ` [PATCH 02/21] expand and simplify the call of dup_token() in copy() Al Viro
2026-03-16 7:03 ` [PATCH 03/21] more dup_token() optimizations Al Viro
2026-03-16 7:03 ` [PATCH 04/21] parsing #define: saner handling of argument count, part 1 Al Viro
2026-03-16 7:03 ` [PATCH 05/21] simplify collect_arguments() and fix error handling there Al Viro
2026-03-16 7:04 ` [PATCH 06/21] try_arg(): don't use arglist for argument name lookups Al Viro
2026-03-16 7:04 ` [PATCH 07/21] make expand_has_...() responsible for expanding its argument Al Viro
2026-03-16 7:04 ` [PATCH 08/21] preparing to change argument number encoding for TOKEN_..._ARGUMENT Al Viro
2026-03-16 7:04 ` [PATCH 09/21] steal 2 bits from argnum for argument kind Al Viro
2026-03-16 7:04 ` [PATCH 10/21] on-demand argument expansion Al Viro
2026-03-16 7:04 ` [PATCH 11/21] kill create_arglist() Al Viro
2026-03-16 7:04 ` [PATCH 12/21] stop mangling arglist, get rid of TOKEN_ARG_COUNT Al Viro
2026-03-16 7:04 ` [PATCH 13/21] deal with ## on arguments separately Al Viro
2026-03-16 7:04 ` [PATCH 14/21] preparations for __VA_OPT__ support: reshuffle argument slot assignments Al Viro
2026-03-16 7:04 ` [PATCH 15/21] pre-process.c: split try_arg() Al Viro
2026-03-16 7:04 ` [PATCH 16/21] __VA_OPT__: parsing Al Viro
2026-03-16 7:04 ` [PATCH 17/21] expansion-time va_opt handling Al Viro
2026-03-16 7:04 ` [PATCH 18/21] merge(): saner handling of ->noexpand Al Viro
2026-03-16 7:04 ` [PATCH 19/21] simplify the calling conventions of collect_arguments() Al Viro
2026-03-16 7:04 ` [PATCH 20/21] make expand_one_symbol() inline Al Viro
2026-03-16 7:04 ` [PATCH 21/21] substitute(): convert switch() into cascade of ifs Al Viro
2026-03-16 16:42 ` [RFC PATCH] pre-process: add __VA_OPT__ support Linus Torvalds
2026-03-19 3:53 ` Al Viro
2026-03-19 4:07 ` Linus Torvalds
2026-03-19 5:34 ` Al Viro
2026-03-17 7:41 ` Chris Li
2026-03-18 6:35 ` Eric Zhang
2026-03-31 8:06 ` Al Viro
2026-03-31 8:07 ` [PATCH 1/6] nextchar(): get rid of special[] Al Viro
2026-03-31 8:07 ` [PATCH 2/6] simplify the inlined side of nextchar() Al Viro
2026-03-31 8:07 ` [PATCH 3/6] tokenize_stream(): don't bother with isspace() Al Viro
2026-03-31 8:07 ` [PATCH 4/6] TOKEN_DIRECTIVE: recognize directive-introducing # in tokenizer Al Viro
2026-03-31 8:07 ` Al Viro [this message]
2026-03-31 8:07 ` [PATCH 6/6] try to get whitespaces right Al Viro
2026-04-01 10:39 ` [RFC PATCH] pre-process: add __VA_OPT__ support Al Viro
2026-04-01 16:18 ` Linus Torvalds
2026-04-01 19:52 ` Al Viro
2026-04-01 20:22 ` Al Viro
2026-02-25 7:05 ` [PATCH] sparse: add support for __VA_OPT__ Chris Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260331080729.1378613-5-viro@zeniv.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=ben.dooks@codethink.co.uk \
--cc=chriscli@google.com \
--cc=dan.carpenter@linaro.org \
--cc=linux-sparse@vger.kernel.org \
--cc=rf@opensource.cirrus.com \
--cc=torvalds@linux-foundation.org \
--cc=zxh@xh-zhang.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox