LLVM retrieve name of AllocaInst

2020-07-24 05:27发布

问题:

I am trying to retrieve the name of the pointer passed to a cudaMalloc call.

CallInst *CUMallocCI = ... ; // CI of cudaMalloc call
Value *Ptr = CUMallocCI->getOperand(0);
if (AllocaInst *AI = dyn_cast<AllocaInst>(Ptr) != nullptr) {
  errs() << AI->getName() << "\n";
}

The above however just prints an empty line. Is is possible to get the pointer name out of this alloca?

This is the relevant IR:

%28 = alloca i8*, align 8
...
...
call void @llvm.dbg.declare(metadata i8** %28, metadata !926, metadata !DIExpression()), !dbg !927
%257 = call i32 @cudaMalloc(i8** %28, i64 1), !dbg !928
...
...
!926 = !DILocalVariable(name: "d_over", scope: !677, file: !3, line: 191, type: !22)
!927 = !DILocation(line: 191, column: 10, scope: !677)

回答1:

Answering my own question. It turns out that there is an llvm.dbg.declare call (DbgDeclareInst) corresponding to the alloca but it may appear anywhere in the caller function's basic blocks. Probably it comes after the first use of this Alloca value? Not sure. In any case, my solution is to search for DbgDeclareInst instructions, check if it is for an AllocaInst and if so compare that alloca with the alloca of interest and if equal get the variable name. Something like this:

CallInst *CUMallocCI = ... ; // CI of cudaMalloc call
Value *Ptr = CUMallocCI->getOperand(0);
if (AllocaInst *AI = dyn_cast<AllocaInst>(Ptr) != nullptr) {
  if ( !AI->hasName() ) {
    // Function this AllocaInst belongs
    Function *Caller = AI->getParent()->getParent();
    // Search for llvm.dbg.declare
    for ( BasicBlock& BB : *Caller) 
      for (Instruction &I : BB) {
        if ( DbgDeclareInst *dbg = dyn_cast<DbgDeclareInst>(&I))
          // found. is it for an AllocaInst?
          if ( AllocaInst *dbgAI = dyn_cast<AllocaInst>(dbg->getAddress()))
            // is it for our AllocaInst?
            if (dbgAI == AI)
              if (DILocalVariable *varMD = dbg->getVariable()) // probably not needed?
                errs() << varMD->getName() << "\n";
  } else {
    errs() << AI->getName() << "\n";
  }
}