IDOM(Immediate Dominator)

379 阅读2分钟

定义

在支配树(Dominator Tree)中,IDOM(Immediate Dominator)是指直接支配者,它是支配树中的一个节点,该节点在到达另一个节点的所有路径上都是该节点的最后一个共同祖先

换句话说,如果节点B的IDOM是节点A,那么在从程序入口到节点B的所有路径上,节点A都是最后一个出现在节点B之前的节点

例子


entry

|

A

/ \

B C

/ \ \

D E F

在这个图中,假设每个结点代表一个基本块(basic block) 或者一个指令

  • A 直接支配B和C,因为从entry到达B和C的所有路径都会经过 A

  • B 直接支配D和E,因为从entry到达D和E的所有路径都会经过B,但不会在到达B之前经过C

  • C 直接支配F,因为从entry到达F的所有路径都会经过C,但不会到达C之前经过B

在这个例子中:

  • D的IDOM是B,因为B是到达D的所有路径上的最后一个共同祖先

  • E的IDOM也是B,原因同上

  • F的IDOM是C,因为C是到达F的所有路径上的最后一个共同祖先

代码


function calculateIDOM(n: Node) {

    // 初始化每个节点的IDOM为其自身(或者对于入口节点是null)

    idom[n] = null;

    // 初始化队列

    queue = new Queue();

    // 将所有没有前驱的节点(例如入口节点)加入队列

    for each node n without a predecessor p {

        queue.add(n);

    }

    // 处理队列中的每个节点

    while (!queue.isEmpty()) {

        n = queue.remove();

        for each node m dominated by n {

            if (m is not a root node) {

                // 寻找m的所有前驱的IDOM的交集

                new_idom = findCommonDominatorOfPredecessors(m);

                if (new_idom != idom[m]) {

                    idom[m] = new_idom;

                    // 如果m的IDOM改变了,需要重新计算m支配的节点

                    queue.add(new_idom);

                }

            }

        }

    }

}

如果需要用代码来计算IDOM,通常可以通过以下算法:

  • 计算每个节点的支配者集合(dominance frontier)

  • 使用这个集合来计算IDOM