subtarget通过-mcpu=绑定芯片代号,由tablegen生成代码驱动枚举值(如riscv::rocket)控制后端行为;-mattr=可叠加修改默认特性;amdgpu用generation映射指令族而非具体型号;配置错误将静默降级为generic。

Subtarget通过-mcpu=参数绑定具体芯片代号
LLVM后端不靠硬编码判断CPU型号,而是把芯片差异抽象成可配置的子目标(Subtarget)——-mcpu=传入的值,会触发对应XXXSubtarget类的实例化,并驱动TableGen生成的XXXGenSubtargetInfo.inc完成特征解析。比如RISC-V后端中-mcpu=generic-rv64和-mcpu=rocket-rv64会走不同分支,前者启用基础RV64IMAFDC,后者额外开启+zicsr和+zifencei等扩展。
RISCVSubtarget::getGeneration()这类函数返回芯片代际标识
实际区分型号的核心逻辑藏在getGeneration()或类似接口里,它不返回字符串,而是枚举值,比如:
-
RISCV::Generic表示通用兼容模式 -
RISCV::Rocket对应SiFive Rocket核心微架构 -
RISCV::Sifive7指向SiFive U7系列SoC
这些枚举由RISCVFeatures.td中def FeatureRocket : SubtargetFeature这类定义驱动,最终影响HasRocket字段的布尔状态,进而控制指令选择、寄存器分配策略等后端行为。
多个-mattr=组合可覆盖-mcpu=默认特性
-mcpu=只提供一个基线配置,真正灵活的型号适配靠-mattr=叠加。例如:
llc -mtriple=riscv64-unknown-elf -mcpu=generic-rv64 -mattr=+zba,+zbb,-zbs input.ll
这表示:以generic-rv64为起点,显式启用Zba/Zbb扩展,同时禁用Zbs(即使generic默认包含它)。注意-mattr=中的+/-前缀必须明确,否则会被忽略;多个-mattr=参数会按顺序合并,后出现的覆盖先出现的同名特性。
AMDGPU后端用Generation枚举映射硬件代际而非具体型号
像AMDGPU这种支持大量GPU型号的后端,Generation枚举(R600、GFX9等)并不一对一对应某款显卡,而是代表指令编码族和微架构共性。例如GFX9涵盖Vega 10/20/Navi 1x,它们共享VI编码格式,但VOLCANIC_ISLANDS和GFX9都映射到SIEncodingFamily::VI,说明Subtarget区分的是“能用哪套指令集”,不是“是不是某张卡”。真要区分Navi 21和Navi 22,得靠subtargetEncodingFamily()之后的ST.hasMAFMA()这类细粒度查询。
Subtarget真正的复杂点在于:它既不是纯静态配置,也不是运行时探测——所有判断都在编译期完成,且依赖TableGen生成代码与C++逻辑的严格对齐。一旦Target.td里SubtargetFeature的FieldName和XXXSubtarget类字段名不一致,整个特性开关就失效,而这种错误不会报编译错误,只会静默降级为generic行为。











