开发者

Modern equivalent of LLVM AnnotationManager?

Now that LLVM's AnnotationManager is gone (it disappeared in the 2.6 release, I think?), how can I get the annotations for specific fu开发者_运维百科nctions, globals, and instructions?

(For example, I have bitcode compiled from C void myFunction(__attribute__((annotate("foo"))) int var) --- given an Argument * reference to this int var argument, how might I determine which annotate attributes are attached to it?)


To get annotations for a specific function, traverse the entry BasicBlock of the function to find its calls to the @llvm.var.annotation intrinsic, as follows:

Module *module;

[...]

std::string getGlobalVariableString(std::string name)
{
    // assumption: the zeroth operand of a Value::GlobalVariableVal is the actual Value
    Value *v = module->getNamedValue(name)->getOperand(0);
    if(v->getValueID() == Value::ConstantArrayVal)
    {
        ConstantArray *ca = (ConstantArray *)v;
        return ca->getAsString();
    }

    return "";
}

void dumpFunctionArgAnnotations(std::string funcName)
{
    std::map<Value *,Argument*> mapValueToArgument;

    Function *func = module->getFunction(funcName);
    if(!func)
    {
        std::cout << "no function by that name.\n";
        return;
    }

    std::cout << funcName << "() ====================\n";


    // assumption: @llvm.var.annotation calls are always in the function's entry block.
    BasicBlock *b = &func->getEntryBlock();


    // run through entry block first to build map of pointers to arguments
    for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
    {
        Instruction *inst = it;
        if(inst->getOpcode()!=Instruction::Store)
            continue;

        // `store` operands: http://llvm.org/docs/LangRef.html#i_store
        mapValueToArgument[inst->getOperand(1)] = (Argument *)inst->getOperand(0);
    }


    // run through entry block a second time, to associate annotations with arguments
    for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
    {
        Instruction *inst = it;
        if(inst->getOpcode()!=Instruction::Call)
            continue;

        // assumption: Instruction::Call's operands are the function arguments, followed by the function name
        Value *calledFunction = inst->getOperand(inst->getNumOperands()-1);
        if(calledFunction->getName().str() != "llvm.var.annotation")
            continue;

        // `llvm.var.annotation` operands: http://llvm.org/docs/LangRef.html#int_var_annotation

        Value *annotatedValue = inst->getOperand(0);
        if(annotatedValue->getValueID() != Value::InstructionVal + Instruction::BitCast)
            continue;
        Argument *a = mapValueToArgument[annotatedValue->getUnderlyingObject()];
        if(!a)
            continue;

        Value *annotation = inst->getOperand(1);
        if(annotation->getValueID() != Value::ConstantExprVal)
            continue;
        ConstantExpr *ce = (ConstantExpr *)annotation;
        if(ce->getOpcode() != Instruction::GetElementPtr)
            continue;

        // `ConstantExpr` operands: http://llvm.org/docs/LangRef.html#constantexprs
        Value *gv = ce->getOperand(0);

        if(gv->getValueID() != Value::GlobalVariableVal)
            continue;

        std::cout << "    argument " << a->getType()->getDescription() << " " << a->getName().str()
            << " has annotation \"" << getGlobalVariableString(gv->getName().str()) << "\"\n";
    }
}


AnnotationManager was deleted because it was useless (and it won't solve your problem). All the annotations are handled via the global named 'llvm.global.annotations' and annotation intrinsics, which you can surely parse and obtain the information you needed.

Look into IR to have an idea, how your C code was transformed into IR and what annotation attribute was turned into.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜