2012-12-12 37 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. 檢查它是否是當前處理的函數。如果沒有,這意味着你找到了當前函數和另一個函數共享的變量。

還有其他的方法來檢查它,例如遍歷當前模塊中的所有全局變量。