当前位置: 首页 > news >正文

cetos做网站360网站建设基本情况

cetos做网站,360网站建设基本情况,wordpress添加播放器代码,江苏网页定制Getting Started with LLVM Core Libraries 参考1 LLVM是构架编译器(compiler)的框架系统#xff0c;以C编写而成#xff0c;用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time)#xff0c;对开…Getting Started with LLVM Core Libraries 参考1 LLVM是构架编译器(compiler)的框架系统以C编写而成用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time)对开发者保持开放并兼容已有脚本。 工具和设计 追溯llvm的历史要追溯到10年前2014起初它着眼于编译器的后端算法和中间表述今天依然是llvm的重点当时其他部分还要依赖gcc。其中最重要的是它的IRllvm在整个编译的过程中有很多种中间表示如AST(C/C转换成IR的过程)、DAG(IR转换成特定机器的汇编语言的过程)、某种特定的中间表示(汇编器和链接器使用)等其他中间表示依然起到很重要的作用但是真正让llvm与众不同的还是它的IR甚至llvm这个名字的由来还和IR有很大的关系。 首先看IR(intermediate representation)的特点 SSA signal static assignment 静态单赋值 三地址码 无限多个寄存器其存在方式有两种一种在内存中一种是在磁盘上SSA能够更方便的优化再加上保存在磁盘上的这种编码方式能够达到几近全时优化的效果这也是llvm的作者在最早介绍llvm的论文中提出的目标但是IR的描述能力毕竟有限要想实现全时优化就要求对诸如程序分布这种行为做出描述这也意味着实现了此功能的llvm要像jvm那样能够成为一个运行平台类似jvm的名字llvm这个名字就是这么来的。 随着llvm项目的发展其设计目标已经重点放在了通过磁盘上的IR操作实现链接时优化等功能而不是全时优化最终只保留了llvm这个名字但是llvm已经成了一个强大的编译器框架而不是一个类似jvm的那样的平台。 说到这说一下个人理解吧感觉是llvm起初提出了一个比较精妙的编码表示方案有利于一些编译优化进而发现可以憧憬的的目标——全时优化但是又发现实现全时优化比较困难在llvm的mail list上有人专门就此发起了一个很详细的讨论详细阐述了llvm不能像java那样成为一个platform或者vm的原因重点还是要做编译器。 不管怎样llvm这么名字还是保留下来了现在如果有人跟你提起“LLVM”可能是指以下内容 整个LLVM Project/框架 由LLVM框架构造的编译器 LLVM框架的可重用代码库 LLVM IRLLVM框架主要包括三个方面的核心内容 前端(frontend):将源码转换成中间代码(IR),包括词法分析、语法分析、语义分析、中间代码生成IR中间表示 两种方式readable和binary-encoded后端(backend):将IR转换成汇编代码包括寄存器分配每个步骤中间交互有两种介质1) in-memory; 2) by-file前者变现出来通过一些高层的工具如clang自动进行指定的动作后者可以每一步每一步分离开来通过一个个独立的工具完成。 前端可以使用不同的编译工具对代码文件做词法分析以形成抽象语法树AST然后将分析好的代码转换成LLVM的中间表示IRintermediate representation中间部分的优化器只对中间表示IR操作通过一系列的pass对IR做优化后端负责将优化好的IR解释成对应平台的机器码。LLVM的优点在于中间表示IR代码编写良好而且不同的前端语言最终都转换成同一种的IR。 为什么使用三段式设计优势在哪里首先解决一个很大的问题假如有N种语言C、OC、C、Swift…的前端同时也有M个架构模拟器、arm64、x86…的target是否就需要N*M个编译器三段式架构的价值就提现出来了通过共享优化器的中转很好的解决了这个问题。 LLVM编译一个源文件的过程 预处理 - 词法分析 - Token - 语法分析 - AST - 代码生成 - LLVM IR - 优化 - 生成汇编代码 - Link - 目标文件 完全需要我们手工或者依靠其他工具如lex, yacc来做的事情是从源代码到token的词法分析和从token到AST的语法分析词法分析的输出是将源代码解析成一个个的token。这些token就是有类型和值的一些小单元比如是关键字还是数字还是标识符从AST转LLVM开始LLVM就开始提供一系列的工具帮助我们快速开发。从IR(中间指令代码)到DAG(有向无环图)再到机器指令针对常用的平台LLVM有完善的后端。也就是说我们只要完成了到IR这一步后面的工作我们就享有和Clang一样的先进生产力了。 CodeGen负责将语法树从顶至下遍历翻译成LLVM IRLLVM IR是Frontend的输出也是LLVM Backerend的输入桥接前后端。 笔记 External Projects 附加工具 Clang extra tools 前段附加工具 Compiler-RT 编译器运行时 DragonEgg 利用GCC(不仅支持类c语言解析) 得到 IR LLVM test suite 测试 LLDB 类 gdb 调试器 libc 底层运行时库 系统动态链接库Frontend 前段 Clang 1. 使用 libclang 2. 理解Clang diagnostics 3. the frontend phases词法分析 Lexical analysis语法分析 Syntactic analysisAST 抽象语法树TranslationUnitDecl 翻译单元TypedefDecl 类型定义FunctionDecl 函数定义CFG语义分析 Semantic analysis编译器架构的王者LLVM——4简单的词法和语法分析 使用 Lex和Yacc 词法分析: 在正则表达式已经成为基本技能的今天词法分析完全无门槛啊。正常情况下我们只要写一组正则表达式或者写个简单的状态机就可以了。 词法分析的输出是将源代码解析成一个个的token。这些token就是有类型和值的一些小单元比如是关键字还是数字还是标识符等等。这个阶段不用管它们是如何组合的都是干嘛的。 比如一个token类型是数值值是3. 这个信息就已经足够了至于这个3干嘛用后面整理AST的时候再放到合适的位置上去。 至于什么时上下文无关语言什么是确定有穷自动机非确定有穷自动机等等这些暂时都不需要了解。 语法分析 语法分析诚然是比词法分析要复杂一些。但是幸运的是对于绝大多数语句和表达式来讲并不需要高深的知识“移进-归约”是个好方法但是在我们学习的相当长的一段时期内都用不上。 语法分析的输出是抽象语法树AST既然是棵树自然构造时需要递归。所以在大部分的语句中我们只按递归下降的方法就足够了。 对于表达式递归下降还不够用至少运算符还有优先级啊。所以针对表达式我们还需要运算符优先分析法。SLRLALR和LR暂时还用不上。 ASTMatcher 抽象语法树匹配器 查找全局变量及其调用函数 参考 ASTMatcher 是 Clang 中用来帮助我们实现 code-to-code 的转译或者完成某些查询的工具。 ASTMatcher提供了一个领域特定语言DSL来创建基于Clang AST的谓词同时支持C这意味着允许用户编写一个程序来匹配AST节点并能通过访问节点的c接口来获取该AST节点的属性、源位置等任何信息。 其主要由宏与模板驱动用法和 函数式编程 及其类似。 ASTMatcher用来匹配AST的节点它通过调用构造函数创建也可以构建成一个ASTMatchers的树其内部可以嵌套多个ASTMatcher使得匹配更加具体准确。 所有匹配器都是名词描述实体并且可以绑定这样它们就会指向匹配到的内容。为此只需要在这些匹配器中调用 bind() 方法例 variable(hasType(isInteger())).bind(intvar);由于Clang AST中有上千个class我们显然不可能一个个去看去分析。 这时候我们要清楚一点使用ASTMatcher的前提是了解你想匹配的AST的样子。 通常情况下创建合适的ASTMatcher的策略如下 1. 寻找想匹配的节点的最外层的类 2. 在 AST Matcher Reference 中查看所写的Matcher要么匹配到需要的节点要么进行”细化”处理 3. 创建外部匹配表达式验证它是否按预期运行。 4. 为接下来你想匹配的内部节点检查匹配器。 5. 重复以上步骤,直到完成匹配器。示例代码 #includestdio.h int a; int main(){a 1;return 0; }clang 编译得到 AST clang -cc1 -ast-dump |-VarDecl 0xf4a0b8 F:\1.c:2:1, col:5 col:5 used a int -FunctionDecl 0xf4a160 line:3:1, line:6:1 line:3:5 main int ()-CompoundStmt 0xf4a248 col:11, line:6:1|-BinaryOperator 0xf4a200 line:4:1, col:5 int | |-DeclRefExpr 0xf4a1c8 col:1 int lvalue Var 0xf4a0b8 a int| -IntegerLiteral 0xf4a1e0 col:5 int 1-ReturnStmt 0xf4a238 line:5:1, col:8-IntegerLiteral 0xf4a218 col:8 int 0我们可以清楚的看到全局变量a对应的节点类型为 VarDecl 引用该变量处的节点类型为 DeclRefExpr 而DeclRefExpr 最外层有一层函数对应 FunctionDecl节点类型。 得到这些信息我们就可以总结出来”匹配模型”。 对于使用了的全局变量我们找它的引用这个引用需要对应于一个全局变量声明而且引用是在某个函数内部。这种模式下我们即可得到所有已使用了的全局变量的信息包括在哪个函数内部调用。 转换到AST 节点来看它首先是一个DeclRefExpr类型节点同时它对应于一个VarDecl全局节点而且这个DeclRefExpr节点在某个FunctionnDecl下。 因此我们写出如下的Matcher StatementMatcher GlobalVarMatcher declRefExpr(to(varDecl(hasGlobalStorage()).bind(gvarName) // 变量引用declRefExpr -- 全局变量varDecl 节点绑定为 “gvarName”) // to, hasAncestor(functionDecl().bind(function) // 该节点其外层有函数定义 则绑定到 ”function”) ).bind(globalReference); // declRefExpr节点绑定到字符串”globalReference” 在上述Matcher中为匹配特定AST节点我们把匹配的varDecl节点绑定到字符串“gvarName”functionDecl节点绑定到字符串”function”declRefExpr节点绑定到字符串”globalReference”以便稍后在匹配回调中检索。 获取匹配节点 定义了matcher后将需要添加更多的工具来运行它们。Matchers与MatchCallback配对并注册一个MatchFinder对象然后从一个ClangTool运行。 LLVM IR 中间表达 1. 语法syntaxa. Module: Module类声明了一个迭代器可以遍历module中的functionb. Function:Function对象可能是函数声明可能是函数定义获取这两个不同对象的内容可调用不同的函数。使用isDeclaration()方法check对象是否是函数声明包含函数原型.通过getArgumentList()方法或是用arg_iterator迭代器遍历可获得函数参数。函数定义 遍历函数内容(Function::iterator i function. begin(), e function.end(); i ! e; i) c. BasicBlock 基本块 Basic Block类BB中包含了一系列指令可以通过getTerminator()方法获取最后一条指令。以通过CFG例如通过getSinglePredecessor()方法访问前一个BB。d. Instruction 指令它的确切功能可以通过getOpcode来获取它返回代表LLVM IR操作码的llvm::Instruction枚举的成员。也可以通过op_begin()和op_end()来获取操作数这两个方法继承自User类。3层概念Function::iterator -- BasicBlock::iterator -- i-getOpcodeName()e. use-def与def-use链【很重要的两个类——Value类和User类】个继承了Value类的类意味着类内定义了可能被其他类使用的结果一个继承了User类的类意味着这个实体可能使用了一个或多个Value接口。ValueValue类定义了use_begin()和use_end()方法用于遍历Users访问def-use链即访问所有使用了value的user。User2. 生成器 generator 3. IR级优化pass-Ox-print-stats理解pass间依赖e.g. Loop Info and Dominator Tree理解pass API定制pass优化pass管理器 LLVMPassManagerRef PM: unwrap(PM)-add(pass);The ImmutablePass classPass类的函数getAnalysisIfAvailable()、getAnalysis()、getAnalysisID()这三个常用的函数也都是在这个头文件中使用的。Pass之间的交互是会经常用到这样的函数的。 ModulePass class 模块pass 类 增加/删除 函数 处理MetaData元数据在函数之外CallGraphSCCPass class FunctionPass class 函数pass类 处理函数内部的信息LLVM::Function类 getName() 成员函数 取得了函数的名字virtual bool runOnFunction(Function F) 是 FunctionPass class 的虚函数 一个FunctionPass的子类要想做一些实际的工作就必须对这个虚函数进行实现。注册pass static RegisterPassHello X(hello, Hello World Pass); 对hello PASS进行注册只有PASS进行了注册之后才可以进行使用。HELLO PASS LoopPass class 循环pass类 RegionPass class BasicBlockPass class 基本快pass类 MachineFunctionPass class LVM类 功能 LLVMContext 上下文类基本是最核心的保存上下文符号的类 环境相关部分如Contexts Module 模块类一般一个文件是一个模块里面有函数列表和全局变量表 Function 函数类函数类生成出来就是一个C函数 Constant 常量类各种常量的定义都是从这里派生出来的 Value 各值类型的基类几乎所以的函数、常量、变量、表达式都可以转换成Value型 Type 类型类表示各种内部类型或用户类型每一个Value都有个getType方法来获取其类型。 BasicBlock 基本块一般是表示一个标签注意这个块不是嵌套形式的结构而是每个块结尾可以用指令跳转 到其他块类似C语言中的标签的功能Values中使用最多就是常量Constant从上图可以看到Constant主要可以概括为以下几个部分: 标量常量Scalar Constants比如整形常量ConstantInt浮点型常量ConstantFP 组合常量Composite Constants比如常量结构体ConstStruct常量数组ConstantDataArray等 常量表达式Constant Expressions主要是ConstantExpr这个类该类有一个及其重要的API接口getGetElementPtr用来从多元素常量中获取首地址比如获取数组字符串的首地址 全局值Global Values是全局变量和函数值的间接基类换而言之就是全局值包括全局变量GlobalVariable和函数Function全局值都有一个很重要的属性就是连接属性 全局变量Global Variables 全局别名Global Aliases 函数值Function values首先要介绍的是LLVM类型系统的使用因为LLVM的每条语句都是带有类型的LLVM语句可以转换成Value型指针那么我们用如下的方法就可以获取到当前value的类型 Type* t value-getType();Type类型也很容易使用例如获取其指针就可以 PointerType* ptr_type t-getPointerTo(); // 获取指向 Type类型数据的指针type类型中还有很多静态函数可供生成基本类型 / 获取基本类型 static Type * getVoidTy (LLVMContext C) static Type * getFloatTy (LLVMContext C) static Type * getDoubleTy (LLVMContext C) static Type * getMetadataTy (LLVMContext C)// 获取不同长度整形类型 static IntegerType * getInt8Ty (LLVMContext C) static IntegerType * getInt16Ty (LLVMContext C) static IntegerType * getInt32Ty (LLVMContext C) static IntegerType * getInt64Ty (LLVMContext C)// 获取指向不同类型的指针类型 static PointerType * getFloatPtrTy (LLVMContext C, unsigned AS0) static PointerType * getDoublePtrTy (LLVMContext C, unsigned AS0) static PointerType * getInt8PtrTy (LLVMContext C, unsigned AS0) static PointerType * getInt16PtrTy (LLVMContext C, unsigned AS0) static PointerType * getInt32PtrTy (LLVMContext C, unsigned AS0) static PointerType * getInt64PtrTy (LLVMContext C, unsigned AS0) Backend 后端 1. TableGen 生成LLVM后端代码生成器LLVMcodegenerator) LLVM编译时会调用TableGen的工具产生相应的类 2. SelectionDAG 拓扑排序/线性化‘指令调度’ 3. Scheduler 调度器 4. MachineInstr 5. Register allocation 寄存器分配 6. Prologue and epilogue 7. MCInst运行时 JIT Just-In-Time Compiler是一种动态编译中间代码的方式根据需要在程序中编译并执行生成的机器码能够大幅提升动态语言的执行速度。 JIT引擎的工作原理并没有那么复杂本质上是将原来编译器要生成机器码的部分要直接写入到当前的内存中然后通过函数指针的转换找到对应的机器码并进行执行。 但实践中往往需要处理许多头疼的问题例如内存的管理符号的重定向处理外部符号相当于要处理编译器后端的诸多复杂的事情真正要设计一款能用的JIT引擎还是非常困难的。 当然基本的功能是提供一款解释器的底层工具将LLVM字节码解释执行具体能够做的事例如可以制作一款跨平台的C插件系统使用clang将C/C代码一次编译到.bc字节码然后在各个平台上解释运行。也可以制作一款云调试系统联网远程向系统注册方法获取C客户端的debug信息等等。当然还有很多其他的用法等着大家来开发。 制作LLVM字节码的解释器还是非常简单的最棒的示例应该是LLVM源码中的工具lli 一共700行左右的C代码调用LLVM工具集实现了LLVM字节码JIT引擎如果想很好的学习llvm中的解释器和JIT可以参考其在 lli 交叉编译 仿真平台 QEMU Clang静态分析 1. 后端指令生成的性能优化 基于前端AST的静态分析编译器技术的两大法宝 2. 竞争对手HP Fortify and Synopsis Coverity 3. exponential-time complexity不支持inter-module analysis 4. forward data flow analysis 数据流分析给变量符号关联一些属性然后在后面用到的地方检查约束是否满足False positives往往导致程序员忽略所有的警告信息
http://www.huolong8.cn/news/296468/

相关文章:

  • 部署iis网站网站负责人备案采集照具体要求
  • 南通哪些公司做网站北京网站设计济南兴田德润评价
  • 网站设计图wordpress首页分类标题
  • 无锡 做网站网页制作需要什么基础
  • 珠海建设网站公司哪家好人才网站建设
  • 技术先进的网站建设公大企业网站建设公司排名
  • 佳木斯哈尔滨网站建设灯罩技术支持东莞网站建设
  • 邯郸网站建设邯郸网站制作厦门关键词优化平台
  • 西安 网站建设 培训班html门户网站开发源代码
  • 百度怎么收录网站asp.net 新建网站
  • 怎么更换网站模板邵武建设局网站
  • 可信网站认证 代理商护肤网站的功能设计
  • 深圳网站建设优化城阳网站建设培训
  • 100个免费推广网站下载京东的网络营销方式
  • 网站内页做排名福州网站建设资讯
  • 网站建设相关行业有哪些正规营销型网站建设公司
  • 南通设计网站建设360建筑网怎么删除简历
  • 郑州市的实惠推广网站百度商桥网站代码去哪里添加
  • 系统网站怎么做网站开发jquery
  • 自适应网站如何做mip网站后台管理系统软件
  • 网站制作建设公司哪家好开鲁网站seo免费版
  • asp企业网站如何在电脑安装wordpress
  • 做网站需要软件做网站网页需要学些什么
  • 上海网站建设外包公司企业网站开发定制
  • 咸宁网站seo颐高养生园网站建设
  • wordpress站点后台wordpress主题下载
  • 怎样申请做c c 网站wordpress 添加xml
  • 网站开发有什么技术要求调用wordpress的文章编辑器
  • 西宁网站运营公司海外电商有哪些平台
  • 小说网站防盗做的好处推广普通话的内容简短