LoopAnalysis
LoopAnalysis
IRLoop,包含以下几个关键概念:
- header: 循环的起始节点,同时也是回边指向的节点
- entering block: 指向header的基本块,不属于循环内
- latch: 循环内指向循环的基本块
- exiting block: 存在一条边从exiting block指向循环外
- exit block: exiting edge指向的基本块就是exit block, 不属于循环内
IRLoop有以下性质:
- 一个loop的header是唯一的:也就是说一个loop可以由它的header确定,一个节点最多也只能是一个loop的header
- loop之间可以嵌套:如一个大loop中包含一个小loop
- 两个loop不会交叉:两个loop要么不相交,要么是嵌套关系,永远不会只共享一部分节点。如下图中的两个loop,我们会将其结合视作一个loop
LoopInfo
该部分源码地址:https://llvm.org/doxygen/GenericLoopInfoImpl_8h_source.html#l00573
LoopInfo Pass会识别IR中的循环,流程如下:
- 后序遍历domTree,这样可以保证先找到内层的循环
- 遍历每个基本块,如果这个基本块支配它的某个前继节点,那么该基本块为header, 其前继节点为latch,边是back edge
- 以这个基本块为header开始找循环中的其他块以及该循环中的子循环,这部分的函数叫discoverAndMapSubloop
discoverAndMapSubloop的流程如下:
- 首先沿着latchBlock倒着往回找到循环中的所有block。
考虑到header的性质,循环中的所有块都被header支配,如果该header的循环中存在subloop,那么它们一定在header的支配域中。由于我们采用后序遍历,因此subloop一定先于header被遍历
- 遍历的block要么不在任何循环里,要么在一个已经发现的subloop中。对于不在任何循环中的block,我们直接将其加入当前header的loop,同时将其前继加入worklist中;对于已经在循环中的block,我们找到其最外层的subloop,然后设置嵌套关系,最后将subloop的header的前继加入worklist中。
最后完善循环嵌套关系:
- 沿着支配树的postOrder,将每个基本块加入循环
- 将每个基本块加入其对应的subLoop以及它所有祖先loop中,如果这个基本块是这个subloop的头部,那么说明该subloop中的所有块应该已经被遍历过了(postOrder),此时将该subLoop加入到它的父亲中,并调整其中blocks和它所拥有的subloops的顺序
其他的一些信息,如每个loop的latchBlock,ExitBlock等都可以根据上述信息辅助得出。
LCSSA
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ando's blog!