LLVM Cookbook

链接

https://blog.csdn.net/qq_23599965/article/details/88344459

 

https://github.com/zy445566/llvm-guide-zh

万花筒:用LLVM实现语言(备注:万花筒(Kaleidoscope)是LLVM实现的语言名称)

  • 万花筒:教程简介和Lexer
  • 万花筒:实现解析器和AST
  • 万花筒:代码生成到LLVM IR
  • 万花筒:添加JIT和优化器支持
  • 万花筒:扩展语言:控制流程
  • 万花筒:扩展语言:用户定义的运算符
  • 万花筒:扩展语言:可变变量
  • 万花筒:编译为目标代码
  • 万花筒:添加调试信息
  • 万花筒:结论和其他有用的LLVM花絮

在LLVM中构建JIT

  • 构建JIT:从KaleidoscopeJIT开始
  • 构建JIT:添加优化 - ORC层的介绍
  • 构建JIT:按函数惰性编译
  • 构建JIT:极端懒惰 - 使用从AST编译JIT的编译回调
  • 构建JIT:远程JITing - 远程处理隔离和懒惰

LLVM’s Analysis and Transform Passes

  • Introduction

  • Analysis Passes
    • -aa-eval: Exhaustive Alias Analysis Precision Evaluator
    • -basicaa: Basic Alias Analysis (stateless AA impl)
    • -basiccg: Basic CallGraph Construction
    • -count-aa: Count Alias Analysis Query Responses
    • -da: Dependence Analysis
    • -debug-aa: AA use debugger
    • -domfrontier: Dominance Frontier Construction
    • -domtree: Dominator Tree Construction
    • -dot-callgraph: Print Call Graph to “dot” file
    • -dot-cfg: Print CFG of function to “dot” file
    • -dot-cfg-only: Print CFG of function to “dot” file (with no function bodies)
    • -dot-dom: Print dominance tree of function to “dot” file
    • -dot-dom-only: Print dominance tree of function to “dot” file (with no function bodies)
    • -dot-postdom: Print postdominance tree of function to “dot” file
    • -dot-postdom-only: Print postdominance tree of function to “dot” file (with no function bodies)
    • -globalsmodref-aa: Simple mod/ref analysis for globals
    • -instcount: Counts the various types of Instructions
    • -intervals: Interval Partition Construction
    • -iv-users: Induction Variable Users
    • -lazy-value-info: Lazy Value Information Analysis
    • -libcall-aa: LibCall Alias Analysis
    • -lint: Statically lint-checks LLVM IR
    • -loops: Natural Loop Information
    • -memdep: Memory Dependence Analysis
    • -module-debuginfo: Decodes module-level debug info
    • -postdomfrontier: Post-Dominance Frontier Construction
    • -postdomtree: Post-Dominator Tree Construction
    • -print-alias-sets: Alias Set Printer
    • -print-callgraph: Print a call graph
    • -print-callgraph-sccs: Print SCCs of the Call Graph
    • -print-cfg-sccs: Print SCCs of each function CFG
    • -print-dom-info: Dominator Info Printer
    • -print-externalfnconstants: Print external fn callsites passed constants
    • -print-function: Print function to stderr
    • -print-module: Print module to stderr
    • -print-used-types: Find Used Types
    • -regions: Detect single entry single exit regions
    • -scalar-evolution: Scalar Evolution Analysis
    • -scev-aa: ScalarEvolution-based Alias Analysis
    • -stack-safety: Stack Safety Analysis
    • -targetdata: Target Data Layout
  • Transform Passes
    • -adce: Aggressive Dead Code Elimination
    • -always-inline: Inliner for always_inline functions
    • -argpromotion: Promote ‘by reference’ arguments to scalars
    • -bb-vectorize: Basic-Block Vectorization
    • -block-placement: Profile Guided Basic Block Placement
    • -break-crit-edges: Break critical edges in CFG
    • -codegenprepare: Optimize for code generation
    • -constmerge: Merge Duplicate Global Constants
    • -constprop: Simple constant propagation
    • -dce: Dead Code Elimination
    • -deadargelim: Dead Argument Elimination
    • -deadtypeelim: Dead Type Elimination
    • -die: Dead Instruction Elimination
    • -dse: Dead Store Elimination
    • -functionattrs: Deduce function attributes
    • -globaldce: Dead Global Elimination
    • -globalopt: Global Variable Optimizer
    • -gvn: Global Value Numbering
    • -indvars: Canonicalize Induction Variables
    • -inline: Function Integration/Inlining
    • -instcombine: Combine redundant instructions
    • -aggressive-instcombine: Combine expression patterns
    • -internalize: Internalize Global Symbols
    • -ipconstprop: Interprocedural constant propagation
    • -ipsccp: Interprocedural Sparse Conditional Constant Propagation
    • -jump-threading: Jump Threading
    • -lcssa: Loop-Closed SSA Form Pass
    • -licm: Loop Invariant Code Motion
    • -loop-deletion: Delete dead loops
    • -loop-extract: Extract loops into new functions
    • -loop-extract-single: Extract at most one loop into a new function
    • -loop-reduce: Loop Strength Reduction
    • -loop-rotate: Rotate Loops
    • -loop-simplify: Canonicalize natural loops
    • -loop-unroll: Unroll loops
    • -loop-unroll-and-jam: Unroll and Jam loops
    • -loop-unswitch: Unswitch loops
    • -loweratomic: Lower atomic intrinsics to non-atomic form
    • -lowerinvoke: Lower invokes to calls, for unwindless code generators
    • -lowerswitch: Lower SwitchInsts to branches
    • -mem2reg: Promote Memory to Register
    • -memcpyopt: MemCpy Optimization
    • -mergefunc: Merge Functions
    • -mergereturn: Unify function exit nodes
    • -partial-inliner: Partial Inliner
    • -prune-eh: Remove unused exception handling info
    • -reassociate: Reassociate expressions
    • -reg2mem: Demote all values to stack slots
    • -sroa: Scalar Replacement of Aggregates
    • -sccp: Sparse Conditional Constant Propagation
    • -simplifycfg: Simplify the CFG
    • -sink: Code sinking
    • -strip: Strip all symbols from a module
    • -strip-dead-debug-info: Strip debug info for unused symbols
    • -strip-dead-prototypes: Strip Unused Function Prototypes
    • -strip-debug-declare: Strip all llvm.dbg.declare intrinsics
    • -strip-nondebug: Strip all symbols, except dbg symbols, from a module
    • -tailcallelim: Tail Call Elimination
  • Utility Passes
    • -deadarghaX0r: Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
    • -extract-blocks: Extract Basic Blocks From Module (for bugpoint use)
    • -instnamer: Assign names to anonymous instructions
    • -verify: Module Verifier
    • -view-cfg: View CFG of function
    • -view-cfg-only: View CFG of function (with no function bodies)
    • -view-dom: View dominance tree of function
    • -view-dom-only: View dominance tree of function (with no function bodies)
    • -view-postdom: View postdominance tree of function
    • -view-postdom-only: View postdominance tree of function (with no function bodies)
    • -transform-warning: Report missed forced transformations

 LLVM opt 选项 优化

LLVM Cookbook_第1张图片

其他的优化选项还有

  • adce: Aggressive Dead Code Elimination
  • bb-vectorize: Basic-Block Vectorization
  • constprop: Simple constant propagation
  • dce: Dead Code Elimination
  • deadargelim: Dead Argument Elimination
  • globaldce: Dead Global Elimination
  • globalopt: Global Variable Optimizer
  • gvn: Global Value Numbering
  • inline: Function Integration/Inlining
  • instcombine: Combine redundant instructions
  • licm: Loop Invariant Code Motion
  • loop: unswitch: Unswithch Loop
  • loweratomic: Lower atomic intrinsics to non-atomic form
  • lowerinvoke: Lower invokes to calls, for unwindless code generators
  • lowerswitch: Lower SwithcInsts to branches
  • mem2reg: Promote Memory to Registry
  • memcpyopt: MemCpy Optimization
  • simplifycfg: Simplify the CFG
  • sink: Code sinking
  • tailcallelim: Tail Call Elimination

可以在源码目录 test/Transforms/下找到测试代码。



作者:peteyuan
链接:https://www.jianshu.com/p/b0d8431cbab1
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

ADCE(Aggressive Dead Code Elimination).

https://dongaxis.github.io/2016/05/31/LLVM-optimization-ADCE/

迭代标记有哪些其他的指令使用了会被使用的指令

简单的描述一下算法:

  1. 假设存在这样一个集合worklist, 这个集合里面的所有的指令都是一定会被使用的;
  2. 那么我们遍历这个指令, 并将这个集合中的所有的指令标为有效。
  3. 假设当前遍历出来的指令为X, 那么检查当前有哪些其他的指令使用了这条指令, 并将使这些指令标记为有效, 最后吧这些指令加入worklist;
  4. 循环执行1, 如果worklist为空, 那么停止循环。
  5. 最后遍历所有的指令, 删除没有被标记为有效的指令。

 

3.4 -bb-vectorize:基本块向量化

此pass将基本块中的指令组合成向量指令。它遍历每个基本块,试图对兼容的指令进行配对,重复这个过程,直到没有为向量化选择额外的配对。当某对相容指令的输出被另一对相容指令用作输入时,这些对就是潜在向量化链的一部分。只有当指令对是长度超过某个阈值的链的一部分时,才会融合到向量指令中。此外,pass尝试为每对兼容指令找到可能的最佳链。这些启发式方法旨在防止向量化在不会提高结果代码性能的情况下发生。
--------------------- 

 

3.18 -gvn:全局值编号

此pass执行全局值编号,以消除全部和部分冗余指令。它还执行冗余负载消除。

 

3.28 -licm:循环不变的代码移动

此pass执行循环不变的代码移动,尝试从循环体中删除尽可能多的代码。它可以将代码提升到preheader块中,或者如果安全的话,将代码下沉到exit块中。此pass还促进循环中必须别名的内存位置驻留在寄存器中,从而提升和降低“不变”负载和存储。
此pass使用别名分析有两个目的:

  1. 将循环不变的加载和调用移出循环。如果我们能够确定循环内的加载或调用不会对存储的任何东西进行别名,我们就可以像其他指令一样提升或降低它。
  2. 内存的标量提升。如果在循环内部有一个存储指令,我们将尝试将存储移动到循环之后,而不是在循环内部。只有在以下几个条件为真时才会发生这种情况:
    1. 所存储的指针是循环不变的。
    2. 循环中没有可能别名指针的存储或加载。循环中没有对指针进行mod/ref的调用。

如果这些条件为真,我们可以提升指针循环中的加载和存储,以使用临时alloca 'd变量。然后,我们使用mem2reg功能为变量构造适当的SSA表单。

 

 

 

 

你可能感兴趣的:(LLVM Cookbook)