143 lines · bash
1#!/bin/bash2 3if [ $# -lt 2 ]; then4 echo "Path to clang and llvm-profdata required!"5 echo "Usage: update_memprof_inputs.sh /path/to/updated/clang /path/to/updated/llvm-profdata"6 exit 17else8 CLANG=$19 LLVMPROFDATA=$210fi11 12# Allows the script to be invoked from other directories.13OUTDIR=$(dirname $(realpath -s $0))14 15# Note that changes in the code below which affect relative line number16# offsets of calls from their parent function can affect callsite matching in17# the LLVM IR.18cat > ${OUTDIR}/memprof.cc << EOF19#include <stdlib.h>20#include <string.h>21#include <unistd.h>22char *foo() {23 return new char[10];24}25char *foo2() {26 return foo();27}28char *bar() {29 return foo2();30}31char *baz() {32 return foo2();33}34char *recurse(unsigned n) {35 if (!n)36 return foo();37 return recurse(n-1);38}39int main(int argc, char **argv) {40 // Test allocations with different combinations of stack contexts and41 // coldness (based on lifetime, since they are all accessed a single time42 // per byte via the memset).43 char *a = new char[10];44 char *b = new char[10];45 char *c = foo();46 char *d = foo();47 char *e = bar();48 char *f = baz();49 memset(a, 0, 10);50 memset(b, 0, 10);51 memset(c, 0, 10);52 memset(d, 0, 10);53 memset(e, 0, 10);54 memset(f, 0, 10);55 // a and c have short lifetimes56 delete[] a;57 delete[] c;58 // b, d, e, and f have long lifetimes and will be detected as cold by default.59 sleep(200);60 delete[] b;61 delete[] d;62 delete[] e;63 delete[] f;64 65 // Loop ensures the two calls to recurse have stack contexts that only differ66 // in one level of recursion. We should get two stack contexts reflecting the67 // different levels of recursion and different allocation behavior (since the68 // first has a very long lifetime and the second has a short lifetime).69 for (unsigned i = 0; i < 2; i++) {70 char *g = recurse(i + 3);71 memset(g, 0, 10);72 if (!i)73 sleep(200);74 delete[] g;75 }76 return 0;77}78EOF79 80COMMON_FLAGS="-fuse-ld=lld -Wl,--no-rosegment -gmlt -fdebug-info-for-profiling -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -m64 -Wl,-build-id -no-pie"81 82${CLANG} ${COMMON_FLAGS} -fmemory-profile ${OUTDIR}/memprof.cc -o ${OUTDIR}/memprof.exe83env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof.exe > ${OUTDIR}/memprof.memprofraw84 85# Generate another profile without any column numbers.86${CLANG} ${COMMON_FLAGS} -gno-column-info -fmemory-profile ${OUTDIR}/memprof.cc -o ${OUTDIR}/memprof.nocolinfo.exe87env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof.nocolinfo.exe > ${OUTDIR}/memprof.nocolinfo.memprofraw88 89${CLANG} ${COMMON_FLAGS} -fprofile-generate=. \90 ${OUTDIR}/memprof.cc -o ${OUTDIR}/pgo.exe91env LLVM_PROFILE_FILE=${OUTDIR}/memprof_pgo.profraw ${OUTDIR}/pgo.exe92${LLVMPROFDATA} merge --text ${OUTDIR}/memprof_pgo.profraw -o ${OUTDIR}/memprof_pgo.proftext93 94rm ${OUTDIR}/memprof.cc95rm ${OUTDIR}/pgo.exe96rm ${OUTDIR}/memprof_pgo.profraw97 98cat > ${OUTDIR}/memprof_internal_linkage.cc << EOF99#include <cstring>100#include <unistd.h>101static void foo() {102 int *a = new int[5];103 memset(a, 0, 5);104}105int main(int argc, char **argv) {106 foo();107 return 0;108}109EOF110 111${CLANG} ${COMMON_FLAGS} -fmemory-profile -funique-internal-linkage-names ${OUTDIR}/memprof_internal_linkage.cc -o ${OUTDIR}/memprof_internal_linkage.exe112env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof_internal_linkage.exe > ${OUTDIR}/memprof_internal_linkage.memprofraw113 114rm ${OUTDIR}/memprof_internal_linkage.cc115 116cat > ${OUTDIR}/memprof_loop_unroll_a.cc << EOF117int* a[2];118extern void foo();119int main() {120 foo();121 for (int i = 0; i < 1000000; ++i) {122 *a[0] = 1;123 }124 return 0;125}126EOF127cat > ${OUTDIR}/memprof_loop_unroll_b.cc << EOF128#include <string>129extern int* a[2];130void foo() {131 for (int i = 0; i < 2; ++i) {132 a[i] = new int[1];133 }134}135EOF136${CLANG} ${COMMON_FLAGS} -fmemory-profile ${OUTDIR}/memprof_loop_unroll_a.cc -O0 -o ${OUTDIR}/memprof_loop_unroll_a.o -c137${CLANG} ${COMMON_FLAGS} -fmemory-profile ${OUTDIR}/memprof_loop_unroll_b.cc -O3 -o ${OUTDIR}/memprof_loop_unroll_b.o -c138${CLANG} ${COMMON_FLAGS} -fmemory-profile ${OUTDIR}/memprof_loop_unroll_a.o ${OUTDIR}/memprof_loop_unroll_b.o -o ${OUTDIR}/memprof_loop_unroll.exe139env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof_loop_unroll.exe > ${OUTDIR}/memprof_loop_unroll.memprofraw140rm ${OUTDIR}/memprof_loop_unroll_a.cc141rm ${OUTDIR}/memprof_loop_unroll_a.o142rm ${OUTDIR}/memprof_loop_unroll_b.cc143rm ${OUTDIR}/memprof_loop_unroll_b.o