aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2016-08-24 14:03:05 -0400
committerMichal Marek <mmarek@suse.com>2016-08-24 16:34:19 -0400
commitdee81e9886748594babac67c14b0f720148e255d (patch)
tree5c1bc1e5b8c6475e7d5845593f958e34807bfa1c /scripts
parente007c53397acb5554e226693e3bff54a312ccd96 (diff)
fixdep: faster CONFIG_ search
Do you think kernel build is 100% dominated by gcc? You are wrong! One small utility called "fixdep" consistently manages to sneak into profile's first page (unless you have small monitor of course). The choke point is this clever code: for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } 4 branches per 4 characters is not fast. Use strstr(3), so that SSE2 etc can be used. With this patch, fixdep is so deep at the bottom, it is hard to find it. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Michal Marek <mmarek@suse.com>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/basic/fixdep.c86
1 files changed, 28 insertions, 58 deletions
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 746ec1ece614..fff818b92acb 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -82,8 +82,7 @@
82 * to date before even starting the recursive build, so it's too late 82 * to date before even starting the recursive build, so it's too late
83 * at this point anyway. 83 * at this point anyway.
84 * 84 *
85 * The algorithm to grep for "CONFIG_..." is bit unusual, but should 85 * We don't even try to really parse the header files, but
86 * be fast ;-) We don't even try to really parse the header files, but
87 * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will 86 * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
88 * be picked up as well. It's not a problem with respect to 87 * be picked up as well. It's not a problem with respect to
89 * correctness, since that can only give too many dependencies, thus 88 * correctness, since that can only give too many dependencies, thus
@@ -115,11 +114,6 @@
115#include <ctype.h> 114#include <ctype.h>
116#include <arpa/inet.h> 115#include <arpa/inet.h>
117 116
118#define INT_CONF ntohl(0x434f4e46)
119#define INT_ONFI ntohl(0x4f4e4649)
120#define INT_NFIG ntohl(0x4e464947)
121#define INT_FIG_ ntohl(0x4649475f)
122
123int insert_extra_deps; 117int insert_extra_deps;
124char *target; 118char *target;
125char *depfile; 119char *depfile;
@@ -241,37 +235,22 @@ static void use_config(const char *m, int slen)
241 print_config(m, slen); 235 print_config(m, slen);
242} 236}
243 237
244static void parse_config_file(const char *map, size_t len) 238static void parse_config_file(const char *p)
245{ 239{
246 const int *end = (const int *) (map + len); 240 const char *q, *r;
247 /* start at +1, so that p can never be < map */ 241
248 const int *m = (const int *) map + 1; 242 while ((p = strstr(p, "CONFIG_"))) {
249 const char *p, *q;
250
251 for (; m < end; m++) {
252 if (*m == INT_CONF) { p = (char *) m ; goto conf; }
253 if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
254 if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
255 if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
256 continue;
257 conf:
258 if (p > map + len - 7)
259 continue;
260 if (memcmp(p, "CONFIG_", 7))
261 continue;
262 p += 7; 243 p += 7;
263 for (q = p; q < map + len; q++) { 244 q = p;
264 if (!(isalnum(*q) || *q == '_')) 245 while (*q && (isalnum(*q) || *q == '_'))
265 goto found; 246 q++;
266 } 247 if (memcmp(q - 7, "_MODULE", 7) == 0)
267 continue; 248 r = q - 7;
268 249 else
269 found: 250 r = q;
270 if (!memcmp(q - 7, "_MODULE", 7)) 251 if (r > p)
271 q -= 7; 252 use_config(p, r - p);
272 if (q - p < 0) 253 p = q;
273 continue;
274 use_config(p, q - p);
275 } 254 }
276} 255}
277 256
@@ -291,7 +270,7 @@ static void do_config_file(const char *filename)
291{ 270{
292 struct stat st; 271 struct stat st;
293 int fd; 272 int fd;
294 void *map; 273 char *map;
295 274
296 fd = open(filename, O_RDONLY); 275 fd = open(filename, O_RDONLY);
297 if (fd < 0) { 276 if (fd < 0) {
@@ -308,18 +287,23 @@ static void do_config_file(const char *filename)
308 close(fd); 287 close(fd);
309 return; 288 return;
310 } 289 }
311 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 290 map = malloc(st.st_size + 1);
312 if ((long) map == -1) { 291 if (!map) {
313 perror("fixdep: mmap"); 292 perror("fixdep: malloc");
314 close(fd); 293 close(fd);
315 return; 294 return;
316 } 295 }
296 if (read(fd, map, st.st_size) != st.st_size) {
297 perror("fixdep: read");
298 close(fd);
299 return;
300 }
301 map[st.st_size] = '\0';
302 close(fd);
317 303
318 parse_config_file(map, st.st_size); 304 parse_config_file(map);
319
320 munmap(map, st.st_size);
321 305
322 close(fd); 306 free(map);
323} 307}
324 308
325/* 309/*
@@ -446,22 +430,8 @@ static void print_deps(void)
446 close(fd); 430 close(fd);
447} 431}
448 432
449static void traps(void)
450{
451 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
452 int *p = (int *)test;
453
454 if (*p != INT_CONF) {
455 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n",
456 *p);
457 exit(2);
458 }
459}
460
461int main(int argc, char *argv[]) 433int main(int argc, char *argv[])
462{ 434{
463 traps();
464
465 if (argc == 5 && !strcmp(argv[1], "-e")) { 435 if (argc == 5 && !strcmp(argv[1], "-e")) {
466 insert_extra_deps = 1; 436 insert_extra_deps = 1;
467 argv++; 437 argv++;