Getting Started with LLVM Core Libraries阅读笔记

Getting Started with LLVM Core Libraries

目录

  • 1 Build and Install LLVM
  • 2 External Projects
  • 3 Tools and Design
  • 4 Frontend
  • 5 LLVM IR
  • 6 Backend
  • 7 JIT
  • 8 交叉编译
  • 9 Clang静态分析
  • 10 LibTooling

Build and Install LLVM

External Projects

  1. Clang extra tools
  2. Compiler-RT
  3. DragonEgg
  4. LLVM test suite
  5. LLDB
  6. libc++

Tools and Design

Frontend

  1. 使用libclang
  2. 理解Clang diagnostics
  3. the frontend phases:
    1. Lexical analysis
    2. Syntactic analysis(AST)
      1. TranslationUnitDecl
        1. TypedefDecl
        2. FunctionDecl
      2. CFG
    3. Semantic analysis

LLVM IR

  1. syntax
    1. Module
    2. Function
    3. BasicBlock
    4. Instruction
    5. use-def与def-use链
      1. Value
      2. User
  2. generator
  3. IR级优化:pass
    1. -Ox
    2. -print-stats
    3. 理解pass间依赖:
      1. e.g. Loop Info and Dominator Tree
    4. 理解pass API
    5. 定制pass

Backend

  1. TableGen
  2. SelectionDAG
  3. Scheduler
  4. MachineInstr
  5. Register allocation
  6. Prologue and epilogue
  7. MCInst

JIT

  1. ExecutionEngine
  2. llvm::JIT / llvm::MCJIT
  3. RTDyldMemoryManager
    1. allocateCodeSection() allocateDataSection()
    2. getSymbolAddress() 外部库中符号的地址
    3. finalizeMemory()
  4. JITCodeEmitter < MachineCodeEmitter
  5. JITMemoryManager
  6. JITResolver 处理还未编译的目标函数(生成stub?)
  7. TargetJITInfo
    1. replaceMachineCodeForFunction
    2. relocate
    3. emitFunctionStub
  8. <Target>CodeEmitter
  9. OwningPtr<ExecutionEngine> EE(EngineBuilder(M).create());
    1. Function *SumFn = M->getFunction("sum");
    2. int (*Sum)(int, int) = (int (*)(int, int))EE->getPointerToFunction(SumFn);
  10. $ clang++ sum-jit.cpp -g -O3 -rdynamic -fno-rtti $(llvm-config --cppflags --ldflags --libs jit native irreader) -o sum-jit
  11. 传递一般的参数:GenericValue //不知道这里是怎么自动调整栈的?
  12. 新的MCJIT
    1. MCJIT::finalizeObject() //看起来这里强调了对象的生命周期管理
    2. ObjectBuffer ObjectCache ObjectImage
      1. RuntimeDyldImpl::loadObject()
      2. RuntimeDyld::getSymbolLoadAddress()
    3. MCJIT::emitObject()

交叉编译

  1. build,host,target
  2. Multilib
  3. Cross Linux from Scratch http://trac.cross-lfs.org
  4. There are complete development boards emulated by QEMU.(完全仿真的开发板?不错耶)

Clang静态分析

  1. (后端指令生成的)性能优化 & (基于前端AST的)静态分析,编译器技术的两大法宝!
  2. 竞争对手:HP Fortify and Synopsis Coverity
  3. exponential-time complexity,不支持inter-module analysis
  4. e.g. forward dataflow analysis
    1. 给变量符号关联一些属性,然后在后面用到的地方检查约束是否满足
    2. False positives:往往导致程序员忽略所有的警告信息
  5. symbolic execution engine
    1. 经过一个分支的时候,直接把if条件作为假设,往下进一步推理(靠)
  6. clang -cc1 --analyze –analyzer-checker=<package>与clang --analyze -Xanalyzer ...
  7. 可用的checker:
    1. alpha.core.BoolAssignment, alpha.security.MallocOverflow, alpha.unix.cstring.NotNullTerminated
    2. core.NullDereference, core.DivideZero, core.StackAddressEscape
    3. cplusplus.NewDelete
    4. debug.DumpCFG, debug.DumpDominators, debug.ViewExplodedGraph
    5. llvm.Conventions
    6. security.FloatLoopCounter, security.insecureAPI.UncheckedReturn, ...
    7. unix.API, unix.Malloc, unixMallocSizeof, unix.MismatchedDeallocator
  8. -fsyntax-only
  9. scan-build
    1. $ scan-build gcc -c joe.c -o joe.o
    2. $ scan-view <ouput_dir>
    3. 实际的例子:
      1. $ scan-build ../httpd-2.4.9/configure -prefix=$(pwd)/../install
      2. $ scan-build make
  10. 扩展
    1. ProgramState, ProgramPoint, ExplodedGraph
      1. 程序状态不可变?
    2. To save space, this graph is folded:llvm::FoldingSetNode(引用计数?)
    3. 挑战:how to model the memory behavior(别名问题)
      1. lvalue -> memory region -> binding -> symbolic value
    4. class ReactorChecker : public Checker<check::PostCall> {
      1. ...
      2. void checkPostCall(const CallEvent/*最近的一次函数调用*/ &Call, CheckerContext &C) const;
        1. if (Call.getCalleeIdentifier() == ...
    5. p241 The mutable keyword should only be used for mutexes or such caching scenarios.
    6. K, 新checker需要用TableGen语法来注册?? lib/StaticAnalyzer/Checkers/Checkers.td

LibTooling

  1. 生成一个命令数据库
    1. $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../ 嗯?
  2. 理解/使用基于LibTooling的工具:Clang Tidy/Modernizer/Apply Replacements/Format/Query, Modularize, PPTrace(Clang Extra Tools)
    1. clang-tidy
      1. $ clang-tidy -checks="llvm-*" file.cpp
    2. 重构工具:
      1. Clang Modernizer(革命性的?):生成“迁移到C++ 11”的Source-to-Source修改建议
      2. Clang Apply Replacements
        1. 数据结构:clang::tooling::Replacement(YAML格式?避免解析处理patch文件)
        2. 例:$ clang-modernize -loop-convert -serialize-replacements test.cpp --serialize-dir=./
          1. => $ clang-apply-replacements ./
      3. 来自LibFormat的功能:-style=<LLVM|Google|Chromium|Mozilla|Webkit>
      4. ClangFormat:转换IOCCC,强制编码规范(Java里怎么就没这样的命令行工具?)
      5. Modularize
        1. $ readelf -s screen.o
        2. 要求符号的类型信息:C头文件?
        3. p261 条件宏给编译器带来了不必要的头文件重复解析负担
        4. 模块化与import关键词?(让我想起了D语言了)
      6. Module Map Checker
        1. $ module-map-checker module.modulemap 确保覆盖了所有.h头文件
      7. PPTrace(预处理的跟踪输出)
      8. Clang Query:查询AST,同时对AST matchers做测试
        1. clang-query> match callExpr()
      9. Clang Check(只有几百行代码?)
        1. $ clang-check program.c -ast-dump -- (使用程序数据库或在--后提供编译参数)
      10. Remove c_str() calls
  3. 构建代码重构工具:libclang / plugins / LibTooling
    1. Dissecting tooling boilerplate code:ParseCommandLineOptions
    2. Using AST matchers
      1. clang-query> match methodDecl(hasName("walk"))
      2. clang-query> match recordDecl(isSameOrDerivedFrom(hasName("Animal")))
      3. clang-query> match recordDecl(hasMethod(methodDecl(hasName("walk"))))
        1. 根据名字来做匹配?支持正则表达式吗
      4. clang-query> match memberCallExpr(callee(memberExpr(member(hasName("walk")))))
      5. clang-query> match memberCallExpr(callee(memberExpr(member(hasName("walk")))), thisPointerType(recordDecl(isSameOrDerivedFrom(hasName("Animal")))))
        1. 这里的语法虽然能够工作,但非常笨拙!
      6. Putting the AST matcher predicates in C++ code
    3. Writing the callbacks
      1. tooling::Replacements *Replace;
      2. const CXXMethodDecl *method = matchResult.Nodes.getNodeAs<CXXMethodDecl>("methodDecl");
        匹配得到的是一个AST Node?
      3. Replace->insert(Replacement(*matchResult.SourceManager,
        CharSourceRange::getTokenRange(SourceRange(method->getLocation())), NewMethodName)); 

你可能感兴趣的:(C++,阅读,llvm)