diff --git a/gprof/Makefile b/gprof/Makefile new file mode 100644 index 0000000..f06abee --- /dev/null +++ b/gprof/Makefile @@ -0,0 +1,17 @@ +export CFLAGS = -pg # Use gprof +export CFLAGS += -static # Static link +export CFLAGS += -O0 # Heavy optimization +export CFLAGS += -Wl,--defsym,_mcount=mcount # Link _mcount to mcount +export CFLAGS += -mapcs-frame # Use standard calling convention +#export CFLAGS += -fno-omit-frame-pointer # Don't omit fp (might not necessary to enable this) + +AppMain.exe: + @arm-mingw32ce-gcc -o AppMain $(CFLAGS) profile.c + +AppMain.mitigated.s: + @arm-mingw32ce-gcc -O0 -S -fno-omit-frame-pointer -mapcs-frame profile.c + @mv profile.s AppMain.mitigated.s + +.PHONY: +clean: + @rm -f AppMain.exe AppMain*.s diff --git a/gprof/README.md b/gprof/README.md new file mode 100644 index 0000000..0626aad --- /dev/null +++ b/gprof/README.md @@ -0,0 +1,29 @@ +Gprof test program +------------------ + + - Needs gprof-enabled CeGCC. + - `make` to compile AppMain.exe. + + +## CFLAGS + +By default, GCC emits code that is not comformant to [APCS](https://www.cl.cam.ac.uk/~fms27/teaching/2001-02/arm-project/02-sort/apcs.txt). +Gprof's `_mcount` assumes APCS-compliant and `fp` being present in the binary. + +- `-mapcs-frame` is disabled by default for all optimization level + - It leads to a crash without APCS. Must be enabled explicitly. +- `-fno-omit-frame-pointer` is enabled for all optimization level but `-O0` + - It might have some effect on the compilation, but not sure + - As I experiment unsetting (disabling) this flag, it doesn't crash even with `-O2` + + +## Experiment results: flags' effect + +- `-fno-omit-frame-pointer` looks like it has nothing to do with calling convention because of `-mapcs-frame` +- Optimization other than `-O0` optimizes the func call (inlining etc) and the resulting graph becomes strange (lack of main() etc.) + + +|CFLAGS|Screenshot| +|:-----|:--------:| +|`-O0`|| +|`-O2`|| diff --git a/gprof/o0.png b/gprof/o0.png new file mode 100644 index 0000000..a121a65 Binary files /dev/null and b/gprof/o0.png differ diff --git a/gprof/o2.png b/gprof/o2.png new file mode 100644 index 0000000..55c503d Binary files /dev/null and b/gprof/o2.png differ diff --git a/gprof/profile.c b/gprof/profile.c new file mode 100644 index 0000000..797f1df --- /dev/null +++ b/gprof/profile.c @@ -0,0 +1,31 @@ +#include + +int __attribute__((noinline)) fibonacci(int n) { + if (n <= 1) return n; + return fibonacci(n - 1) + fibonacci(n - 2); +} + +void __attribute__((noinline)) dummy_work(int count) { + volatile int sum = 0; + for (int i = 0; i < count; i++) { + sum += i; + } +} + +void __attribute__((noinline)) heavy_logic() { + for (int i = 0; i < 5; i++) { + // It will take up to a few sec + printf("Computing fib(30)... iteration %d\n", i); + fibonacci(30); + } +} + +int main(int argc, char* argv[]) { + printf("--- Profiling Test Start ---\n"); + + heavy_logic(); + dummy_work(1000); + + printf("--- Profiling Test End ---\n"); + return 0; +}