Pages

Sunday 20 July 2014

How to create LLVM transforms pass with Clang option (flag) in llvm-3.4

We are going to create Module Pass. In the same way it is possible to create Function, BasicBlock, etc. Instead of Module use Function, BasiBlock, etc

Step 1: Got to the llvm/lib/Transformas/MyLLVMPasses directory.


cd llvm/lib/Transformas/MyLLVMPasses


Step 2: Create NewLlvmPass.cpp file (you can give any name) in MyLLVMPasses  directory and write there this code


#include "llvm/Transforms/MyLLVMPasses.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Pass.h"

using namespace llvm;

namespace {
class NewLlvmPass : public ModulePass {
public:
    static char ID;
    NewLlvmPass() : ModulePass(ID) {
      initializeNewLlvmPassPass(*PassRegistry::getPassRegistry());
    }

    bool runOnModule(Module &M);
 };
} // end namespace

char NewLlvmPass::ID = 0;
INITIALIZE_PASS_BEGIN(NewLlvmPass, "myoption", "New LLVM Pass", false, false)
INITIALIZE_PASS_END(NewLlvmPass, "myoption", "New LLVM Pass", false, false)

ModulePass *llvm::createNewLlvmPassPass() {
  return new NewLlvmPass();
}

// runOnModule(Module &M) is like main()
bool NewLlvmPass::runOnModule(Module &M) {

  bool Changed = false;

  errs() << "New LLVM Pass" << "\n";

  return Changed;
}


Step 3: Open llvm/include/llvm/Transforms/MyLLVMPasses.h file. After class decelerations add this code


ModulePass *createNewLlvmPassPass();


Step 4: Open llvm/include/llvm/LinkAllPasses.h file. Add this code.


(void) llvm::createNewLlvmPassPass();


Step 5: Open llvm/include/llvm/InitializePasses.h file and in end of file add this code


void initializeNewLlvmPassPass(PassRegistry&);


Step 6: Open llvm/include/llvm-c/Transforms/MyLLVMPasses.h file and add this line
void LLVMAddNewLlvmPassPass(LLVMPassManagerRef PM);
see below


extern "C" {
#endif

/** See llvm::createNewLlvmPassPass function. */
void LLVMAddNewLlvmPassPass(LLVMPassManagerRef PM);


#ifdef __cplusplus
}


Step 7: Open llvm/lib/Transforms/MyLLVMPasses/CmakeLists.txt file. Add in file pass' file name.


add_llvm_library(LLVMMyLLVMPasses
  NewLlvmPass.cpp
  )

add_dependencies(LLVMMyLLVMPasses intrinsics_gen)


Step 8: Open llvm/lib/Transforms/MyLLVMPasses/MyLLVMPasses.cpp file. Add lines which are highlighted.


// initializeMyLLVMPasses - Initialize all passes linked into the
// MyLLVMPasses library.
void llvm::initializeMyLLVMPasses(PassRegistry &Registry) {
  initializeNewLlvmPassPass(Registry);
}

void LLVMInitializeMyLLVMPasses(LLVMPassRegistryRef R) {
  initializeMyLLVMPasses(*unwrap(R));
}

void LLVMAddNewLlvmPassPass(LLVMPassManagerRef PM) {
  unwrap(PM)->add(createNewLlvmPassPass());
}


Step 9: Open file llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp file. Add line
Opts.NewLlvmPass = Args.hasArg(OPT_enable_myoption);
in function ParseCodeGenArgs, after those lines (see below).


Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive);
Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);

Opts.NewLlvmPass = Args.hasArg(OPT_enable_myoption);


Step 10: Open llvm/tools/clang/lib/CodeGen/BackendUtil.cpp file. In end of 
EmitAssemblyHelper::CreatePasses() functio add this code


if (CodeGenOpts.NewLlvmPass) {
  MPM->add(createNewLlvmPassPass());
}


Step 11: Open llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def file. Add this line
CODEGENOPT(NewLlvmPass       , 1, 0)  ///< Run My New LLVM pass

you can add it after Vectorize, like this


CODEGENOPT(VectorizeSLP , 1, 0)  /// < Run SLP vectorizer.

CODEGENOPT(NewLlvmPass  , 1, 0)  /// < Run My New LLVM pass


Now we must add our Clang option, which we named "-myoption"

Step 12: Open llvm/tools/clang/lib/Driver/Tools.cpp file and in Clang::ConstructJob function add this code


if (Args.hasArg(options::OPT_enable_myoption))
  CmdArgs.push_back("-myoption");


Step 13: Open llvm/tools/clang/include/clang/Driver/Options.td file. Add these lines


def enable_myoption : Flag<["-"], "myoption">, Flags<[CC1Option]>,
  HelpText<"New LLVM Pass">;


you can add it before  // standard options comment.

Step 14: Now go to check LLVM pass with Clang option.


make
make install


Step 15: Run (path_to_install_dir is absolute path where installed clang/clang++ )


path_to_install_dir/clang++ -mayoption test.cpp


Output during compilation.


New LLVM Pass

How to create own Transforms pass directory in llvm-3.4

Step 1: Go to the llvm Transforms directory and create directory MyLLVMPasses 
            (you can give any directory name)


cd llvm/lib/Transforms
mkdir MyLLVMPasses


Step 2: Add directory name MyLLVMPasses in Transforms/CmakeLists.txt file 


add_subdirectory(MyLLVMPasses)


Step 3: Add directory name MyLLVMPasses in Transforms/LLVMBuild.txt file


[common]
subdirectories = IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC MyLLVMPasses


Step 4: Add directory name MyLLVMPasses in Transforms/Makefile file


PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello ObjCARC MyLLVMPasses


Step 5: Create CmakeLists.txt file in  MyLLVMPasses directory and write these lines


add_llvm_library(LLVMMyLLVMPasses
  )

add_dependencies(LLVMMyLLVMPasses intrinsics_gen)


Step 6: Create LLVMBuild.txt file in MyLLVMPasses directory and write these lines


[component_0]
type = Library
name = MyLLVMPasses
parent = Transforms
library_name = MyLLVMPasses
required_libraries = Analysis Core Support Target TransformUtils


Step 7:  Create Makefile in MyLLVMPasses directory and write these lines


LEVEL = ../../..
LIBRARYNAME = LLVMMyLLVMPasses
BUILD_ARCHIVE = 1

include $(LEVEL)/Makefile.common


Step 8: Create MyLLVMPasses.cpp file in MyLLVMPasses directory and write these lines


#include "llvm/Transforms/MyLLVMPasses.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/Transforms/MyLLVMPasses.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h"
#include "llvm/PassManager.h"

using namespace llvm;
// initializeMyLLVMPasses - Initialize all passes linked into the
// MyLLVMPasses library.

void llvm::initializeMyLLVMPasses(PassRegistry &Registry) {
  // nothing is needed here yet
}

void LLVMInitializeMyLLVMPasses(LLVMPassRegistryRef R) {
  initializeMyLLVMPasses(*unwrap(R));
}


Step 9: Create MyLLVMPasses.h file in llvm/include/llvm/Transforms and write these lines


#ifndef LLVM_TRANSFORMS_MYLLVMPASSES_H
#define LLVM_TRANSFORMS_MYLLVMPASSES_H

#include "llvm/ADT/StringRef.h"

namespace llvm {

class FunctionPass;
class Pass;

} // End llvm namespace

#endif


Step 10: Create MyLLVMPasses.h file in llvm/include/llvm-c/Transforms and write these lines


#ifndef LLVM_C_TRANSFORMS_MYLLVMPASSES_H
#define LLVM_C_TRANSFORMS_MYLLVMPASSES_H

#include "llvm-c/Core.h"

#ifdef __cplusplus
extern "C" {
#endif

// LLVMCTransformsMyLLVMPasses MyLLVMPasses transformations

#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */

#endif


Step 11: Open llvm/include/llvm-c/Initialization.h file, add this line


void LLVMInitializeMyLLVMPasses(LLVMPassRegistryRef R);


Step 12: Open llvm/include/llvm/InitializePasses.h file, add this line


// initializeMyLLVMPasses - Initialize all passes linked into the
// MyLLVMPasses library.
void initializeMyLLVMPasses(PassRegistry&);


Step 13: Add directory name MyLLVMPasses in lib/Transforms/IPO/LLVMBuild.txt file


[component_0]
type = Library
name = IPO
parent = Transforms
library_name = ipo
required_libraries = Analysis Core IPA InstCombine Scalar Support Target TransformUtils Vectorize MyLLVMPasses


Step 14: Include MyLLVMPasses.h file in llvm/include/llvm/LinkAllPasses.h file


#include "llvm/Transforms/MyLLVMPasses.h"


Step 15: Include MyLLVMPasses.h file in llvm/tools/clang/lib/CodeGen/BackendUtil.cpp file


#include "llvm/Transforms/MyLLVMPasses.h"

Tuesday 6 May 2014

get bitcode(.bc) from source in llvm/clang

get bytecode from C++ program. 
test.cpp

int main()
{
  const int count = 3;
  const int value = 5;

  int result = count + value;

  return 0;
}


get bytecode.

clang++ -c -emit-llvm test.cpp -o testbyte.bc -S


read bytecode file (testbyte.bc).

vim testbyte.bc


testbyte.bc
.
.
.
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %count = alloca i32, align 4
  %value = alloca i32, align 4
  %result = alloca i32, align 4
  store i32 0, i32* %retval
  store i32 3, i32* %count, align 4
  store i32 5, i32* %value, align 4
  store i32 8, i32* %result, align 4
  ret i32 0
}
.
.
.

Sunday 4 May 2014

Install LLVM/Clang in Linux/Ubuntu using git

Step 1: 
Download LLVM and Clang


git clone http://llvm.org/git/llvm.git llvm

cd llvm/tools

git clone http://llvm.org/git/clang.git clang


Step 2: 
Configure and install LLVM and Clang


cd ../

mkdir build  (for building without polluting the source directory)

cd build

../configure --enable-optimized --enable-assertions
                                --prefix=/home/user/llvm/install

make

make install


for more information about configure and install see. Getting Started with the LLVM System


Step 3: 
Testing LLVM/Clang, compile small C++ program (test.cpp)

// test.cpp

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
  cout << "Hello LLVM/Clang" << "\n";

  return 0;
}


Step 4: 
Run


/home/user/llvm/install/bin/clang++ test.cpp -o hello

./hello


Output:

Hello LLVM/Clang