summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile94
1 files changed, 94 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 2b78f7be2..3cc5f8377 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,6 @@
.PHONY: all build install doc clean html deb pkg bintar sdist
+.PHONY: profile-build profile-rgl-time profile-rgl-memory profile-rgl-clean
+.PHONY: bench-build bench-rgl bench-rgl-pre-pmcfg bench-rgl-clean
# This gets the numeric part of the version from the cabal file
VERSION=$(shell sed -ne "s/^version: *\([0-9.]*\).*/\1/p" gf.cabal)
@@ -18,6 +20,51 @@ else
endif
endif
+# Profiling configuration.
+#
+# The profiling targets intentionally use Stack even when the normal build falls
+# back to cabal, because Stack's --work-dir makes it easy to keep profiled and
+# unprofiled build products separate. The default RGL target is German, which
+# is complex and a good compiler stress test; override
+# RGL_PROFILE_MODULES or RGL_PROFILE_GF_OPTIONS for different experiments.
+PROFILE_STACK_WORK ?= .stack-work-profile
+PROFILE_GHC_OPTIONS ?= -fprof-auto -fprof-cafs
+PROFILE_DIR ?= $(CURDIR)/profile
+
+RGL_DIR ?= ../gf-rgl
+RGL_PROFILE_DIR ?= $(PROFILE_DIR)/rgl
+RGL_PROFILE_GFO_DIR ?= $(RGL_PROFILE_DIR)/gfo
+RGL_PROFILE_PGF_DIR ?= $(RGL_PROFILE_DIR)/pgf
+RGL_PROFILE_MODULES ?= $(RGL_DIR)/src/german/LangGer.gf
+RGL_PROFILE_IMPORT_DIRS ?= $(RGL_DIR)/src/api
+RGL_PROFILE_IMPORT_OPTIONS = $(foreach dir,$(RGL_PROFILE_IMPORT_DIRS),-i $(dir))
+RGL_PROFILE_GF_OPTIONS ?= --make --quiet --src --preproc=mkPresent --gf-lib-path=$(RGL_PROFILE_GFO_DIR) --gfo-dir=$(RGL_PROFILE_GFO_DIR) --output-dir=$(RGL_PROFILE_PGF_DIR) --name=RGLProfile $(RGL_PROFILE_IMPORT_OPTIONS)
+RGL_PROFILE_GF = stack --stack-yaml $(CURDIR)/stack.yaml --work-dir $(PROFILE_STACK_WORK) exec --profile gf --
+
+RGL_TIME_STEM ?= $(RGL_PROFILE_DIR)/rgl-time
+RGL_MEMORY_STEM ?= $(RGL_PROFILE_DIR)/rgl-memory
+RGL_MEMORY_RTS ?= -hc
+RGL_HEAP_SAMPLE_INTERVAL ?= 0.1
+
+BENCH_STACK_WORK ?= $(PROFILE_STACK_WORK)
+BENCH_PROFILE_FLAGS ?= --profile
+BENCH_GHC_OPTIONS ?= $(PROFILE_GHC_OPTIONS)
+BENCH_TARGET ?= gf:bench:gf-compiler-bench
+BENCH_TASTY_OPTIONS ?=
+BENCH_PRE_PMCFG_FLAG ?= --flag gf:pre-pmcfg
+BENCH_PRE_PMCFG_STACK_WORK ?= .stack-work-profile-pre-pmcfg
+
+RGL_BENCH_DIR ?= $(PROFILE_DIR)/rgl-bench
+RGL_BENCH_GFO_DIR ?= $(RGL_BENCH_DIR)/gfo
+RGL_BENCH_PGF_DIR ?= $(RGL_BENCH_DIR)/pgf
+RGL_BENCH_NAME ?= RGLBench
+RGL_BENCH_MODULES ?=
+RGL_BENCH_IMPORT_DIRS ?= $(RGL_PROFILE_IMPORT_DIRS) $(RGL_DIR)/src/prelude
+RGL_BENCH_PRE_PMCFG_DIR ?= $(PROFILE_DIR)/rgl-bench-pre-pmcfg
+RGL_BENCH_PRE_PMCFG_NAME ?= RGLBenchPrePmcfg
+BENCH_RTS_OPTIONS ?= +RTS -T -RTS
+BENCH_STACK = stack --stack-yaml $(CURDIR)/stack.yaml --work-dir $(BENCH_STACK_WORK)
+
all: build
dist/setup-config: gf.cabal Setup.hs WebSetup.hs
@@ -28,6 +75,53 @@ endif
build: dist/setup-config
${CMD} ${CMD_PFX}build
+profile-build:
+ stack --work-dir $(PROFILE_STACK_WORK) build --profile --ghc-options "$(PROFILE_GHC_OPTIONS)"
+
+profile-rgl-time: profile-build
+ @test -n "$(RGL_PROFILE_MODULES)" || { echo "No RGL modules found. Set RGL_DIR or RGL_PROFILE_MODULES."; exit 1; }
+ @command -v ghc-prof-flamegraph >/dev/null || { echo "Missing ghc-prof-flamegraph."; exit 1; }
+ rm -rf $(RGL_PROFILE_GFO_DIR) $(RGL_PROFILE_PGF_DIR)
+ mkdir -p $(RGL_PROFILE_DIR) $(RGL_PROFILE_GFO_DIR) $(RGL_PROFILE_PGF_DIR)
+ rm -f $(RGL_TIME_STEM).prof $(RGL_TIME_STEM).svg $(RGL_TIME_STEM).log
+ $(RGL_PROFILE_GF) $(RGL_PROFILE_GF_OPTIONS) $(RGL_PROFILE_MODULES) +RTS -s -p -po$(RGL_TIME_STEM) -RTS > $(RGL_TIME_STEM).log 2>&1 || { tail -n 80 $(RGL_TIME_STEM).log; exit 1; }
+ ghc-prof-flamegraph $(RGL_TIME_STEM).prof --output $(RGL_TIME_STEM).svg
+
+profile-rgl-memory: profile-build
+ @test -n "$(RGL_PROFILE_MODULES)" || { echo "No RGL modules found. Set RGL_DIR or RGL_PROFILE_MODULES."; exit 1; }
+ @command -v hp2ps >/dev/null || { echo "Missing hp2ps."; exit 1; }
+ rm -rf $(RGL_PROFILE_GFO_DIR) $(RGL_PROFILE_PGF_DIR)
+ mkdir -p $(RGL_PROFILE_DIR) $(RGL_PROFILE_GFO_DIR) $(RGL_PROFILE_PGF_DIR)
+ rm -f $(RGL_MEMORY_STEM).hp $(RGL_MEMORY_STEM).ps $(RGL_MEMORY_STEM).aux $(RGL_MEMORY_STEM).tmp.ps $(RGL_MEMORY_STEM).log
+ $(RGL_PROFILE_GF) $(RGL_PROFILE_GF_OPTIONS) $(RGL_PROFILE_MODULES) +RTS -s $(RGL_MEMORY_RTS) -i$(RGL_HEAP_SAMPLE_INTERVAL) -po$(RGL_MEMORY_STEM) -RTS > $(RGL_MEMORY_STEM).log 2>&1 || { tail -n 80 $(RGL_MEMORY_STEM).log; exit 1; }
+ cd $(dir $(RGL_MEMORY_STEM)) && hp2ps $(notdir $(RGL_MEMORY_STEM)).hp
+ @if command -v gs >/dev/null 2>&1; then \
+ gs -q -dNOPAUSE -dBATCH -sOutputFile=$(RGL_MEMORY_STEM).tmp.ps -sDEVICE=ps2write -c "<</Orientation 1>> setpagedevice" -- $(RGL_MEMORY_STEM).ps && mv $(RGL_MEMORY_STEM).tmp.ps $(RGL_MEMORY_STEM).ps; \
+ else \
+ echo "Missing gs; leaving $(RGL_MEMORY_STEM).ps without orientation fix."; \
+ fi
+
+profile-rgl-clean:
+ rm -rf $(RGL_PROFILE_DIR)
+
+bench-build:
+ $(BENCH_STACK) build $(BENCH_TARGET) --bench --no-run-benchmarks $(BENCH_PROFILE_FLAGS) --ghc-options "$(BENCH_GHC_OPTIONS)"
+
+bench-rgl: bench-build
+ @test -d "$(RGL_DIR)" || { echo "Missing RGL_DIR: $(RGL_DIR)"; exit 1; }
+ rm -rf $(RGL_BENCH_GFO_DIR) $(RGL_BENCH_PGF_DIR)
+ mkdir -p $(RGL_BENCH_GFO_DIR) $(RGL_BENCH_PGF_DIR)
+ GF_BENCH_RGL_DIR="$(RGL_DIR)" GF_BENCH_NAME="$(RGL_BENCH_NAME)" GF_BENCH_GFO_DIR="$(RGL_BENCH_GFO_DIR)" GF_BENCH_PGF_DIR="$(RGL_BENCH_PGF_DIR)" GF_BENCH_MODULES="$(RGL_BENCH_MODULES)" GF_BENCH_IMPORT_DIRS="$(RGL_BENCH_IMPORT_DIRS)" $(BENCH_STACK) bench $(BENCH_TARGET) $(BENCH_PROFILE_FLAGS) --ghc-options "$(BENCH_GHC_OPTIONS)" --benchmark-arguments "$(BENCH_TASTY_OPTIONS) $(BENCH_RTS_OPTIONS)"; \
+ status=$$?; \
+ if test -f gf-compiler-bench.prof; then mv gf-compiler-bench.prof "$(RGL_BENCH_DIR)/gf-compiler-bench.prof"; fi; \
+ exit $$status
+
+bench-rgl-pre-pmcfg:
+ $(MAKE) bench-rgl BENCH_STACK_WORK="$(BENCH_PRE_PMCFG_STACK_WORK)" RGL_BENCH_DIR="$(RGL_BENCH_PRE_PMCFG_DIR)" RGL_BENCH_NAME="$(RGL_BENCH_PRE_PMCFG_NAME)" BENCH_PROFILE_FLAGS="$(BENCH_PROFILE_FLAGS) $(BENCH_PRE_PMCFG_FLAG)"
+
+bench-rgl-clean:
+ rm -rf $(RGL_BENCH_DIR) $(RGL_BENCH_PRE_PMCFG_DIR)
+
install:
ifeq ($(STACK),1)
stack install