2

In the example bellow, I am trying to extract all the global variables referenced by each instruction, but I keep missing some of them.

... // inside a BB
for (Instruction * I : BB) {
  for (Use &U : I->operands()) {
    if(GlobalVariable * GV = dyn_cast<GlobalVariable >(U)){
      // Do something with GV
      GV->dump();
    }
  }
}

But when I am targeting getting the global values of:

@end = global i8 0, align 1
@.str = private unnamed_addr constant [4 x i8] c"YES\00", align 1
@.str.2 = private unnamed_addr constant [3 x i8] c"NO\00", align 1

define void @TempF() {
entry:
  %tmp8 = load i8, i8* @end, align 1
  %tmp9 = trunc i8 %tmp8 to i1
  %tmp10 = select i1 %tmp9, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i32 0, i32 0)
  ret void
}

When running my pass on this IR, only @end = global i8 0, align 1 gets printed. But not ...

@.str = private unnamed_addr constant [4 x i8] c"YES\00", align 1
@.str.2 = private unnamed_addr constant [3 x i8] c"NO\00", align 1

I understand that @.str is not part of the operands as @end is. @.str is something reference by one of the operands.

What modifications do I have to implement to be able to get the global variables inside the operands?

2
  • What if you ->dump() outside of your if? What other operands do you see then? Probably you need another if(s) to act accordingly on their contents, no? Commented Oct 2, 2017 at 21:40
  • @Stanislav, yes, after seeing @Brian's answer, I totally agree with you. But I would like to avoid writing code for every corner case. I think I will solve it by building a set with all the non GV operators and verifying which may have operands (getNumOperands()!=0), similar to what Brian done, but, perhaps, by casting them to instructions. Still trying to implement it. Am I correct to assume only instructions have operands? Commented Oct 3, 2017 at 4:59

1 Answer 1

3

In your case, the select instruction has GetElementPtr operators. You will need to extend your code to both detect this case, and then iterate through the arguments (the pointer and ) to the operator. I have suggested an extension to your for loop below, currently printing out these other cases.

for (Use &U : (&*I)->operands()) {
    if(GlobalVariable * GV = dyn_cast<GlobalVariable>(U)){
      // Do something with GV
      GV->dump();
    }
    else if (GEPOperator* gepo = dyn_cast<GEPOperator>(&U))
    {
        errs() << "GEPO - " << *gepo << "\n";
        if (GlobalVariable* gv = dyn_cast<GlobalVariable>(gepo->getPointerOperand()))
        {
            errs() << "GV - " << *gv << "\n";
        }
        for (auto it = gepo->idx_begin(), et = gepo->idx_end(); it != et; ++it)
        {
            if (GlobalVariable* gv = dyn_cast<GlobalVariable>(*it))
            {
                errs() << "GVi - " << *gv <<  "\n";
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hello @Brian, thank you for the answer. Considering I want to be generic, are there other corner cases of which I should be aware? Any chance of having another "level" of GEP instructions? Am I approaching this problem through the right direction? My other idea would be getting all global from SRC module and copy to DST module (that contains less instructions), and remove the GV that are not used (similar to extract-function.cpp), do you think this is a better approach?
I think any additional levels of GEP would be using other values, so those should already be detected separately. Note, these are Operators, and this question discusses some of the differences: stackoverflow.com/questions/33574522/…. In my work, I actually care about the distinction, so I have always worked through the different cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.