2012-12-12 41 views
0

最近我用LLVM API来测试C++程序。现在我想找出不同功能之间的共享变量,有没有办法做到这一点?看起来AliasAnalysis不起作用!如何使用LLVM API在函数中找出共享变量?

我写一个函数传递如下:

bool EscapeAnalysis::runOnFunction(Function& F) { 
    EscapePoints.clear(); 

    TargetData& TD = getAnalysis<TargetData>(); 
    AliasAnalysis& AA = getAnalysis<AliasAnalysis>(); 
    Module* M = F.getParent(); 
// errs() << *M << "\n"; 
// Walk through all instructions in the function, identifying those that 
// may allow their inputs to escape. 
    for(inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) { 
     Instruction* I = &*II; 

    // The most obvious case is stores. Any store that may write to global 
    // memory or to a function argument potentially allows its input to escape. 
     if (StoreInst* S = dyn_cast<StoreInst>(I)) { 
      Type* StoreType = S->getOperand(0)->getType(); 
      unsigned StoreSize = TD.getTypeStoreSize(StoreType); 
      Value* Pointer = S->getPointerOperand(); 

      bool inserted = false; 
      for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); 
        AI != AE; ++AI) { 
       if (!isa<PointerType>(AI->getType())) continue; 
       AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, AI, ~0UL); 
       if (R != AliasAnalysis::NoAlias) { 
        EscapePoints.insert(S); 
        inserted = true; 
        break; 
       } 
      } 

      if (inserted) 
       continue; 

      for (Module::global_iterator GI = M->global_begin(), GE = M->global_end(); 
       GI != GE; ++GI) { 
       errs() << *GI << "\n"; 
       AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, GI, ~0UL); 
       errs() << "R: " << R << " , NoAlias: " << AliasAnalysis::NoAlias << "\n"; 

       if (R != AliasAnalysis::NoAlias) { 
        EscapePoints.insert(S); 
        break; 
       } 
      } 

     // Calls and invokes potentially allow their parameters to escape. 
     // FIXME: This can and should be refined. Intrinsics have known escape 
     // behavior, and alias analysis may be able to tell us more about callees. 
     } else if (isa<CallInst>(I) || isa<InvokeInst>(I)) { 
      EscapePoints.insert(I); 

      // Returns allow the return value to escape. This is mostly important 
      // for malloc to alloca promotion. 
     } else if (isa<ReturnInst>(I)) { 
      EscapePoints.insert(I); 

      // Branching on the value of a pointer may allow the value to escape through 
      // methods not discoverable via def-use chaining. 
     } else if(isa<BranchInst>(I) || isa<SwitchInst>(I)) { 
      EscapePoints.insert(I); 
     } 

    // FIXME: Are there any other possible escape points? 
    } 

    return false; 
} 

测试的main.cpp如下: 的#include

using namespace std; 

int X = 0; 

int foo() { 
X = 1; 
int b = 1; 
return 0; 
} 

int bar(int param) { 
int y = X; 
int z = 9; 
int a = z; 

++a; 
return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    cout << "Hello world!" << endl; 
    return 0; 
} 

全局变量X共享功能栏和功能foo之间的变量。 但是,当我使用命令如下运行通:

opt -load ./EscapeAnalysis.so -escape-analysis main.o | llc > main.ss 

我得到的结果是:

R: 1 , NoAlias: 0 

所有的结果都是一样的。 我打印出escapePoint中的变量,在函数栏中找到变量a,z,y在escapePoint中。这是不对的!

注:我写了一个选择通过测试程序。

+0

你能准确地展示你如何使用别名分析吗?另外,你是否在寻找一种方法来查找共享*变量*(不需要别名分析)或共享*内存*(它确实)? – Oak

+0

我已经向您展示了我如何使用别名分析,您可以检查它。哦,是的!你是否认为没有必要使用别名分析来查找共享变量?我想找出函数之间的共享变量。例如上面的函数栏和函数foo之间的变量X!但现在我不熟悉LLVM API,不知道该怎么做。 – ZZB

回答

2

如果您想确定两个不同的变量可能指向同一内存,则需要别名分析。如果你只是想检查哪些变量在同一模块中与其它功能共用,您可以:

  1. 遍历所有指令,并为每个:
  2. 遍历所有的操作数,并为每个:
  3. 检查它是否是一个GlobalVariable(通过isa,例如),如果是这样:
  4. 遍历全球的所有用途(通过use_beginuse_end),并为每个:
  5. 检查它是否是一个Instruction,和我f so:
  6. 检索封闭函数(通过getParent()->getParent()),并为该函数:
  7. 检查它是否是当前处理的函数。如果没有,这意味着你找到了当前函数和另一个函数共享的变量。

还有其他的方法来检查它,例如遍历当前模块中的所有全局变量。