Basic "Hello World" LLVM passes. Based on LLVM for Grad Students and skeleton code.
hello
prints out the name of every functiondump
dumps LLVM IR for the first function, basic block and instruction it seesmutate
modifies the first binary operator of each function to a multiplicationrtlib
inserts a call to a hook function after the first binary operatorfnentry
inserts call at function entryattr
finds functions with attributefoo
srcloc
printsfile:line
metadata from each function (requires debug information)cli
shows how to define a command-line optionreturns
inserts calls before function returnshookargs
calls a hook function with argumentstrace
inserts hooks at function enter and exit points (script to verify correctness)demangle
ishello
with C++ name demanglingregexp
demonstrates thellvm::Regex
support library
Why does the RegisterPass<>
method not work when loaded into clang
? Under this method the pass dynamic library is loaded and enabled with opt -load <pass lib> -<pass name>
. By default, the clang
CLI emulates gcc
as much as possible. In particular it does not directly expose LLVM optimization passes. To get it to work directly with clang
we need to register the pass in code using the PassManagerBuilder
.
How do you detect function attributes like __attribute__((annotate("foo")))
? These are recorded in a global variable called llvm.global.annotations
. Brandon Holt demonstrates a technique to parse this and attach them as function attributes.
What is the return value of doInitialization
and runOnFunction
? Return true
if any changes were made.
How do you determine original source code location of an LLVM Function? This requires the program is compiled with debug information -g
. The information can be accessed through getSubprogram
method.
How do you define a string constant? Use CreateGlobalStringPtr(...)
on an IRBuilder
. Unfortunately I encountered an obscure segfault with LLVM 7.0.0 on Ubuntu. A more manual approach which avoided this problem was to use ConstantDataArray::getString
, followed by new GlobalVariable
and ConstantExpr::getPointerCast
.
How do you create a floating-point constant? Use ConstantFP
, for example ConstantFP::get(Type::getDoubleTy(ctx), 42.0)
.
Which instructions exit a function? Terminator instructions end basic blocks, either to exit the function or to branch to another part of the same function. The terminator instructions are:
ret
returns control flow back to the caller.br
transfers control flow to one of two other blocks in the current function.switch
is a generalization ofbr
, allowing control flow to several other blocks based on a valueindirectbr
jumps to another location by addressing into a list of labelsinvoke
is a call instruction that handles alternative control flow in the case of an exceptionresume
propagates an exceptioncatchswitch
switches between exception catch handlerscatchret
cleanupret
unreachable
informs the optimizer that a piece of code us unreachable
Use getTerminator
method of BasicBlock
to find.
How do you demangle C++ names? LLVM provides its own implementation of __cxa_demangle
(from cxxabi.h
) in Demangle.h
, specifically itaniumDemangle
. The symbolizer source code provides a useful example. The ItaniumPartialDemangler
(introduced in LLVM 7) enables access to subcomponents of the mangled name.
How do you define command-line options? Use cl::opt
to declare options statically, as shown in cli.cc
. When the pass is loaded directly in LLVM opt -load <pass lib>
these will be accessible as regular command-line options, and visible in help too. When loaded into Clang with clang++ -Xclang -load -Xclang <pass lib>
options must be forwarded to the LLVM backend with the -mllvm
flag.
- Pass arguments to hook functions
- Function exit in the case of exceptions
- Function exit with tail calls?
- How to inline hook function calls?
- Combine to a full tracer pass
- Call c++ hook function (handle mangling)
- Get pass working directly with clang (not via
opt
) - New style passes?