llvm get annotations

Hello everyone !

I followed http://stackoverflow.com/questions/4976298/modern-equivalent-of-llvm-annotationmanager in order to get annotations from my target bytecode. All the examples that I give in the following is related to the code from that link. I have __attribute__((annotate("DS"))) int f=0; into the target C++ program and the related IR code:

@.str = private unnamed_addr constant [3 x i8] c"DS\00", section “llvm.metadata”
@llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (i32* @f to i8*), i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0), i32 18 }], section “llvm.metadata”

I have two problems following the examples from http://stackoverflow.com/questions/4976298/modern-equivalent-of-llvm-annotationmanager :

  1. Cannot use annotatedValue->getUnderlyingObject() since Value class has not this method. Instead, I found in LLVM the following methods: llvm::GetUnderlyingObject(),getUnderlyingObjectFromInt(), getUnderlyingObjects().

I hacked the method llvm::GetUnderlyingObject()…that is with Capital G (different from getUnderlyingObject()) and call myGetUnderlyingObject(annotatedValue,0,6) as mentioned at http://llvm.org/docs/doxygen/html/namespacellvm.html#ace6c957db39858291c6ce01c38e78480 .

  1. Since I write my code into runOnFunction(), I have problems with getGlobalVariableString(std::string name) function from the stackoverflow link. So I have to integrate the following part of code into runOnFunction():

std::string name = gv->getName().str();

// assumption: the zeroth operand of a Value::GlobalVariableVal is the actual Value

//Module* module = ; //can I use Module& llvm::CallGraph::getModule() ?
Value *v = module->getNamedValue(name)->getOperand(0);
if(v->getValueID() == Value::ConstantArrayVal)
{
ConstantArray *ca = (ConstantArray *)v;
std::cout << " argument " << a->getType()->getDescription() << " “<getName().str()
<< " has annotation “” << ca->getAsString() << “”\n”;
}

Is there an easier way to get the simple DS annotation of @f ?

Thank you for any suggestion!

Hi Alexandru,

[...]
Is there an easier way to get the simple DS annotation of @f ?

I used to annotate C / C++ functions with e.g.
__attribute__((annotate("kernel"))) and the retrieved the name of the
function with the following code:

/*****************************************************/

GlobalValue *gv;
Value *a = gv->getOperand(0);

ConstantStruct *annoStruct =
    dynamic_cast<ConstantStruct>(
        dynamic_cast<ConstantArray>(a)->getOperand(0);
    );

GlobalVariable *gvar = dynamic_cast<GlobalVariable>(
    dynamic_cast<ConstantExpr>(
        annoStruct->getOperand(1)
    )->getOperand(0)
);

std::string str = dynamic_cast<ConstantDataArray>(
    gvar->getOperand(0)
)->getAsString();

if (str.find("kernel")) {
    [...]
}

/*****************************************************/

Inside the last if one can find the function that belongs to the annotation.

IMO its a bit ugly, but it works for me :wink:

Cheers,
Sebastian

Hi Sebastian,

Thanks for the response.

I already did this :

I cast the entire annotated expression to Value*. Then, in order to avoid ugly things like getAsString(), I check if V->getValueID() == Value::ConstantArrayVal in order to cast it to ConstantArray. Because it contains only array[0], I cast array0>getOperand(0) to ConstantStruct. Therefore, from ConstantStruct you can get all the four operands. Now, as a TODO, is only to get the names of @f, @str from every field.

But right now I have only a small step to do. ConstantStruct->getOperand(0) gives me i8* bitcast (i32* @f to i8*) . Do you know how I can get the name @f from this? I cannot convert it again to ConstantStruct and follow the same procedure, it will give me a segfault.

Thank you again. Your advice was very helpful :slight_smile:

Hi, I solved it. From the ConstantStruct you can call getOperand() multiple times, so “mine” as deep as you can.

Hi,

Hi, I solved it. From the ConstantStruct you can call getOperand() multiple
times, so "mine" as deep as you can.

Great that you figured it out. And I'm glad, that I could help you.

Cheers,
Sebastian