扩展LLVM:添加指令、内部函数、类型等

  1. Introduction and Warning
  2. Adding a new intrinsic function
  3. Adding a new instruction
  4. Adding a new SelectionDAG node
  5. Adding a new type
    1. Adding a new fundamental type
    2. Adding a new derived type

Introduction and Warning

在使用LLVM的过程中,可能希望为研究项目或实验定制它。此时,可能意识到需要向LLVM添加一些内容,不管是新的基本类型、新的内在函数还是全新的指令。

当意识到这一点时,停下来想想。真的需要扩展LLVM吗?它是LLVM在其当前化身中不支持的一个新的基本功能,还是可以从已经存在的LLVM元素合成它?如果不确定,询问LLVM dev列表。原因是,扩展LLVM将涉及到更新所有不同的传递,使用扩展,并且有许多LLVM分析和转换,所以这可能是相当多的工作。

添加内部函数比添加指令容易得多,并且对优化过程是透明的。如果添加的功能可以表示为函数调用,则内部函数是LLVM扩展的首选方法。

在投入大量的精力在一个非常重要的扩展上之前,先问一下想要做的事情是否可以用已经存在的基础架构来完成,或者也许其他人已经在做了。这样做会节省很多时间和精力。

Adding a new intrinsic function

向LLVM添加一个新的内部函数比添加一个新的指令要容易得多。几乎所有对LLVM的扩展都应该从一个内在函数开始,然后在有必要的情况下转换为指令。

llvm/docs/LangRef.html:记录内部。确定它是否特定于代码生成器,以及限制是什么。

llvm/include/llvm/Intrinsics*.td:为内在函数添加一个条目。描述它的内存访问特性以进行优化(控制它是否是DCE'd、CSE'd等)。请注意,tblgen将llvm_int_ty type用于参数的任何内在函数,都将被tblgen视为重载,并且在内部函数的名称上需要相应的后缀。              llvm/lib/Analysis/ConstantFolding.cpp:如果可以常量折叠内部函数,请在canConstantFoldCallTo和ConstantFoldCall函数中添加对它的支持。

llvm/test/Regression/*:将测试用例添加到测试套件中

一旦内在函数被添加到系统中,就必须为其添加代码生成器支持。

通常必须执行以下步骤:

在lib/Target/CBackend中添加对C后端的支持/

根据内在特性,有几种方法可以实现这一点。对于大多数intrinsic,在llib/CodeGen/IntrinsicLowering.cpp的LowerIntrinsicCall中添加代码来降低内部函数是有意义的。

第二,在所有情况下将内部代码降低到扩展的C代码序列是有意义的,那么只需在Writer.cpp中的visitCallist中发出。如果内在函数有某种方式可以用GCC(或任何其它编译器)扩展来表示,那么可以根据编译CBE输出的编译器来有条件地支持它(参见llvm.prefetch示例)。

第三,如果内在函数真的没有降低的方法,只需让代码生成器发出打印错误消息的代码,并在执行时调用abort。

将选择的目标文件lib/Target/*/*.td添加到目标文件中。

通常是向.td文件中添加一个与内在模式匹配的模式的问题,尽管很明显,可能还需要添加要生成的指令。在PowerPC和X86后端中有许多示例可以遵循。

Adding a new SelectionDAG node

与内部函数一样,向LLVM添加一个新的SelectionDAG节点比添加一个新的指令要容易得多。通常会添加新节点来帮助表示多个目标通用的指令。这些节点通常映射到LLVM指令(add,sub)或内在(byteswap,population count)。在其他情况下,添加了新的节点以允许许多目标执行一个共同的任务(在浮点和整数表示之间转换)或在单个节点中捕获更复杂的行为(旋转)。

include/llvm/CodeGen/SelectionDAGNodes.h:为新的SelectionDAG节点添加枚举值。

lib/CodeGen/SelectionDAG/SelectionDAG.cpp:添加代码以将节点打印到getOperationName。如果在给定常量参数时可以在编译时对新节点求值(例如用另一个常量添加一个常量),请找到接受适当数量参数的getNode方法,并将节点的大小写添加到switch语句中,该语句对采用与新节点相同数量参数的节点执行常量折叠。

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:根据需要添加代码以使节点合法化、升级和扩展。需要在LegalizeOp中为节点添加case语句,该语句将对节点的算子调用LegalizeOp,并在任何算子因合法化而更改时返回新节点。可能并非SelectionDAG框架支持的所有目标都会在本机支持新节点。在这种情况下,还必须在LegalizeOp中的节点case语句中添加代码,以便将节点扩展为更简单、合法的操作。将余数展开为除法、乘法和减法的ISD::UREM就是一个很好的例子。

Adding a new instruction

警告:添加指令会更改位码格式,需要一些努力才能保持与以前版本的兼容性。只有在绝对必要时才添加指令。

l  llvm/include/llvm/Instruction.def: add a number for your instruction and an enum name为指令添加数字和枚举名称

l  llvm/include/llvm/Instructions.h: add a definition for the class that will represent your instruction为将表示指令的类添加定义

l  llvm/include/llvm/Support/InstVisitor.h: add a prototype for a visitor to your new instruction type为新的指令类型添加访问者原型

l  llvm/lib/AsmParser/Lexer.l: add a new token to parse your instruction from assembly text file添加一个新的标记来解析程序集文本文件中的指令

l  llvm/lib/AsmParser/llvmAsmParser.y: add the grammar on how your instruction can be read and what it will construct as a result添加语法,说明如何读取指令以及它将作为结果构造什么

l  llvm/lib/Bitcode/Reader/Reader.cpp: add a case for your instruction and how it will be parsed from bitcode为指令添加大小写,以及如何从位代码解析它

l  llvm/lib/VMCore/Instruction.cpp: add a case for how your instruction will be printed out to assembly添加一个案例,说明如何将指令打印到程序集

l  llvm/lib/VMCore/Instructions.cpp: implement the class you defined in llvm/include/llvm/Instructions.h实现在llvm/include/llvm/Instructions.h中定义的类

l  测试你的指令

l  Test your instruction

l  llvm/lib/Target/*: Add support for your instruction to code generators, or add a lowering pass. 向代码生成器添加对指令的支持,或添加降低传递。

l  llvm/test/Regression/*: add your test cases to the test suite. 将测试用例添加到测试套件中。

Adding a new type

警告:添加新类型会更改位码格式,并将破坏与当前现有LLVM安装的兼容性。只有在绝对必要时才添加新类型。

Adding a fundamental type

l  llvm/include/llvm/Type.h: add enum for the new type; add static Type* for this type

l  llvm/lib/VMCore/Type.cpp: add mapping from TypeID => Type*; initialize the static Type*

l  llvm/lib/AsmReader/Lexer.l: add ability to parse in the type from text assembly

l  llvm/lib/AsmReader/llvmAsmParser.y: add a token for that type

Adding a derived type

l  llvm/include/llvm/Type.h: add enum for the new type; add a forward declaration of the type also

l  llvm/include/llvm/DerivedTypes.h: add new class to represent new class in the hierarchy; add forward declaration to the TypeMap value type

l  llvm/lib/VMCore/Type.cpp: add support for derived type to:

l  std::string getTypeDescription(const Type &Ty,

l    std::vector<const Type*> &TypeStack)

l  bool TypesEqual(const Type *Ty, const Type *Ty2,

l    std::map<const Type*, const Type*> & EqTypes)

  1. add necessary member functions for type, and factory methods

l  llvm/lib/AsmReader/Lexer.l: add ability to parse in the type from text assembly

l  llvm/lib/BitCode/Writer/Writer.cpp: modify void BitcodeWriter::outputType(const Type *T) to serialize your type

l  llvm/lib/BitCode/Reader/Reader.cpp: modify const Type *BitcodeReader::ParseType() to read your data type

l  llvm/lib/VMCore/AsmWriter.cpp: modify

void calcTypeName(const Type *Ty,

std::vector<const Type*> &TypeStack,

std::map<const Type*,std::string> &TypeNames,

std::string & Result)

to output the new derived type

最新文章

  1. Linux No volume control GStreamer plugins and/or devices found
  2. 清空表数据 mysql让主键从1开始
  3. du -sh
  4. http://www.cnblogs.com/xwdreamer/archive/2012/02/21/2360818.html
  5. 小猪猪逆袭成博士之C++基础篇(三)字符串
  6. C#开发模式——单例模式
  7. apache日志管理【转】
  8. node.js连接MySQL操作及注意事项
  9. 数据结构基础(3) --Permutation &amp; 插入排序
  10. .NET开发微信小程序-微信支付
  11. HTTP协议09-响应首部字段
  12. SQL Server异常汇总
  13. Mac 安装微软雅黑字体
  14. poj1511,线段树扫描线面积
  15. SAS DATA ENCODING 解决odbc乱码问题
  16. struts2 18拦截器详解(十)
  17. javascript console自动点击页面元素
  18. 基于 Flutter 以两种方式实现App主题切换
  19. Js 过滤emoji表情...持续补充中..
  20. ny236 心急的C小加 hdoj1051 Wooden Sticks

热门文章

  1. 【golang】golang 相关问题?
  2. Android动态调试so库JNI_Onload函数-----基于IDA实现
  3. Ubuntu下修改Nexus 5的boot.img--改user模式为debug模式
  4. 1.简单认识PHP和环境搭建
  5. Intel汇编程序设计-整数算术指令(中)
  6. IDEA 这样设置,好看到爆炸!!!
  7. Cmder右键配置
  8. queryset惰性与缓存
  9. [C] gcc
  10. x小结:certutil -hashfile D:\1.exe MD5