ExpandLargeDivRem
这个 Pass(ExpandLargeDivRem)的主要作用,是在 LLVM 后端针对那些 位宽超过目标硬件或配置所能直接支持的整数除法/取余指令(div/rem),将它们“拆解”成对外部自动生成函数的调用,从而保证在不支持大整数除法的架构上也能正确地执行。具体来说:
检测不支持的指令
在遍历函数中的所有 UDiv、SDiv、URem、SRem 指令时,先读取目标子系统(TargetLowering)报告的最大可合法处理位宽,或者使用用户通过 -expand-div-rem-bits 强制设置的阈值。如果除法/取余操作的位宽超过该阈值,则认定为“超大”指令需要特殊处理。
跳过简单情况
对于常数幂二的除数(如除以 8、16 等),后端往往有专门的移位或乘法优化,所以这里不做拆分。
可扩展向量类型暂不支持,只有定长向量会被拆解。
向量指令的标量化(scalarize)
如果指令作用于一个向量(VectorType),先将其拆成若干条标量除法/取余,然后把结果再插回到向量中,这一步收集生成新的 BinaryOperator,后续一起处理。
调用库 ...