Unfortunately, plug-ins are dynamically linked in LLVM which excludes this approach on Windows (without relying on Cygwin). For all my searching I was not able to find instructions on integrating a pass directly with the opt tool but I needed to support custom passes on Windows without using Cygwin. Mostly as a note for myself, I am listing here the steps I used to create my own custom pass as part of the opt tool; hopefully they will be useful for others as well.
I've followed as best I could the format used by existing infrastructure within LLVM. This does not mean that I have not missed something critical or what I have provided adheres to LLVM policy and/or standards.
N.B. These examples assume you are:
- already familiar with writing a custom pass as described by the LLVM documentation
- capable of understanding Makefiles and how to modify them to suit your needs
- using llvm-3.0 (that is the version used in these examples)
These examples will build a pass named mypass which will simply print out all function names. This pass will be part of the Custom library (also created here).
The first step is to create a new directory named Custom under llvm/lib/Transforms. This is where all passes for the new library will live. Create a very simple function pass and place it in this new directory - I used the following (MyPass.cpp)
The first step is to create a new directory named Custom under llvm/lib/Transforms. This is where all passes for the new library will live. Create a very simple function pass and place it in this new directory - I used the following (MyPass.cpp)
#define DEBUG_TYPE "mypass"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Custom.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct MyPass : public FunctionPass {
static char ID;
MyPass() : FunctionPass(ID) {
initializeMyPassPass(*PassRegistry::getPassRegistry());
}
/*
* Just print the function name
*/
bool runOnFunction(Function &F) {
bool Changed = false;
errs().write_escaped(F.getName()) << "\n";
return Changed;
}
};
}
char MyPass::ID = 0;
INITIALIZE_PASS(MyPass, "mypass", "Print all function names",
false, false)
FunctionPass *llvm::createMyPassPass() {
return new MyPass();
}
#include "llvm/InitializePasses.h"
#include "llvm-c/Initialization.h"
using namespace llvm;
/// initializeCustom - Initialize all passes in the Custom library
void llvm::initializeCustom(PassRegistry &Registry) {
initializeMyPassPass(Registry);
}
/// LLVMInitializeCustom - C binding for initializeCustom.
void LLVMInitializeCustom(LLVMPassRegistryRef R) {
initializeCustom(*unwrap(R));
}
LEVEL = ../../..
LIBRARYNAME = LLVMCustom
BUILD_ARCHIVE = 1
include $(LEVEL)/Makefile.common
add_llvm_library(LLVMCustom
MyPass.cpp
Custom.cpp
)
First, you need to define a way for LLVM to create an instance of your pass. Save the following as Custom.h in llvm/include/llvm/Transforms/
#ifndef LLVM_CUSTOM_H
#define LLVM_CUSTOM_H
namespace llvm {
FunctionPass *createMyPassPass();
}
#endif
void initializeCustom(PassRegistry&);
void initializeMyPassPass(PassRegistry&);
#include "llvm/Transforms/Custom.h"
// This part must reside in the constructor of struct ForcePassLinking
(void) llvm::createMyPassPass();
- llvm/lib/Transforms/Makefile
- llvm/lib/Transforms/CMakeLists.txt
- llvm/tools/opt/Makefile (add link dependency for 'custom')
- llvm/tools/opt/CMakeLists.txt (add link dependency for 'custom')
- llvm/tools/bugpoint/Makefile (add link dependency for 'custom')
- llvm/tools/bugpoint/CMakeLists.txt (add link dependency for 'custom')
initializeCustom(Registry);
-mergereturn - Unify function exit nodes
-module-debuginfo - Decodes module-level debug info
-mypass - Print all function names
-no-aa - No Alias Analysis (always returns 'may' alias)
-no-path-profile - No Path Profile Information