美文网首页
LLVM资料整理

LLVM资料整理

作者: 西西里铿锵 | 来源:发表于2019-07-26 15:20 被阅读0次
    • LLVM是模块化、可重用的编译器以及工具链技术的
    • GCC、LLVM、clang
    • 传统的编译器架构:前端-优化器(中间代码)-后端->机器代码
    • 不同的前端后端使用统一的中间代码LLVM Intermediate Representation(LLVM IR)
    • 如果需要支持一种新的编程语言,只要实现一个新的前端
    • 如果需要支持一种新的硬件设备,只要实现一个新的后端
    • 优化阶段使用统一的LLVM IR,不需要做修改
    • GCC 前端后端耦合在一起,需要每个都实现
    • LLVM现在被作为实现各种静态和运行时编译语言的通用基础架构(GCC家族、Java、.Net、Python、Ruby、Scheme、Haskell、D等)

    Clang

    • LLVM项目的一个子项目
    • 基于LLVM架构的C/C++/Objective-C编译
    • 相比GCC,Clang编译速度快(Debug模式下编译OC速度比GCC快三倍)、占用内存效(Clang生成的AST占用内存是GCC的1/5)、模块化设计(Clang基于库的模块化设计,易于IDE集成和其他用途的重用)、诊断信息可读性强(在编译过程种,Clang创建并保留了大量详细的元数据(metaData),有利于调试)
    • clang代码需要放在./llvm/tools下

    Clang+LLVM

    • 前端使用Clang进行词法分析、语法分析、语义分析、生成中间代码
    • 优化器和后端使用LLVM

    OC源文件的编译过程

    • 通过命令行查看编译过程:$ clang -ccc-print-phases main.m
    • 词法分析,生成token:$ clang -fmodules -E -Xclang -dump-tokens main.m
    • 生成语法树-AST:$ clang -fmodules -fsyntax-only -Xclang -ast-dump main.m

    LLVM IR

    LLVM IR有3种表现形式:

    • text:文本格式,$ clang -S -emit-llvm main.m
    • memory: 内存格式
    • bitcode:二进制格式,$ clang -C -emit-llvm main.m

    LLVM IR语法:

    • 注释以分号;开头
    • 全局标识符以@开头,局部标识符以%开头
    • alloca,在当前函数栈帧种分配内存
    • i32,32bit
    • align,内存对齐
    • load,读取数据
    • store,写入数据

    LLVM源码编译

    • 安装cmake和ninja,ninja可以直接从github下载解压到bin目录
    brew install cmake
    brew install ninja
    
    • 编译ninja模板:
    cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的安装路径
    
    • $ ninja
    • $ ninja install
    • 也可以生成xcode模板进行编译

    应用与实践

    libclang、libTooling

    clang插件开发

    Pass开发

    开发新的编程语言

    clang插件开发

    • 在llvm源码目录下clang/tools目录下开发,新建目录XXPlugin,在CMakeList.txt添加该目录
    • XXPlugin下新建一个cpp文件,新建一个txt,txt中添加这个cpp
    add_llvm_loadable_module(XXPlugin XXPlugin.cpp) 
    //如果又多个Plugin,都放在括号中,逗号分割
    
    • 在cpp中写一个class XXAction继承自PluginASTAction
    • 注册插件
    static FrontendPluginRegistry::Add<XXPlugin::XXAction>
    X("XXPlugin", "description");
    
    • 重写CreateASTConsumer和ParseArgs(直接返回true)两个方法
    • 定义一个Consumer类继承自ASTConsumer
    • 重写HandleTranslationUnit方法,该方法当Clang编译完语法树时调用
    • 编译完成后的dylb动态库放在Xcode中,Build Settings中Other C Flags添加该动态库路径以及插件名称,同时Compiler需要改成自己编译好的llvm编译器(Default自带编译器不允许加载插件)。如果重新编译插件代码生成dylb,使用这个插件的工程需要Clean重新加载插件。
    • 需要对Xcode进行Hack,才能修改默认编译器。下载XcodeHacking.zip,修改HackedClang文件中的ExecPath的路径为llvm本地路径。然后在XcodeHacking目录下执行命令
    $ sudo mv HackedClang.xcplugin `xcode-select -print-path`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
    $ sudo mv HackedBuildSystem.xcspec `xcode-select -print-path`/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications
    
    • 构造一个Consumer,用来抛出警告或错误信息
    • MatchFinder可以用来查找语法树上下文

    注:资料整理自MJ公开课。

    相关文章

      网友评论

          本文标题:LLVM资料整理

          本文链接:https://www.haomeiwen.com/subject/plcdrctx.html