1#!/bin/bash
2
3if [ $# -lt 1 ]; then
4  echo "Path to clang required!"
5  echo "Usage: update_thinlto_indirect_call_promotion_inputs.sh /path/to/updated/clang"
6  exit 1
7else
8  CLANG=$1
9fi
10
11# Remember current directory.
12CURDIR=$PWD
13
14# Allows the script to be invoked from other directories.
15OUTDIR=$(dirname $(realpath -s $0))
16cd $OUTDIR
17
18# Creates trivial header file to expose `global_func`.
19cat > lib.h << EOF
20void global_func();
21EOF
22
23# Creates lib.cc. `global_func` might call one of two indirect callees. One
24# callee has internal linkage and the other has external linkage.
25cat > lib.cc << EOF
26#include "lib.h"
27static void callee0() {}
28void callee1() {}
29typedef void (*FPT)();
30FPT calleeAddrs[] = {callee0, callee1};
31void global_func() {
32    FPT fp = nullptr;
33    fp = calleeAddrs[0];
34    fp();
35    fp = calleeAddrs[1];
36    fp();
37}
38EOF
39
40# Create main.cc. Function `main` calls `global_func`.
41cat > main.cc << EOF
42#include "lib.h"
43int main() {
44    global_func();
45}
46EOF
47
48# Clean up temporary files on exit and return to original directory.
49cleanup() {
50  rm -f $OUTDIR/lib.h
51  rm -f $OUTDIR/lib.cc
52  rm -f $OUTDIR/main.cc
53  rm -f $OUTDIR/lib.h.pch
54  rm -f $OUTDIR/a.out
55  cd $CURDIR
56}
57trap cleanup EXIT
58
59# Generate instrumented binary
60${CLANG} -fuse-ld=lld -O2 -fprofile-generate=. lib.h lib.cc main.cc
61# Create raw profiles
62env LLVM_PROFILE_FILE=thinlto_indirect_call_promotion.profraw ./a.out
63