whether these transformations are doable and how?

Hi folk,

I’m a newbie to llvm, please first forgive my naive questions. I want to instrument llvm code to do some run-time monitoring work. After reading some of the llvm documentation, it begins clear to me that I can do the instrumentation in a transformation pass. There are several things I want to do in the transformation pass, but I’m not sure whether they are doable and how to do them even after I read the documentation. I would be very appreciate if anyone can answer my questions or give me hints of how to do them.

  1. can I add more global memory objects to a module? any hint how to do it? do I need to derive a pass from ModulePass?
  2. can I add more stack allocated memory objects to a function? the answer seems yes, any hint how to do it?
  3. can I modify a function to take extra formal parameters? can I update all calls of the original function to take extra actual paramters? The function might be called across multiple modules. It seems this has to be done at both ModulePass and FunctionPass levels.

Thanks,
Neal

Hi folk,

I'm a newbie to llvm, please first forgive my naive questions. I want to
instrument llvm code to do some run-time monitoring work. After reading
some of the llvm documentation, it begins clear to me that I can do the
instrumentation in a transformation pass. There are several things I want
to do in the transformation pass, but I'm not sure whether they are doable
and how to do them even after I read the documentation. I would be very
appreciate if anyone can answer my questions or give me hints of how to do
them.

1. can I add more global memory objects to a module? any hint how to do
it? do I need to derive a pass from ModulePass?

Yes, a ModulePass should be able to do that.

2. can I add more stack allocated memory objects to a function? the answer
seems yes, any hint how to do it?

In a FunctionPass, insert an alloca instruction in the entry block to
add a stack allocated memory object.

3. can I modify a function to take extra formal parameters? can I update
all calls of the original function to take extra actual paramters? The
function might be called across multiple modules. It seems this has to be
done at both ModulePass and FunctionPass levels.

A pass can only work with one module. You can use llvm-link to
combine multiple modules into a single module before you run the pass.
  Or you can make sure opt runs on all your modules, but in that case
you'll have to be able to apply the transformation to a call without
necessarily being able to see the definition.

Ning Wang wrote:

Hi folk,

I'm a newbie to llvm, please first forgive my naive questions. I want to instrument llvm code to do some run-time monitoring work. After reading some of the llvm documentation, it begins clear to me that I can do the instrumentation in a transformation pass. There are several things I want to do in the transformation pass, but I'm not sure whether they are doable and how to do them even after I read the documentation. I would be very appreciate if anyone can answer my questions or give me hints of how to do them.

1. can I add more global memory objects to a module? any hint how to do it? do I need to derive a pass from ModulePass?

Yes. Inside your pass, create a new GlobalVariable object. Please read the LLVM doxygen files (http://www.llvm.org/doxygen/hierarchy.html) to get specific information on using the classes below. Since this is a modification at global scope, you need to use a ModulePass.

2. can I add more stack allocated memory objects to a function? the answer seems yes, any hint how to do it?

Yes. Inside your pass, create a new AllocaInst object. You can probably do this in a FunctionPass.

3. can I modify a function to take extra formal parameters? can I update all calls of the original function to take extra actual paramters? The function might be called across multiple modules. It seems this has to be done at both ModulePass and FunctionPass levels.

Since this is a global change, use a ModulePass.

This change is a bit more difficult. First, to add parameters, I believe you can't change the original function; you have to create a new, empty function with the new parameters and then clone the body of the old function into the new function. There's a utility function (I think it's in llvm/lib/Transform/Utils) that helps do this.

Updating callers is a bit more difficult. Direct callers are easy; just scan through the def/use chain of the function and find them. Indirect callers are a different matter. You need to use some sort of analysis that tells you the potential call targets of an indirect function call. I think LLVM has a conservative analysis pass to do that.

-- John T.

  1. can I modify a function to take extra formal parameters? can I
    update all calls of the original function to take extra actual
    paramters? The function might be called across multiple modules. It
    seems this has to be done at both ModulePass and FunctionPass levels.

Since this is a global change, use a ModulePass.

This change is a bit more difficult. First, to add parameters, I
believe you can’t change the original function; you have to create a
new, empty function with the new parameters and then clone the body of
the old function into the new function. There’s a utility function (I
think it’s in llvm/lib/Transform/Utils) that helps do this.

Updating callers is a bit more difficult. Direct callers are easy; just

PIC16 Target does both the things.
See the PIC16Cloner pass inside lib/Target/PIC16/PIC16Passes directory.

  • Sanjiv

Hi Ning,

The easy way is to check some examples in lib/Transformation or lib/Analysis.

You may also write some simple c programs, then you can use "llc
-march=cpp x.bc" to see how you can declare variables using LLVM APIs.

For example, you can simply write a c program named test.c as:

#include <stdio.h>

int global_1;
float global_2;

int main()
{
  int stack_1, stack_2;

  ...
  return 0;
}

You can translate it to LLVM Bytecode by:
llvm-gcc -emit-llvm -c test.c
opt -mem2reg -f < test.o > test.new.o

then, convert it c++ formation by:
llc -march=cpp test.new.o

You should be able to get some hints about how to declare global
variables from generated file --- test.new.o.cpp.

Hi!

3. can I modify a function to take extra formal parameters? can I update
all calls of the original function to take extra actual paramters? The
function might be called across multiple modules. It seems this has to be
done at both ModulePass and FunctionPass levels.

Check out DeadArgumentElimination pass. It does opposite of what you
want, but you'll get an idea.

Thanks for all the replies which are really helpful.

one more question regarding transformation:

  1. Given an instruction %x1 = I1, can I replace the rhs “I1” with “I2” and get a new instruction %x1 = I2? Alternatively, I can add a new instruction %x2 = I2, and replace all uses of %x1 with %x2, and then delete %x1 = I1, but it seems the former is simpler or faster if it’s doable.

Any suggestion?
Neal

It’s a silly question. I rephrase it as “is it possible to use different instruction to def the same ssa variable?”

Creating a new instruction, replacing all the uses, and deleting the
old instruction is the standard procedure; for various reasons, LLVM
doesn't allow editing certain aspects of an Instruction.

-Eli

The code you're looking for is Value::replaceAllUsesWith(Value*).
Values maintain backpointers to users, so it doesn't need to search
for users in the rest of the function, making this an efficient
operation.

Reid