[PATCH 01/21] split copy() into "need to copy" and "can move in place" cases

Al Viro <[email protected]> Mon, 16 Mar 2026 07:03:55 +0000
Newsgroups org.kernel.vger.linux-sparse
Message-ID <[email protected]>
For one thing, rechecking the flag on each iteration of a loop is rather
silly, especially when there's very little in common between the "copy"
and "move" cases and the loop is pretty hot.

For another, it's better to have the counter-related logics lifted
into substitute().

Signed-off-by: Al Viro <[email protected]>
---
 pre-process.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/pre-process.c b/pre-process.c
index 4e322855..ae493dc2 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -598,15 +598,23 @@ static struct token *dup_token(const struct token *token, struct position *strea
 	return alloc;	
 }
 
-static struct token **copy(struct token **where, struct token *list, int *count)
+static struct token **move_into(struct token **where, struct token *list)
+{
+	*where = list;
+	while (!eof_token(list)) {
+		if (token_type(list) == TOKEN_IDENT && list->ident->tainted)
+			list->pos.noexpand = 1;
+		where = &list->next;
+		list = *where;
+	}
+	return where;
+}
+
+static struct token **copy(struct token **where, struct token *list)
 {
-	int need_copy = --*count;
 	while (!eof_token(list)) {
 		struct token *token;
-		if (need_copy)
-			token = dup_token(list, &list->pos);
-		else
-			token = list;
+		token = dup_token(list, &list->pos);
 		if (token_type(token) == TOKEN_IDENT && token->ident->tainted)
 			token->pos.noexpand = 1;
 		*where = token;
@@ -698,7 +706,10 @@ static struct token **substitute(struct token **list, const struct token *body,
 				continue;
 			}
 		copy_arg:
-			tail = copy(&added, arg, count);
+			if (!--*count)
+				tail = move_into(&added, arg);
+			else
+				tail = copy(&added, arg);
 			added->pos.newline = body->pos.newline;
 			added->pos.whitespace = body->pos.whitespace;
 			break;
-- 
2.47.3