In two previous posts, I looked into cleaning the stack frame of a function before using it by adding assembly at the beginning of each function. This was done either by modifying LLVM with a custom codegen pass or by rewriting the assembly between the compiler and the assembler. The current implementation adds a loop at the beginning of every function. We look at the impact of this modification on the performance on the application.
In order to help the SimGridMC state comparison code, I wrote a proof-of-concept LLVM pass which cleans each stack frame before using it. However, SimGridMC currently does not work properly when compiled with clang/LLVM. We can do the same thing by pre-processing the assembly generated by the compiler before passing it to the linker: this is done by inserting a script between the compiler and the assembler. This script will rewrite the generated assembly by prepending stack-cleaning code at the beginning of each function.
In the previous episode, we implemented a LLVM pass which does nothing. Now we are trying to modify this to create a (proof-of-concept) LLVM pass which fills the current stack frame with zero before using it.
The SimGrid model checker uses memory introspection (of the heap,
stack and global variables) in order to detect the equality of the
state of a distributed application at the different nodes of its
execution graph. One difficulty is to deal with uninitialised
variables. The uninitialised global variables are usually not a big
problem as their initial value is 0. The heap variables are dealt with
by memset
ing to 0 the content of the buffers returned by malloc
and friends. The case of uninitialised stack variables is more
problematic as their value is whatever was at this place on the stack
before. In order to evaluate the impact of those uninitialised
variables, we would like to clean each stack frame before using
them. This could be done with a LLVM plugin. Here is my first attempt
to write a LLVM pass to modify the code of a function.