Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge tag llvmorg-17.0.0-rc4 into rustc/17.0-2023-07-29 #151

Merged
merged 93 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
c6d6417
[compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
jrtc27 Aug 22, 2023
2e17e9e
[RISCV] Check type size for lax conversions between RVV builtin types…
topperc Aug 21, 2023
4d5feaf
[OpenMP][OMPT] Fix reported target pointer for data alloc callback
mhalk Aug 16, 2023
1d54dc2
[OpenMP][OMPT] Fix `target enter data` callback ordering & reported d…
mhalk Aug 22, 2023
6d0ff3d
[CGCall][RISCV] Handle function calls with parameter of RVV tuple type
eopXD Aug 15, 2023
7dbb49a
[Coroutines] [CoroElide] Don't think exceptional terminator don't lea…
ChuanqiXu9 Aug 23, 2023
a4bf0d9
[BOLT][Instrumentation] Keep profile open in WatchProcess
treapster Jul 4, 2023
1856972
[MachineLICM][WinEH] Don't hoist register reloads out of funclets
kalle-llvm Aug 13, 2023
dcb7bcf
clang: Fix x86-no-gather-no-scatter.cpp on macOS after 993bdb047c90e9
nico Aug 18, 2023
f1d5ea3
[clang] Set FP options in Sema when instantiating CompoundStmt
spavloff Aug 21, 2023
e54f483
[clang] Run test for concrete target
spavloff Aug 21, 2023
5db0d77
Finish renaming getOperandSegmentSizeAttr() from `operand_segment_siz…
joker-eph Aug 9, 2023
67dca9d
Fix MLIR build failure: error: no member named 'getValue' in 'mlir::O…
joker-eph Aug 20, 2023
0d8fd07
Fix some missing fully qualified namespaces in MLIR TableGen generator
joker-eph Aug 22, 2023
c5f0c32
Fix MLIR pass manager initialization: hash the pass pipeline to detec…
joker-eph Aug 22, 2023
69946c8
Fix MSAN error: use of unitialized value when hashing the MLIR pass m…
joker-eph Aug 22, 2023
a95298a
Fix canonicalizer to copy the entire GreedyRewriteConfig instead of s…
joker-eph Aug 9, 2023
5e47fe1
Fix ODS verifier emission for DerivedAttr when Properties are enabled
joker-eph Aug 23, 2023
4b414e5
Fix regression of D157680
XinWang10 Aug 18, 2023
01f7134
[libc++] Fix problems with GCC 13 and switch to it in the CI
philnik777 Aug 14, 2023
231dab0
[libc++] Move header_information.py up from tests
ian-twilightcoder Aug 10, 2023
ae49840
[libc++][Modules] Remove unnecessary `requires` from the module map
ian-twilightcoder Aug 8, 2023
5e2c522
[libc++][Modules] Generate the __std_clang_module header
ian-twilightcoder Aug 9, 2023
0521244
[libc++][Modules] Simplify the __std_clang_module header generation
ian-twilightcoder Aug 17, 2023
f63cdbc
[libc++][ranges] Fix `ranges::to` test.
var-const Jul 27, 2023
4114813
[libc++] Increase the constexpr steps limit on some `bitset` tests.
var-const Jul 27, 2023
2641da8
[libc++][Modules] locale fails to compile with clang modules when _LI…
ian-twilightcoder Aug 23, 2023
f05226d
[C++20] [Coroutines] Mark await_suspend as noinline if the awaiter is…
ChuanqiXu9 Aug 14, 2023
6998ecd
[NFC] [C++20] [Coroutines] Mention the side effect of a fix may bring…
ChuanqiXu9 Aug 24, 2023
51844c6
[BOLT][Instrumentation] Fix indirect call profile in PIE
treapster Jun 29, 2023
3670e6a
[BOLT][Instrumentation] Add test for append-pid option
treapster Jun 23, 2023
77d7f7d
[PowerPC] Exclude frexp(long double) on linux
lei137 Aug 23, 2023
ef7421f
[AArch64] Check opcode before trying to extract register from operand
dtellenbach Aug 23, 2023
0ec768e
[libc++] Fix GNU/Hurd build
sthibaul Aug 25, 2023
e91ad6b
[Driver] Add PIE support on Solaris
rorth Aug 18, 2023
baae3c3
Revert "[clang] Run test for concrete target"
tru Aug 28, 2023
0638df0
Revert "[clang] Set FP options in Sema when instantiating CompoundStmt"
tru Aug 28, 2023
ed108ee
[Driver,X86] Ignore -mfpmath= for assembler input
MaskRay Aug 28, 2023
da76a22
[llvm-rc] Continue to use Argv[0] to resolve executable path
amykhuang Aug 25, 2023
9fbdf9f
Fix up release note; NFC
AaronBallman Aug 29, 2023
a734685
[llvm-exegesis] Use mmap2 when mmap is unavailable to fix riscv32 build
kraj Aug 25, 2023
5d2eda7
[ConstraintElim] fix crash with large constants in mul nsw
erikdesjardins Aug 25, 2023
acc6a14
[Tests][ConstraintElim] autogen newly-added case in large-constant-in…
erikdesjardins Aug 25, 2023
94af834
[X86][BF16] Lower FP_EXTEND for vector types under AVX512BF16
phoebewang Aug 28, 2023
d469d5c
Reland "[clang-repl] Adapt to the recent dylib-related changes in ORC."
vgvassilev Aug 29, 2023
8c5c652
[clang][ExprConstant] Fix crash on uninitialized base class subobject
hazohelet Aug 8, 2023
2c9feb0
[clang-format] Fix braced initializer with templated base class
Aug 1, 2023
4dea033
[clang] Update NumFunctionDeclBits for FunctionDeclBitfields
danix800 Aug 17, 2023
cf16374
[asan] Intercept atoll and strtoll on Windows
MaskRay Aug 27, 2023
dd230ef
[sanitizer] Intercept glibc 2.38 __isoc23_* functions
MaskRay Aug 28, 2023
c8abecd
[compiler-rt] [test] Adjust an XFAIL for strtoll_strict.c for MinGW t…
mstorsjo Aug 28, 2023
b6cf21f
[msan] Fix compilation on non-glibc
brooksdavis Aug 29, 2023
9afe667
Function multi-versioning: disable ifunc for ELF targets other than g…
MaskRay Aug 14, 2023
993681f
[RISCV] Add test case showing vmerge fold miscompile with tail policy
lukel97 Aug 17, 2023
6f1974e
[RISCV] Don't relax policy to ta when vmerge's VL shrinks during folding
lukel97 Aug 17, 2023
1440745
[clang-format] Exclude kw_decltype in RemoveParentheses
owenca Aug 17, 2023
5a60d71
[CMake] Add a few more missing dependencies on ClangDriverOptions
jroelofs Aug 15, 2023
b8444b6
Silently accept -Wgnu-empty-initializer
AaronBallman Aug 10, 2023
b8ea78c
workflows: Fix libclang-abi test after update to use download-artifac…
tstellar Aug 28, 2023
cfd6f0f
[clang] Set FP options in Sema when instantiating CompoundStmt
spavloff Aug 21, 2023
78447a8
[clang] Run test for concrete target
spavloff Aug 21, 2023
45c677d
[clang][test] Make check pattern shorter
spavloff Aug 30, 2023
08d720d
[PowerPC] Update V17.0.0 release notes
lei137 Aug 25, 2023
ad5ed49
[mlir][memref] Fix crash in SubViewReturnTypeCanonicalizer
matthias-springer Aug 25, 2023
94f348b
[mlir][math] Modify math.powf to handle negative bases.
bviyer Aug 25, 2023
cc7e24c
[mlir] Fix crash when adding nested dialect extensions
matthias-springer Aug 26, 2023
b66219d
[mlir] Fix infinite recursion in alias initializer
zero9178 Aug 26, 2023
1b11137
[RISCV] Fix assertion failure when zcmp extension is enabled.
quic-garvgupt Aug 30, 2023
4a999da
[lldb][windows] _wsopen_s does not accept bits other than `_S_IREAD |…
yshui Aug 30, 2023
078e20c
[libc++][format] Fixes out of bounds access.
mordante Aug 26, 2023
844f1e5
[AArch64] Add Defs=[NZCV] to MTE loop pseudos.
statham-arm Aug 21, 2023
2b3336f
[PowerPC][lld] Account for additional X-Forms -> D-Form/DS-Forms load…
amy-kwan Aug 30, 2023
b879e0f
[RISCV] Prevent tryToFoldBNEOnCmpXchgResult from deleting AND if it h…
topperc Aug 28, 2023
dc2d2f9
[clangd] Respect IWYU keep pragma for standard headers.
hokein Jul 31, 2023
a0de0b4
[X86][BF16] Add test coverage for AVX-NE-CONVERT
phoebewang Aug 29, 2023
e9eaf3d
[X86][BF16] Lower FP_ROUND for vector types under AVX512BF16
phoebewang Aug 29, 2023
c138c8a
[UBSan] Disable the function and kcfi sanitizers on an execute-only t…
MaggieYingYi Aug 29, 2023
051aa17
[Driver] Adjust -fsanitize=function & -mexecute-only interop after D1…
MaskRay Aug 30, 2023
a612cb0
[sanitizer][test] -std=c2x instead of -std=c23
MaskRay Aug 31, 2023
6a562bb
[Tooling/Inclusion] Add std::range symbols in the mapping.
hokein Jul 28, 2023
466677b
[llvm-windres] Implement the windres flag --use-temp-file
mstorsjo Aug 30, 2023
ca372df
[AArch64] Fix arm neon vstx lane memVT size
Aug 31, 2023
e04acab
[Driver] Report warnings for unclaimed TargetSpecific options for ass…
MaskRay Sep 1, 2023
ecea6d6
[CodeGen] First check the kind and then the llvm::Function properties.
vgvassilev Sep 1, 2023
7150c6d
[sanitizer] scanf interceptor: fix write size for %mc/%mC/%mS
MaskRay Aug 28, 2023
175a130
[NFC][Clang] Fix static analyzer concern about null value dereference
elizabethandrews Aug 14, 2023
c2c9c0f
[clang] Construct ExprRequirement with SubstitutionDiagnostic on Subs…
zyn0217 Aug 16, 2023
5b4513a
[clang][clangd] Ensure the stack bottom before building AST
zyn0217 Aug 28, 2023
9597525
Revert "[clang][Docs] Added release note for D142609"
hazohelet Sep 4, 2023
ae9c45b
[JumpThreading][NFC] Pre-commit for invalid LVI.
dianqk Sep 3, 2023
dccf183
[JumpThreading] Invalidate LVI after `combineMetadataForCSE`.
dianqk Sep 3, 2023
092b6c5
[mlir][nfc] Allow ops to have operands/attributes named `context`.
chsigg Aug 30, 2023
0537f63
Merge tag 'llvmorg-17.0.0-rc4' of https://github.com/llvm/llvm-projec…
djkoloski Sep 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/libclang-abi-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,12 @@ jobs:
uses: actions/download-artifact@v3
with:
name: build-baseline
path: build-baseline
- name: Download latest
uses: actions/download-artifact@v3
with:
name: build-latest
path: build-latest

- name: Install abi-compliance-checker
run: sudo apt-get install abi-compliance-checker
Expand Down
5 changes: 3 additions & 2 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1844,8 +1844,9 @@ void RewriteInstance::adjustCommandLineOptions() {
exit(1);
}

if (opts::ReorderFunctions != ReorderFunctions::RT_NONE &&
!opts::HotText.getNumOccurrences()) {
if (opts::Instrument ||
(opts::ReorderFunctions != ReorderFunctions::RT_NONE &&
!opts::HotText.getNumOccurrences())) {
opts::HotText = true;
} else if (opts::HotText && !BC->HasRelocations) {
errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n";
Expand Down
24 changes: 24 additions & 0 deletions bolt/runtime/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ int memcmp(const void *s1, const void *s2, size_t n) {
// Anonymous namespace covering everything but our library entry point
namespace {

// Get the difference between runtime addrress of .text section and
// static address in section header table. Can be extracted from arbitrary
// pc value recorded at runtime to get the corresponding static address, which
// in turn can be used to search for indirect call description. Needed because
// indirect call descriptions are read-only non-relocatable data.
uint64_t getTextBaseAddress() {
uint64_t DynAddr;
uint64_t StaticAddr;
__asm__ volatile("leaq __hot_end(%%rip), %0\n\t"
"movabsq $__hot_end, %1\n\t"
: "=r"(DynAddr), "=r"(StaticAddr));
return DynAddr - StaticAddr;
}

constexpr uint32_t BufSize = 10240;

#define _STRINGIFY(x) #x
Expand Down Expand Up @@ -458,6 +472,16 @@ uint64_t __lseek(uint64_t fd, uint64_t pos, uint64_t whence) {
return ret;
}

int __ftruncate(uint64_t fd, uint64_t length) {
int ret;
__asm__ __volatile__("movq $77, %%rax\n"
"syscall\n"
: "=a"(ret)
: "D"(fd), "S"(length)
: "cc", "rcx", "r11", "memory");
return ret;
}

int __close(uint64_t fd) {
uint64_t ret;
__asm__ __volatile__("movq $3, %%rax\n"
Expand Down
33 changes: 23 additions & 10 deletions bolt/runtime/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class BumpPtrAllocator {
/// __bolt_instr_setup, our initialization routine.
BumpPtrAllocator *GlobalAlloc;

// Base address which we substract from recorded PC values when searching for
// indirect call description entries. Needed because indCall descriptions are
// mapped read-only and contain static addresses. Initialized in
// __bolt_instr_setup.
uint64_t TextBaseAddress = 0;

// Storage for GlobalAlloc which can be shared if not using
// instrumentation-file-append-pid.
void *GlobalMetadataStorage;
Expand Down Expand Up @@ -1389,7 +1395,7 @@ void visitIndCallCounter(IndirectCallHashTable::MapEntry &Entry,
const IndCallDescription *CallsiteDesc =
&Ctx->IndCallDescriptions[CallsiteID];
const IndCallTargetDescription *TargetDesc =
Ctx->lookupIndCallTarget(Entry.Key);
Ctx->lookupIndCallTarget(Entry.Key - TextBaseAddress);
if (!TargetDesc) {
DEBUG(report("Failed to lookup indirect call target\n"));
char LineBuf[BufSize];
Expand Down Expand Up @@ -1515,20 +1521,22 @@ extern "C" void __bolt_instr_clear_counters() {
/// on demand.
///
extern "C" void __attribute((force_align_arg_pointer))
__bolt_instr_data_dump() {
__bolt_instr_data_dump(int FD) {
// Already dumping
if (!GlobalWriteProfileMutex->acquire())
return;

int ret = __lseek(FD, 0, SEEK_SET);
assert(ret == 0, "Failed to lseek!");
ret = __ftruncate(FD, 0);
assert(ret == 0, "Failed to ftruncate!");
BumpPtrAllocator HashAlloc;
HashAlloc.setMaxSize(0x6400000);
ProfileWriterContext Ctx = readDescriptions();
Ctx.CallFlowTable = new (HashAlloc, 0) CallFlowHashTable(HashAlloc);

DEBUG(printStats(Ctx));

int FD = openProfile();

BumpPtrAllocator Alloc;
Alloc.setMaxSize(0x6400000);
const uint8_t *FuncDesc = Ctx.FuncDescriptions;
Expand All @@ -1544,7 +1552,6 @@ __bolt_instr_data_dump() {
Ctx.CallFlowTable->forEachElement(visitCallFlowEntry, FD, &Ctx);

__fsync(FD);
__close(FD);
__munmap(Ctx.MMapPtr, Ctx.MMapSize);
__close(Ctx.FileDesc);
HashAlloc.destroy();
Expand All @@ -1557,6 +1564,7 @@ __bolt_instr_data_dump() {
void watchProcess() {
timespec ts, rem;
uint64_t Ellapsed = 0ull;
int FD = openProfile();
uint64_t ppid;
if (__bolt_instr_wait_forks) {
// Store parent pgid
Expand All @@ -1568,7 +1576,7 @@ void watchProcess() {
ppid = __getppid();
if (ppid == 1) {
// Parent already dead
__bolt_instr_data_dump();
__bolt_instr_data_dump(FD);
goto out;
}
}
Expand All @@ -1581,21 +1589,22 @@ void watchProcess() {
// so no need for us to keep dumping.
if (__kill(ppid, 0) < 0) {
if (__bolt_instr_no_counters_clear)
__bolt_instr_data_dump();
__bolt_instr_data_dump(FD);
break;
}

if (++Ellapsed < __bolt_instr_sleep_time)
continue;

Ellapsed = 0;
__bolt_instr_data_dump();
__bolt_instr_data_dump(FD);
if (__bolt_instr_no_counters_clear == false)
__bolt_instr_clear_counters();
}

out:;
DEBUG(report("My parent process is dead, bye!\n"));
__close(FD);
__exit(0);
}

Expand All @@ -1606,6 +1615,7 @@ extern "C" void __bolt_instr_indirect_tailcall();
extern "C" void __attribute((force_align_arg_pointer)) __bolt_instr_setup() {
__bolt_ind_call_counter_func_pointer = __bolt_instr_indirect_call;
__bolt_ind_tailcall_counter_func_pointer = __bolt_instr_indirect_tailcall;
TextBaseAddress = getTextBaseAddress();

const uint64_t CountersStart =
reinterpret_cast<uint64_t>(&__bolt_instr_locations[0]);
Expand Down Expand Up @@ -1691,8 +1701,11 @@ extern "C" __attribute((naked)) void __bolt_instr_start()
/// This is hooking into ELF's DT_FINI
extern "C" void __bolt_instr_fini() {
__bolt_fini_trampoline();
if (__bolt_instr_sleep_time == 0)
__bolt_instr_data_dump();
if (__bolt_instr_sleep_time == 0) {
int FD = openProfile();
__bolt_instr_data_dump(FD);
__close(FD);
}
DEBUG(report("Finished.\n"));
}

Expand Down
3 changes: 3 additions & 0 deletions bolt/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
if config.gnu_ld:
config.available_features.add("gnu_ld")

if lit.util.which("fuser"):
config.available_features.add("fuser")

llvm_config.use_default_substitutions()

llvm_config.config.environment["CLANG"] = config.bolt_clang
Expand Down
168 changes: 168 additions & 0 deletions bolt/test/runtime/instrumentation-indirect-2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// Check that indirect call hash tables properly register multiple calls,
// and that calls from different processes don't get mixed up when using
// --instrumentation-file-append-pid.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

__attribute__((noinline)) void funcA(int pid) { printf("funcA %d\n", pid); }
__attribute__((noinline)) void funcB(int pid) { printf("funcB %d\n", pid); }
__attribute__((noinline)) void funcC(int pid) { printf("funcC %d\n", pid); }
__attribute__((noinline)) void funcD(int pid) { printf("funcD %d\n", pid); }
__attribute__((noinline)) void funcE(int pid) { printf("funcE %d\n", pid); }
__attribute__((noinline)) void funcF(int pid) { printf("funcF %d\n", pid); }
__attribute__((noinline)) void funcG(int pid) { printf("funcG %d\n", pid); }
__attribute__((noinline)) void funcH(int pid) { printf("funcH %d\n", pid); }
__attribute__((noinline)) void funcI(int pid) { printf("funcI %d\n", pid); }
__attribute__((noinline)) void funcJ(int pid) { printf("funcJ %d\n", pid); }
__attribute__((noinline)) void funcK(int pid) { printf("funcK %d\n", pid); }
__attribute__((noinline)) void funcL(int pid) { printf("funcL %d\n", pid); }
__attribute__((noinline)) void funcM(int pid) { printf("funcM %d\n", pid); }
__attribute__((noinline)) void funcN(int pid) { printf("funcN %d\n", pid); }
__attribute__((noinline)) void funcO(int pid) { printf("funcO %d\n", pid); }
__attribute__((noinline)) void funcP(int pid) { printf("funcP %d\n", pid); }

int main() {

void (*funcs[])(int) = {funcA, funcB, funcC, funcD, funcE, funcF,
funcG, funcH, funcI, funcJ, funcK, funcL,
funcM, funcN, funcO, funcP};
int i;

switch (fork()) {
case -1:
printf("Failed to fork!\n");
exit(-1);
break;
case 0:
i = 0;
break;
default:
i = 1;
break;
}
int pid = getpid();
for (; i < sizeof(funcs) / sizeof(void *); i += 2) {
funcs[i](pid);
}

return 0;
}
/*
REQUIRES: system-linux,shell,fuser

RUN: %clang %cflags %s -o %t.exe -Wl,-q -pie -fpie

RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \
RUN: --conservative-instrumentation -o %t.instrumented_conservative \
RUN: --instrumentation-sleep-time=1 --instrumentation-no-counters-clear \
RUN: --instrumentation-wait-forks

# Instrumented program needs to finish returning zero
# Both output and profile must contain all 16 functions
RUN: %t.instrumented_conservative > %t.output
# Wait for profile and output to be fully written
RUN: bash %S/wait_file.sh %t.output
RUN: bash %S/wait_file.sh %t.fdata
RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT
RUN: cat %t.fdata | FileCheck %s --check-prefix=CHECK-COMMON-PROF

CHECK-OUTPUT-DAG: funcA
CHECK-OUTPUT-DAG: funcB
CHECK-OUTPUT-DAG: funcC
CHECK-OUTPUT-DAG: funcD
CHECK-OUTPUT-DAG: funcE
CHECK-OUTPUT-DAG: funcF
CHECK-OUTPUT-DAG: funcG
CHECK-OUTPUT-DAG: funcH
CHECK-OUTPUT-DAG: funcI
CHECK-OUTPUT-DAG: funcJ
CHECK-OUTPUT-DAG: funcK
CHECK-OUTPUT-DAG: funcL
CHECK-OUTPUT-DAG: funcM
CHECK-OUTPUT-DAG: funcN
CHECK-OUTPUT-DAG: funcO
CHECK-OUTPUT-DAG: funcP

CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1
CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1

RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t \
RUN: --instrumentation-file-append-pid \
RUN: -o %t.instrumented

RUN: %t.instrumented > %t.output
# Wait till output is fully written in case child outlives parent
RUN: bash %S/wait_file.sh %t.output
# Make sure all functions were called
RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT

RUN: child_pid=$(cat %t.output | grep funcA | awk '{print $2;}')
RUN: par_pid=$(cat %t.output | grep funcB | awk '{print $2;}')

RUN: bash %S/wait_file.sh %t.$child_pid.fdata
RUN: bash %S/wait_file.sh %t.$par_pid.fdata

RUN: mv %t.$child_pid.fdata %t.child.fdata
RUN: mv %t.$par_pid.fdata %t.parent.fdata

# Instrumented binary must produce two profiles with only local calls
# recorded. Functions called only in child should not appear in parent's
# process and vice versa.
RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-CHILD
RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-NOCHILD
RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-PARENT
RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-NOPARENT

CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1

CHECK-NOCHILD-NOT: funcB
CHECK-NOCHILD-NOT: funcD
CHECK-NOCHILD-NOT: funcF
CHECK-NOCHILD-NOT: funcH
CHECK-NOCHILD-NOT: funcJ
CHECK-NOCHILD-NOT: funcL
CHECK-NOCHILD-NOT: funcN
CHECK-NOCHILD-NOT: funcP

CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1

CHECK-NOPARENT-NOT: funcA
CHECK-NOPARENT-NOT: funcC
CHECK-NOPARENT-NOT: funcE
CHECK-NOPARENT-NOT: funcG
CHECK-NOPARENT-NOT: funcI
CHECK-NOPARENT-NOT: funcK
CHECK-NOPARENT-NOT: funcM
CHECK-NOPARENT-NOT: funcO

*/
Loading