迭代 llvm::Function 以获得通过结果

Iterating over llvm::Function to get pass result

我正在尝试对 llvm IR 进行一些分析。为此,我尝试在 IR 模块的每个函数中获取 MemorySSAAnalysis 传递的结果。

但是在分析第二个函数的时候,出现了崩溃:

  Successfully read Module:
  Name: /mnt/DATA/LLVM/llvm-project/build_dyn_debug/sample1_O3.ll
  Target triple: x86_64-unknown-linux-gnu
  Invalidating analysis: InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Function>, llvm::Module> on /mnt/DATA/LLVM12/llvm-project/build_dyn_debug/sample1_O3.ll
  Invalidating analysis: LazyValueAnalysis on test
  Invalidating analysis: LazyValueAnalysis on test
  Invalidating analysis: LazyValueAnalysis on main
  Invalidating analysis: MemorySSAAnalysis on main
  Invalidating analysis: LazyValueAnalysis on main
  Invalidating analysis: LoopAnalysis on main
  Invalidating analysis: PhiValuesAnalysis on main
  Invalidating analysis: MemoryDependenceAnalysis on main
  Invalidating analysis: DemandedBitsAnalysis on main
  Invalidating analysis: CallGraphAnalysis on /mnt/DATA/LLVM/llvm-project/build_dyn_debug/sample1_O3.ll
  ; Function Attrs: nofree nounwind uwtable
  define dso_local void @test(i32 %a) local_unnamed_addr #0 !dbg !20 {
  entry:
    call void @llvm.dbg.value(metadata i32 %a, metadata !25, metadata !DIExpression()), !dbg !26
    %cmp = icmp sgt i32 %a, 0, !dbg !27
    br i1 %cmp, label %if.then, label %if.end, !dbg !29

    if.then:                                          ; preds = %entry
    ; 1 = MemoryDef(liveOnEntry)
    %puts = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @str, i64 0, i64 0)), !dbg !30
    br label %if.end, !dbg !32

    if.end:                                           ; preds = %if.then, %entry
    ; 2 = MemoryPhi({entry,liveOnEntry},{if.then,1})
      ret void, !dbg !33
  }
  test: /mnt/DATA/LLVM/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h:138:llvm::ilist_iterator<OptionsT, IsReverse, IsConst>::reference llvm::ilist_iterator<OptionsT, IsReverse, IsConst>::operator*() const [with OptionsT = llvm::ilist_detail::node_options<llvm::BasicBlock, true, false, void>; bool IsReverse = false; bool IsConst = false; llvm::ilist_iterator<OptionsT, IsReverse, IsConst>::reference = llvm::BasicBlock&]: Assertion `!NodePtr->isKnownSentinel()' failed.
  Abandon (core dumped)

[编辑] 这是堆栈跟踪

  libc.so.6!__GI_raise(int sig) (/build/glibc-eX1tMB/glibc-2.31/sysdeps/unix/sysv/linux/raise.c:50)
  libc.so.6!__GI_abort() (/build/glibc-eX1tMB/glibc-2.31/stdlib/abort.c:79)
  libc.so.6!__assert_fail_base(const char * fmt, const char * assertion, const char * file, unsigned int line, const char * function) (/build/glibc-eX1tMB/glibc-2.31/assert/assert.c:92)
  libc.so.6!__GI___assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) (/build/glibc-eX1tMB/glibc-2.31/assert/assert.c:101)
  libLLVMCore.so.13git!llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::BasicBlock, true, false, void>, false, false>::operator*(const llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::BasicBlock, true, false, void>,false, false> * const this) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h:138)
  libLLVMCore.so.13git!llvm::simple_ilist<llvm::BasicBlock>::front(llvm::simple_ilist<llvm::BasicBlock> * const this) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/ADT/simple_ilist.h:138)
  libLLVMCore.so.13git!llvm::Function::front(llvm::Function * const this) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/Function.h:772)
  libLLVMCore.so.13git!llvm::Function::getEntryBlock(llvm::Function * const this) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/Function.h:749)
  libLLVMCore.so.13git!llvm::GraphTraits<llvm::Function*>::getEntryNode(llvm::Function * F) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/CFG.h:350)
  libLLVMCore.so.13git!llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::GetEntryNode(const llvm::DominatorTreeBase<llvm::BasicBlock, false> & DT) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h:344)
  libLLVMCore.so.13git!llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::FindRoots(const llvm::DominatorTreeBase<llvm::BasicBlock, false> & DT, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdatePtr BUI) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h:356)
  libLLVMCore.so.13git!llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::BasicBlock, false> & DT, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdatePtr BUI) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h:578)
  libLLVMCore.so.13git!llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false> & DT) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h:1563)
  libLLVMCore.so.13git!llvm::DominatorTreeBase<llvm::BasicBlock, false>::recalculate(llvm::DominatorTreeBase<llvm::BasicBlock, false> * const this, llvm::DominatorTreeBase<llvm::BasicBlock, false>::ParentType & Func) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/Support/GenericDomTree.h:780)
  libLLVMCore.so.13git!llvm::DominatorTreeAnalysis::run(llvm::DominatorTreeAnalysis * const this, llvm::Function & F) (/mnt/DATA/LLVM12/llvm-project/llvm/lib/IR/Dominators.cpp:363)
  libLLVMPasses.so.13git!llvm::detail::AnalysisPassModel<llvm::Function, llvm::DominatorTreeAnalysis, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>::run(llvm::detail::AnalysisPassModel<llvm::Function, llvm::DominatorTreeAnalysis, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> * const this, llvm::Function & IR, llvm::AnalysisManager<llvm::Function> & AM) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:315)
  libLLVMCore.so.13git!llvm::AnalysisManager<llvm::Function>::getResultImpl(llvm::AnalysisManager<llvm::Function> * const this, llvm::AnalysisKey * ID, llvm::Function & IR) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:75)
  libLLVMAnalysis.so.13git!llvm::AnalysisManager<llvm::Function>::getResult<llvm::DominatorTreeAnalysis>(llvm::AnalysisManager<llvm::Function> * const this, llvm::Function & IR) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/PassManager.h:788)
  libLLVMAnalysis.so.13git!llvm::MemorySSAAnalysis::run(llvm::MemorySSAAnalysis * const this, llvm::Function & F, llvm::FunctionAnalysisManager & AM) (/mnt/DATA/LLVM12/llvm-project/llvm/lib/Analysis/MemorySSA.cpp:2329)
  libLLVMPasses.so.13git!llvm::detail::AnalysisPassModel<llvm::Function, llvm::MemorySSAAnalysis, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>::run(llvm::detail::AnalysisPassModel<llvm::Function, llvm::MemorySSAAnalysis, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> * const this, llvm::Function & IR, llvm::AnalysisManager<llvm::Function> & AM) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:315)
  libLLVMCore.so.13git!llvm::AnalysisManager<llvm::Function>::getResultImpl(llvm::AnalysisManager<llvm::Function> * const this, llvm::AnalysisKey * ID, llvm::Function & IR) (/mnt/DATA/LLVM12/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:75)
  llvm::AnalysisManager<llvm::Function>::getResult<llvm::MemorySSAAnalysis>(llvm::AnalysisManager<llvm::Function> * const this, llvm::Function & IR) (/mnt/DATA/LLVM12/install_dyn_debug/include/llvm/IR/PassManager.h:788)
  main(int argc, char ** argv) (/mnt/DATA/Merce/project/erlvaltic/clang/tool/main.cpp:380)

[/编辑]

这是代码:

#include <iostream>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"   
#include "llvm/Support/SourceMgr.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Analysis/MemorySSA.h"
using namespace llvm;

int main(int argc, char *argv[])
{
  if (argc != 2)
  {
    std::cerr << "Usage: " << argv[0] << " ll_filename" << std::endl;
    return 1;
  }
  StringRef filename = argv[1];

  LLVMContext Context;
  SMDiagnostic Err;
  auto m = parseIRFile(filename, Err, Context);
  if (m) {
    std::cout << "Successfully read Module:" << std::endl;
    std::cout << " Name: " << m->getName().str() << std::endl;
    std::cout << " Target triple: " << m->getTargetTriple() << std::endl;

    llvm::PassBuilder passBuilder;
    llvm::LoopAnalysisManager loopAnalysisManager(true); // true is just to output debug info
    llvm::FunctionAnalysisManager functionAnalysisManager(true);
    llvm::CGSCCAnalysisManager cGSCCAnalysisManager(true);
    llvm::ModuleAnalysisManager moduleAnalysisManager(true);

    passBuilder.registerModuleAnalyses(moduleAnalysisManager);
    passBuilder.registerCGSCCAnalyses(cGSCCAnalysisManager);
    passBuilder.registerFunctionAnalyses(functionAnalysisManager);
    passBuilder.registerLoopAnalyses(loopAnalysisManager);
   
    passBuilder.crossRegisterProxies(
        loopAnalysisManager, functionAnalysisManager, cGSCCAnalysisManager, moduleAnalysisManager);
        llvm::ModulePassManager modulePassManager =
    passBuilder.buildPerModuleDefaultPipeline(llvm::PassBuilder::OptimizationLevel::O3);
    modulePassManager.run(*m, moduleAnalysisManager);

    FunctionAnalysisManager &FAM =
        moduleAnalysisManager.getResult<FunctionAnalysisManagerModuleProxy>(*m).getManager();
    auto &functionList = m->getFunctionList();
    for (auto &function : functionList) {
        auto &MSSA = FAM.getResult<MemorySSAAnalysis>(function).getMSSA();
        MSSA.dump();
    }   
  }
  else {
    std::cout << "Error while reading module" << std::endl;
  }
  return 0; 
}

关于发生了什么以及如何解决这个问题的任何帮助? 为什么分析无效?

谢谢

[编辑2] 看来这个问题与我的 IR 文件中的一些调试信息有关。发生核心转储的第二个函数是:

  ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
  declare void @llvm.dbg.value(metadata, metadata, metadata) #1
  

[/EDIT2]

这似乎不是代码的问题,而是具有调试信息的输入数据的问题(请参阅问题中的 EDIT2)