LLVM怎么为一个新架构添加最小可用后端

落墨酱_2192

落墨酱_2192

2026-10-08

161人浏览

原创

llvm新后端最简注册需三步:定义myarch.td目标、用registertarget注册getthemyarchtarget()、在cmakelists.txt中add_subdirectory(myarch);随后可绕过指令选择输出空汇编,再通过ret指令实现首条汇编生成。

llvm怎么为一个新架构添加最小可用后端

LLVM 新后端最简注册:只让 llc 不报错

想让 LLVM 认识一个新架构,第一步不是写指令、不是配寄存器,而是让它能“看见”这个目标。否则 llc -march=myarch 会直接报 error: invalid target 'myarch'。这一步只需三类文件:目标描述(.td)、注册入口(TargetInfo.cpp 和 TargetMachine.cpp)和 CMake 声明。

关键点在于 TargetRegistry::RegisterTarget 调用必须在链接时可见,且 getTheMyArchTarget() 符号不能被 strip。常见坑是忘了在 CMakeLists.txt 中把新目录加进 add_subdirectory,或者 TargetInfo.cpp 没实现 getTheMyArchTarget() 返回非空指针。

  • 新建 llvm/lib/Target/MyArch/MyArch.td,至少包含 def MyArch : Target;
  • 在 MyArchTargetInfo.cpp 中调用 RegisterTarget,传入 getTheMyArchTarget() 地址
  • 在 MyArchTargetMachine.cpp 中定义 getTheMyArchTarget() 并返回全局静态实例
  • 确保 llvm/lib/Target/CMakeLists.txt 包含 add_subdirectory(MyArch)

生成空汇编输出:绕过指令选择与寄存器分配

注册成功后,llc -march=myarch test.ll 仍会失败,典型错误是 SelectionDAG has not been legalized yet 或 no instruction selector。此时不需要实现完整指令选择,只要让 SelectionDAG 阶段不崩溃即可。最轻量做法是继承 TargetLowering 并重写 LowerOperation,对所有操作返回原样节点(Op),再在 TargetMachine 中禁用寄存器分配。

这样做的效果是:IR → SelectionDAG(未 legal)→ 直接 emit 空汇编(或占位符)。它不产生有效代码,但能验证后端骨架是否加载、pass 流水线是否跑通。性能无关紧要,目标是快速获得可调试的上下文。

Aiva.ai
Aiva.ai

Aiva.ai是一款用于生成多风格原创曲目的 AI 音乐作曲助手。

下载
  • 在 MyArchTargetLowering.h 中继承 TargetLowering,构造函数调用 setOperationAction(ISD::ADD, MVT::i32, Expand) 等全部基础操作为 Expand
  • 重写 LowerOperation,统一返回 Op,避免触发未实现的 lowering 逻辑
  • 在 MyArchTargetMachine.cpp 的 createPassConfig 中,跳过 addRegAllocPass 和 addISelPass
  • 用 llc -march=myarch -O0 -filetype=asm test.ll 验证是否输出空 .text 段

添加最简指令选择:从 ret void 开始

空输出只能帮你确认流程,真正迈出第一步是让一条最简单的 IR 指令生成对应汇编。推荐从 ret void 入手,因为它不依赖参数传递、栈帧、寄存器映射等复杂机制。你需要的最小集是:MyArchInstrInfo.td 定义一条 RET 指令、MyArchAsmPrinter.cpp 实现汇编打印、以及 MyArchISelDAGToDAG.cpp 把 ISD::RET 映射过去。

注意 TableGen 生成的 *GenInstrInfo.inc 必须被正确包含,否则 getRetOpcode() 会返回 0 导致断言失败。另一个易错点是 AsmPrinter 的 printInstruction 没覆盖 MyArch::RET 枚举值,导致 fallback 到未实现分支而 abort。

  • MyArchInstrInfo.td 中定义 def RET : InstMyArch<...> { let Pattern = [(ret)]; }</...>
  • MyArchAsmPrinter.cpp 的 printInstruction 加 case MyArch::RET: O
  • MyArchISelDAGToDAG.cpp 的 select 函数中匹配 Node->getOpcode() == ISD::RET,然后 CurDAG->getMachineNode(MyArch::RET, ...)
  • 运行 llc -march=myarch -O0 test.ll,输入 IR 为 define void @f() { ret void },应输出 ret

为什么 statepoint 和 relocation 在初期可以忽略

Native Image 的 LLVM 后端文档明确提到,Graal 生成的 bitcode 会包含 statepoint 指令用于 GC 安全点,且最终对象文件需支持重定位(relocation)才能链接。但对纯 LLVM 新后端开发而言,这两项不是启动障碍——它们属于“运行时兼容性”问题,而非“编译链路打通”问题。

你可以在没有 statepoint lowering 的情况下生成汇编(Graal 不会发给你的后端带 statepoint 的 bitcode,除非你主动启用 GC 支持);重定位则由 MCObjectStreamer 和 MCExpr 层处理,只要不用 -filetype=obj 就不涉及。换句话说:先搞定 -filetype=asm,再考虑 obj;先支持裸函数返回,再支持 GC 安全点。

  • statepoint 是 JVM/GC 语义相关,纯 C/Rust 前端生成的 IR 默认不含它
  • 重定位只在生成目标文件(.o)时生效,汇编输出(.s)无需处理符号重定位
  • GraalVM Native Image 的 LLVM 后端要求你提供 statepoint lowering,但那是 Graal+LLVM 协同场景,非标准 LLVM 后端开发起点
  • 初期用 clang --target=myarch 不可行,因为 clang 还不知道 myarch,所以必须从 .ll 输入开始
实际动手时,最容易卡住的地方不是写代码,而是构建系统没把新目录纳入编译范围,或者 tblgen 没重新生成 .inc 文件就直接编译。每次改完 .td,记得跑一遍 make -j4(或 ninja),观察日志里有没有 Building MyArchGen*.inc 这类行。没有,说明 TableGen 步骤根本没触发。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2323

5

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

6090

13

后端的主要工作内容介绍
后端的主要工作内容介绍

后端是应用程序的服务端部分,负责核心任务,如数据库交互、业务逻辑处理和响应客户端请求。想了解更多后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

5446

10

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

2026.10.08

0

20

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

80

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

80

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

100

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程