不能跳过llvm前端和中端只运行后端流水线,因后端严格依赖合法化(legalize)后的selectiondag输入;llc仅支持通过-filetype等参数截断输出,不支持独立执行单个后端阶段。

怎么跳过LLVM前端和中端,只跑后端流水线
不能直接“只跑后端流水线的一部分”,因为LLVM后端(llvm::TargetMachine驱动的CodeGen)严格依赖合法、已验证、且已完成Legalize的SelectionDAG输入。你无法把任意IR丢给llc并指定“从Instruction Selection开始”。真正可控的切口只有两个:输入形态(bitcode vs. IR)和后端阶段开关。
llc -march=xxx 背后实际触发哪些后端阶段
llc默认会走完整后端流水线:IR → SelectionDAG → MachineDAG → MachineInstr → MCInst → asm/object。但你可以用参数显式截断:
-
-filetype=asm:停在汇编文本生成,不进MC层 -
-filetype=obj:生成目标文件,必须完成全部后端阶段(含重定位信息填充) -
-debug-pass=Structure+-debug-only=isel:只打印指令选择阶段日志,不跳过任何阶段 -
-run-pass=instruction-select:这个参数**无效**——LLVM没有提供单阶段执行模式,它只是让PassManager加载该Pass并运行,但前提仍是整条流水线已启动
想真正只做寄存器分配或指令调度,得换接口
如果你的目标是单独调试RegisterAllocation或InstructionScheduling,llc不是合适工具。正确路径是写一个最小LLVMTargetMachine实例,在代码里手动调用:
-
getTargetLowering()->LowerFormalArguments():拿到SelectionDAG后,可调用DAG->CombineAll模拟部分legalization -
SelectionDAGISel::runOnMachineFunction():这是指令选择入口,调用后MF.getFrameInfo()和MF.getRegInfo()才可用 -
MachineScheduler::schedule():需先有MachineBasicBlock和MachineInstr链表,不能跳过InstructionSelection -
LiveIntervals::runOnMachineFunction():寄存器分配前必经的活跃区间分析,依赖完整的MachineInstr序列
换句话说:所有后端阶段都强依赖前序输出,不存在“独立运行某Pass”的工程接口。强行绕过只会触发assert(0 && "DAG not scheduled")或MachineInstr not in function这类错误。
最容易被忽略的硬性前提:IR必须已Legalize
即使你用opt -O2把IR优化完,它仍可能含ISD::SDIV、ISD::VSETCC等未被目标支持的操作码。后端在SelectionDAGBuilder阶段就会abort。常见报错:
LLVM ERROR: Cannot select: t10: i64 = sdiv t8, t9Cannot select vector comparison
解决方法只有两个:TargetLowering::LowerOperation()里实现对应降级逻辑,或提前用llc -march=xxx -mcpu=yyy -O2全程跑通一次,观察-debug-only=isel输出里哪些节点被Lower了——这才是真实可行的“裁剪”边界。











