LLVM编译原理

LLVM编译原理

LLVM

LLVM是架构编译器的框架系统,以C++编写而成,用于优化任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time)。对开发者保持开放,并兼容已有脚本。

传统编译器设计

源码 Source Code + 前端 Frontend + 优化器 Optimizer + 后端 Backend(代码生成器 CodeGenerator)+ 机器码 Machine Code,如下图所示

图片

ios的编译器架构
OC、C、C++使用的编译器前端是Clang,Swift是swift,后端都是LLVM,如下图所示

图片

模块说明

前端 Frontend:编译器前端的任务是解析源代码(编译阶段),它会进行 词法分析、语法分析、语义分析、检查源代码是否存在错误,然后构建抽象语法树(Abstract Syntax Tree AST),LLVM的前端还会生成中间代码(intermediate representation,简称IR),可以理解为llvm是编译器 + 优化器, 接收的是IR中间代码,输出的还是IR,给后端,经过后端翻译成目标指令集

优化器 Optimizer:优化器负责进行各种优化,改善代码的运行时间,例如消除冗余计算等

后端 Backend(代码生成器 Code Generator):将代码映射到目标指令集,生成机器代码,并且进行机器代码相关的代码优化

示例代码:

#define add(a, b) a + b

int test(int a, int b)
{
   
    return a + add(b, 10);
}

int main()
{
   
    int a = test(1, 2);

    return 0;
}

一、预处理编译阶段

这个阶段主要是处理包括宏的替换,头文件的导入,可以执行如下命令,执行完毕可以看到头文件的导入和宏的替换

//在终端直接查看替换结果
clang -E main.m

//生成对应的文件查看替换后的源码
clang -E main.m >> main2.m

需要注意的是:

  • typedef 在给数据类型取别名时,在预处理阶段不会被替换掉

  • include在这部分中执行,执行后会引入对应的声明

#include 实质是什么?

预编译的时候copy include头文件的内容到当前行

被#include的header file中最常见的内容分为哪几类?

宏定义

typedef

包含别的头文件

inline函数定义

函数声明

struct,union,enum类型定义

(其实可以打开一个.h文件来看看,如 /user/include/stdio.h)

# 1 "main.m"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 412 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.m" 2


int test(int a, int b)
{
   
    return a + b + 10;
}

int main()
{
   
    int a = test(1, 2);
    return 0;
}

二、编译阶段

编译阶段主要是进行词法、语法等的分析和检查,然后生成中间代码IR

1、词法分析

预处理完成后就会进行词法分析,这里会把代码切成一个个token,比如大小括号、等于号还有字符串等,

  • 可以通过下面的命令查看
clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m

词法分析结果

int 'int'        [StartOfLine]  Loc=<main.m:2:1>
identifier &
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值