loopinfo 必须通过 functionanalysismanager 显式获取,不能用已弃用的 getanalysis;遍历时需检查 getheader() 和 getlooppreheader() 是否为空,否则可能断言失败。

必须显式请求 LoopInfo 分析,不能直接用 getAnalysis 获取未注册的分析结果。
LoopInfo 必须通过 FunctionAnalysisManager 获取
LLVM 新 Pass 管理器(NPM)下,LoopInfo 不再是 FunctionPass 的隐式依赖。你得先在 run 函数签名里声明它,再通过 FAM.getResult<loopanalysis>(F)</loopanalysis> 拿到实例。
- 错误写法:
getAnalysis<loopinfowrapperpass>()</loopinfowrapperpass>—— 这是旧 Pass 管理器(OOPM)接口,新代码中已弃用,会编译失败或运行时崩溃 - 正确入口:
LoopInfo &LI = FAM.getResult<loopanalysis>(F);</loopanalysis>,其中FAM是传入的FunctionAnalysisManager & - 需要 include:
#include "llvm/Analysis/LoopAnalysis.h"和#include "llvm/Analysis/LoopInfo.h"
遍历 Loop 时注意嵌套顺序和 header 块有效性
LoopInfo 返回的是按深度递增排列的 Loop* 列表,内层循环优先。但不是每个 Loop* 都有合法的 getHeader() —— 比如某些人工构造或未规范化的 IR 可能导致 header 为 nullptr。
- 务必检查:
if (!LP->getHeader()) continue;,否则后续调用LP->getBlocks()或LP->getLoopPreheader()可能触发断言失败 -
LP->getBlocks()返回的是该 loop 直接包含的基本块,不含子 loop 块;要获取完整嵌套结构,需递归调用LP->getSubLoops() - 若需访问 preheader,用
LP->getLoopPreheader()而非手动找前驱——后者可能返回空,而该函数内部已处理了 canonical 化逻辑
常见错误:在 non-canonical loop 上调用 getLoopPreheader()
getLoopPreheader() 仅对 simplified canonical loop 保证非空。如果 IR 中循环没有 preheader(例如多个 entering block、header 有多个前驱),该函数返回 nullptr,但不会报错,容易被忽略。
- 典型现象:你的 Pass 在某个函数上 crash 或跳过循环,但
opt -loops显示存在 loop —— 很可能是 preheader 缺失导致空指针解引用 - 安全做法:总是判空,或提前用
LoopSimplifyPass(-loop-simplify)规范化 IR;该 Pass 会自动插入 preheader、拆分 latch 等 - 命令行验证:
opt -loop-simplify -analyze -loops input.ll,对比前后输出中是否新增了<pre class="brush:php;toolbar:false;" header></pre>标记
真正麻烦的不是找不到 loop,而是找到的 loop 缺少 header 或 preheader 却没做防护——这类问题在线上 IR 处理中极易静默失败,且只在特定优化级别或前端生成的 IR 上复现。











