-
Notifications
You must be signed in to change notification settings - Fork 98
Expand file tree
/
Copy pathpgo.mk
More file actions
103 lines (97 loc) · 4.91 KB
/
pgo.mk
File metadata and controls
103 lines (97 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#***************************************************************************************
# Copyright (c) 2020-2026 Institute of Computing Technology, Chinese Academy of Sciences
# Copyright (c) 2025-2026 Beijing Institute of Open Source Chip
#
# DiffTest is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#
# See the Mulan PSL v2 for more details.
#***************************************************************************************
PGO_MAX_CYCLE ?= 100000
PGO_EMU_ARGS ?= --no-diff
LLVM_BOLT ?= $(shell readlink -f `command -v llvm-bolt 2> /dev/null`)
# We use readlink -f to get the absolute path of llvm-bolt, it's
# needed since we use argv[0]/../lib/libbolt_rt_instr.a as the path
# to find the runtime library inside llvm-bolt. It's a workaround
# for LLVM before commit abc2eae682("[BOLT] Enable standalone build (llvm#97130)").
# Ref: https://github.com/llvm/llvm-project/blob/release/18.x/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp#L33
# Ref: https://github.com/llvm/llvm-project/blob/release/18.x/bolt/tools/driver/llvm-bolt.cpp#L187
PGO_BOLT ?= $(shell if [ -x "$(LLVM_BOLT)" ]; then echo 1; else echo 0; fi)
PGO_EMU_DIR ?= $(BUILD_DIR)
PGO_DIR = $(PGO_EMU_DIR)/pgo
PGO_RUN_OPT ?= -i $(PGO_WORKLOAD) --max-cycles=$(PGO_MAX_CYCLE) $(PGO_EMU_ARGS)
PGO_RUN_OPT += 1>$(PGO_DIR)/`date +%s`.log \
2>$(PGO_DIR)/`date +%s`.err
pgo-build:
ifeq ($(and $(PGO_WORKLOAD),$(PGO_CLEAN_OBJ),$(PGO_BUILD_TARGET),$(PGO_TARGET)),)
$(error PGO_WORKLOAD, PGO_CLEAN_OBJ, PGO_BUILD_TARGET and PGO_TARGET must all be set)
endif
ifneq ($(PGO_BOLT),1)
@echo "If available, please use install llvm-bolt for much reduced PGO build time."
@echo "Building PGO profile..."
@stat $(PGO_WORKLOAD) > /dev/null
@$(MAKE) $(PGO_CLEAN_OBJ)
@mkdir -p $(PGO_DIR)
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
@$(MAKE) $(PGO_BUILD_TARGET) \
PGO_CFLAGS="-fprofile-generate=$(PGO_DIR)" \
PGO_LDFLAGS="-fprofile-generate=$(PGO_DIR)"
@echo "Training emu with PGO Workload..."
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
$(PGO_TARGET) $(PGO_RUN_OPT)
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
ifdef LLVM_PROFDATA
# When using LLVM's profile-guided optimization, the raw data can not
# directly be used in -fprofile-use. We need to use a specific version of
# llvm-profdata. This happens when verilator compiled with CC=clang
# CXX=clang++. In this case, we should add LLVM_PROFDATA=llvm-profdata
# when calling make. For GCC, this step should be skipped. Also, some
# machines may have multiple versions of llvm-profdata. So please never
# add default value for LLVM_PROFDATA unless we have a proper way to probe
# the compiler and the corresponding llvm-profdata value.
$(LLVM_PROFDATA) merge $(PGO_DIR)/*.profraw -o $(PGO_DIR)/default.profdata
else # ifdef LLVM_PROFDATA
@echo ""
@echo "----------------------- NOTICE BEGIN -----------------------"
@echo "If your verilator is compiled with LLVM, please don't forget"
@echo "to add LLVM_PROFDATA=llvm-profdata when calling make."
@echo ""
@echo "If your verilator is compiled with GCC, please ignore this"
@echo "message and NEVER adding LLVM_PROFDATA when calling make."
@echo "----------------------- NOTICE END -----------------------"
@echo ""
endif # ifdef LLVM_PROFDATA
@echo "Building emu with PGO profile..."
@$(MAKE) $(PGO_CLEAN_OBJ)
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
@$(MAKE) $(PGO_BUILD_TARGET) \
PGO_CFLAGS="-fprofile-use=$(PGO_DIR)" \
PGO_LDFLAGS="-fprofile-use=$(PGO_DIR)"
else # ifneq ($(PGO_BOLT),1)
@echo "Building emu..."
@$(MAKE) $(PGO_BUILD_TARGET) PGO_LDFLAGS="-Wl,--emit-relocs -fuse-ld=bfd"
@mv $(PGO_TARGET) $(PGO_TARGET).pre-bolt
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
@echo "Training emu with PGO Workload..."
@mkdir -p $(PGO_DIR)
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)
@((perf record -j any,u -o $(PGO_DIR)/perf.data -- sh -c "\
$(PGO_TARGET).pre-bolt $(PGO_RUN_OPT) || true") && \
(perf2bolt -p=$(PGO_DIR)/perf.data -o=$(PGO_DIR)/perf.fdata $(PGO_TARGET).pre-bolt || true)) || \
(echo -e "\033[31mlinux-perf is not available, fallback to instrumentation-based PGO\033[0m" && \
$(LLVM_BOLT) $(PGO_TARGET).pre-bolt \
-instrument --instrumentation-file=$(PGO_DIR)/perf.fdata \
-o $(PGO_DIR)/emu.instrumented && \
($(PGO_DIR)/emu.instrumented $(PGO_RUN_OPT) || true))
@echo "Processing BOLT profile data..."
@$(LLVM_BOLT) $(PGO_TARGET).pre-bolt -o $(PGO_TARGET) -data=$(PGO_DIR)/perf.fdata -reorder-blocks=ext-tsp || \
(echo -e "\033[31mBOLT optimization failed, fallback to non-PGO build\033[0m" && \
mv $(PGO_TARGET).pre-bolt $(PGO_TARGET))
endif # ifneq ($(PGO_BOLT),1)
@sync -d $(BUILD_DIR) -d $(PGO_EMU_DIR)