Skip to content

Commit d0e624a

Browse files
avarttaylorr
authored andcommitted
cocci: run against a generated ALL.cocci
The preceding commits to make the "coccicheck" target incremental made it slower in some cases. As an optimization let's not have the many=many mapping of <*.cocci>=<*.[ch]>, but instead concat the <*.cocci> into an ALL.cocci, and then run one-to-many ALL.cocci=<*.[ch]>. A "make coccicheck" is now around 2x as fast as it was on "master", and around 1.5x as fast as the preceding change to make the run incremental: $ git hyperfine -L rev origin/master,HEAD~,HEAD -p 'make clean' 'make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' -r 3 Benchmark 1: make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'origin/master Time (mean ± σ): 4.258 s ± 0.015 s [User: 27.432 s, System: 1.532 s] Range (min … max): 4.241 s … 4.268 s 3 runs Benchmark 2: make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'HEAD~ Time (mean ± σ): 5.365 s ± 0.079 s [User: 36.899 s, System: 1.810 s] Range (min … max): 5.281 s … 5.436 s 3 runs Benchmark 3: make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'HEAD Time (mean ± σ): 2.725 s ± 0.063 s [User: 14.796 s, System: 0.233 s] Range (min … max): 2.667 s … 2.792 s 3 runs Summary 'make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'HEAD' ran 1.56 ± 0.04 times faster than 'make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'origin/master' 1.97 ± 0.05 times faster than 'make coccicheck SPATCH=spatch COCCI_SOURCES="$(echo $(ls o*.c builtin/h*.c))"' in 'HEAD~' This can be turned off with SPATCH_CONCAT_COCCI, but as the beneficiaries of "SPATCH_CONCAT_COCCI=" would mainly be those developing the *.cocci rules themselves, let's leave this optimization on by default. For more information see my "Optimizing *.cocci rules by concat'ing them" (<[email protected]>) on the [email protected] mailing list. This potentially changes the results of our *.cocci rules, but as noted in that discussion it should be safe for our use. We don't name rules, or if we do their names don't conflict across our *.cocci files. To the extent that we'd have any inter-dependencies between rules this doesn't make that worse, as we'd have them now if we ran "make coccicheck", applied the results, and would then have (due to hypothetical interdependencies) suggested changes on the subsequent "make coccicheck". Our "coccicheck-test" target makes use of the ALL.cocci when running tests, e.g. when testing unused.{c,out} we test it against ALL.cocci, not unused.cocci. We thus assert (to the extent that we have test coverage) that this concatenation doesn't change the expected results of running these rules. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 340a4cb commit d0e624a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

Makefile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,29 @@ SPATCH_TEST_FLAGS =
13061306
# COMPUTE_HEADER_DEPENDENCIES=no this will be unset too.
13071307
SPATCH_USE_O_DEPENDENCIES = YesPlease
13081308

1309+
# Set SPATCH_CONCAT_COCCI to concatenate the contrib/cocci/*.cocci
1310+
# files into a single contrib/cocci/ALL.cocci before running
1311+
# "coccicheck".
1312+
#
1313+
# Pros:
1314+
#
1315+
# - Speeds up a one-shot run of "make coccicheck", as we won't have to
1316+
# parse *.[ch] files N times for the N *.cocci rules
1317+
#
1318+
# Cons:
1319+
#
1320+
# - Will make incremental development of *.cocci slower, as
1321+
# e.g. changing strbuf.cocci will re-run all *.cocci.
1322+
#
1323+
# - Makes error and performance analysis harder, as rules will be
1324+
# applied from a monolithic ALL.cocci, rather than
1325+
# e.g. strbuf.cocci. To work around this either undefine this, or
1326+
# generate a specific patch, e.g. this will always use strbuf.cocci,
1327+
# not ALL.cocci:
1328+
#
1329+
# make contrib/coccinelle/strbuf.cocci.patch
1330+
SPATCH_CONCAT_COCCI = YesPlease
1331+
13091332
# Rebuild 'coccicheck' if $(SPATCH), its flags etc. change
13101333
TRACK_SPATCH_DEFINES =
13111334
TRACK_SPATCH_DEFINES += $(SPATCH)
@@ -3158,9 +3181,12 @@ check: $(GENERATED_H)
31583181
exit 1; \
31593182
fi
31603183

3184+
COCCI_GEN_ALL = .build/contrib/coccinelle/ALL.cocci
31613185
COCCI_GLOB = $(wildcard contrib/coccinelle/*.cocci)
31623186
COCCI_RULES_TRACKED = $(COCCI_GLOB:%=.build/%)
3187+
COCCI_RULES_TRACKED_NO_PENDING = $(filter-out %.pending.cocci,$(COCCI_RULES_TRACKED))
31633188
COCCI_RULES =
3189+
COCCI_RULES += $(COCCI_GEN_ALL)
31643190
COCCI_RULES += $(COCCI_RULES_TRACKED)
31653191
COCCI_NAMES =
31663192
COCCI_NAMES += $(COCCI_RULES:.build/contrib/coccinelle/%.cocci=%)
@@ -3195,6 +3221,10 @@ $(COCCI_RULES_TRACKED): .build/% : %
31953221
$(call mkdir_p_parent_template)
31963222
$(QUIET_GEN) >$@
31973223

3224+
$(COCCI_GEN_ALL): $(COCCI_RULES_TRACKED_NO_PENDING)
3225+
$(call mkdir_p_parent_template)
3226+
$(QUIET_SPATCH_CAT)cat $^ >$@
3227+
31983228
ifeq ($(COMPUTE_HEADER_DEPENDENCIES),no)
31993229
SPATCH_USE_O_DEPENDENCIES =
32003230
endif
@@ -3251,7 +3281,11 @@ COCCI_TEST_RES_GEN = $(addprefix .build/,$(COCCI_TEST_RES))
32513281
$(COCCI_TEST_RES_GEN): GIT-SPATCH-DEFINES
32523282
$(COCCI_TEST_RES_GEN): .build/%.res : %.c
32533283
$(COCCI_TEST_RES_GEN): .build/%.res : %.res
3284+
ifdef SPATCH_CONCAT_COCCI
3285+
$(COCCI_TEST_RES_GEN): .build/contrib/coccinelle/tests/%.res : $(COCCI_GEN_ALL)
3286+
else
32543287
$(COCCI_TEST_RES_GEN): .build/contrib/coccinelle/tests/%.res : contrib/coccinelle/%.cocci
3288+
endif
32553289
$(call mkdir_p_parent_template)
32563290
$(QUIET_SPATCH_TEST)$(SPATCH) $(SPATCH_TEST_FLAGS) \
32573291
--very-quiet --no-show-diff \
@@ -3264,7 +3298,11 @@ $(COCCI_TEST_RES_GEN): .build/contrib/coccinelle/tests/%.res : contrib/coccinell
32643298
coccicheck-test: $(COCCI_TEST_RES_GEN)
32653299

32663300
coccicheck: coccicheck-test
3301+
ifdef SPATCH_CONCAT_COCCI
3302+
coccicheck: contrib/coccinelle/ALL.cocci.patch
3303+
else
32673304
coccicheck: $(COCCICHECK_PATCHES_INTREE)
3305+
endif
32683306

32693307
# See contrib/coccinelle/README
32703308
coccicheck-pending: coccicheck-test

contrib/coccinelle/README

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,16 @@ Git-specific tips & things to know about how we run "spatch":
5757

5858
To disable this behavior use the "SPATCH_USE_O_DEPENDENCIES=NoThanks"
5959
flag.
60+
61+
* To speed up our rules the "make coccicheck" target will by default
62+
concatenate all of the *.cocci files here into an "ALL.cocci", and
63+
apply it to each source file.
64+
65+
This makes the run faster, as we don't need to run each rule
66+
against each source file. See the Makefile for further discussion,
67+
this behavior can be disabled with "SPATCH_CONCAT_COCCI=".
68+
69+
But since they're concatenated any <id> in the <rulname> (e.g. "@
70+
my_name", v.s. anonymous "@@") needs to be unique across all our
71+
*.cocci files. You should only need to name rules if other rules
72+
depend on them (currently only one rule is named).

0 commit comments

Comments
 (0)