tum-i4 / input-dependency-analyzer

7 stars 4 forks source link

Building the project

To build the project llvm3.9 or above should be installed.

   mkdir build
   cd build
   cmake $PATH_TO_SRC
   make

Input Dependency Analysis pass

Input dependency analysis pass is a context sensitive, flow sensitive llvm analysis pass. It gets as an input llvm bitcode and collects information about input dependent and input independent instructions. It considers both data flow dependencies and control flow dependencies. An instruction is said to be input dependent by data flow, if any of its arguments is input dependent. An instruction is input dependent by control flow if it is in a branch, which condition is input dependent. Primary sources of inputs are arguments of main functions. All external functions which are considered as input sources, if not stated otherwise in the configuration files.

Runing input dependency analysis

    opt -load $PATH_TO_LIB/libInputDependency.so bitcode.bc -input-dep -o out_bitcode.bc

Using input dependency in your pass

To use Input dependency analysis information in your pass you need to register it as a required pass

    AU.addRequired<input_dependency::InputDependencyAnalysis>();

Then get it's information:

    const auto& input_dependency_info = getAnalysis<input_dependency::InputDependencyAnalysis>();

InputDependencyAnalysis provides interface to request information about instruction input dependency:

    bool isInputDependent(llvm::Instruction* instr) const;
    bool isInputIndependent(llvm::Instruction* instr) const;

Debug passes

Transformation passes

Input dependency pass will consider the second argument of function f to be input dependent as there is a call site where it is input dependent. Function clonning pass will create two clones of f - f1 and f2, where f1 will be called with the first set of arguments, and f2 will be called with the second set of arguments. The pass will also change call sites to call corresponding clones.

    void f1(int a, int b)
    {
    }
    void f2(int a, int b)
    {
    }

    int x = input;
    f1(3, x);
    f2(2, 3);

To run the pass

    opt -load $PATH_TO_LIB/libInputDependency.so -load $PATH_TO_LIB/libTransforms.so bitcode.bc -clone-functions -o out.bc

Lines (2) and (3) are input dependent. The result of running this pass will be

    void f_extracted(int* a, int* b, int* c)
    {
        *b = input;
        *c = *b + *a;
    }

    void f()
    {
        int x = 0;
        int y;
        int sum;
        f_extracted(&x, &y, &sum);
    }

To run the pass

    opt -load $PATH_TO_LIB/libInputDependency.so -load $PATH_TO_LIB/libTransforms.so bitcode.bc -extract-functions -o out.bc