1、查看控制流图的方法
a) 对于中间表达的 *.ll 文件
opt -dot-cfg before-indvars.ll
dot -Tpng .p.dot -o tmp.png
b) 在调试过程中,可以使用F.
viewCFG()
接口先获取相应的*.dot文件,之后雷同
参考:
自动向量化调试过程查看CFG流图_CanaanLeeN的博客-CSDN博客
2、dominate 信息可以根据CFG计算获取,但是重新计算比较耗时间。如果非常确定的一些变更,也可以直接使用接口addNewBlock及changeImmediateDominator之类进行微调, 可以通过
DT->viewGraph ()
接口获取dominate 信息, 参考
updateDominatorTree
a) addNewBlock 一般对一个不存在于DT的Node,新增添加
b) changeImmediateDominator 一般作用于已经在DT中的边,进行变更调整
参考
https://www.youtube.com/watch?v=bNV18Wy-J0U
3、比较指令对应signed/unsigned有不同的名称,参考
https://web.sonoma.edu/users/f/farahman/sonoma/courses/es310/310_arm/lectures/Chapter_6_BRANCH_ARM.pdf
4、
Condition Codes 和 SVE Predicate condition flags 有不同的含义
,注意区分,参考
https://www.stonybrook.edu/commcms/ookami/support/_docs/Arm_SVE_reduced.pdf
5、llvm中使用接口IsSameAsFreshTree确认更新前后tree结构的一致性,可以使用
p DT->print(errs())
接口打印当前的状态,需要配置
set overload-resolution off
如果遇到
注意:p DT->verify (DominatorTree::VerificationLevel::Fast) 中
Freshly computed tree:
为DT->changeImmediateDominator调整前的形态,而
Current:
是调整后的状态
参考emitMinimumIterationCountCheck,其中ReplaceInstWithInst能调整
Freshly computed tree
对应的dominate信息,其本质是
调整BB->->getTerminator()的跳转指令
6、接口Create(LoopExitBlock, OldTerm)在OldTerm前插入一条指令的效果
7、需要注意SimplifyCFGOpt::simplifySwitch和SimplifyCFGOpt::simplifyCondBranch优化的策略,比如
simplifySwitch将swich优化为branch
, 然后branch又调整回Switch,将导致编译死循环,因此
需要同时对这两个函数进行策略调整
。参考
⚙ D87056 [POC] SVE/SVE2 implementation (LLVM 9)
8、在SimplifyCFGOpt::simplifyOnce->
simplifySwitch
中可以调整控制流,在SinkCommon也可以Sink指令
9、在 SinkCommonCodeFromPredecessors->canSinkInstructions中需要判断两个指令的操作数是否一致I->
isSameOperationAs
(I0)
10、在
SwitchToLookupTable
创建跳转表时,会创建default分支的处理
SI->getDefaultDest()
11、选项-passes=
‘simplifycfg<switch-to-lookup>‘
等效于-passes=simplifycfg –switch-to-lookup