0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

編譯器中的圖論算法是什么

汽車電子技術(shù) ? 來源:程序芯世界 ? 作者:coderSun ? 2023-03-02 16:08 ? 次閱讀

編譯器中的圖論算法

1. 前言

LLVM是一款開源的編譯器框架,近年來已經(jīng)逐漸超越GCC。

許多深度學(xué)習(xí)編譯框架TVM、Tensorflow XLA的后端也是使用的它。 正是由于其友好的Lisense,模塊化及統(tǒng)一的IR,使得其越來越流行。因此對(duì)LLVM的研究很有必要。

圖片

圖1. LLVM的應(yīng)用

文中介紹了LLVM中構(gòu)造支配樹的兩種算法,分別是SLT算法與Semi-NCA算法。構(gòu)造支配樹的算法,就是圖論在編譯器中的一個(gè)應(yīng)用。如果蛻去LLVM的外衣,相信很多參加過ACM比賽的選手應(yīng)該對(duì)支配樹的構(gòu)造很熟悉。

本文的目的是以一種通俗易懂的方式給需要了解這個(gè)算法的朋友一個(gè)感性的認(rèn)識(shí)。如果需要看原論文或者關(guān)于深度學(xué)習(xí)編譯器論文的可以后臺(tái)回復(fù)idom獲取。

2. 支配樹簡介

2.1 支配樹定義

對(duì)于一張有向圖(可以有環(huán)),我們規(guī)定一個(gè)起點(diǎn),從點(diǎn)到圖上另一個(gè)點(diǎn)可能存在多條路徑,對(duì)于從到的任意路徑中,都存在一個(gè)點(diǎn) ,即從到必須經(jīng)過,那么我們稱為的支配點(diǎn)。

用 表示離點(diǎn)最近的支配點(diǎn), 對(duì)于原圖除外,每一個(gè)點(diǎn),從向建一條邊,最后我們得到了一顆以為根的樹,這棵樹就是支配樹(Dominator tree)

2.2 支配樹在編譯器中的應(yīng)用

  • 計(jì)算支配邊界,構(gòu)造SSA
  • 循環(huán)不變量提升

更多應(yīng)用歡迎補(bǔ)充。

3. 基本概念

3.1 DFS樹

對(duì)圖進(jìn)行深度優(yōu)先遍歷得到的一顆樹稱為DFS樹。樹上的每一個(gè)節(jié)點(diǎn)都有一個(gè)按照深度優(yōu)先遍歷的順序得到的編號(hào)。

圖片

圖2.深度優(yōu)先搜索樹

如圖2所示,節(jié)點(diǎn)和實(shí)線虛線共同構(gòu)成了一個(gè)有向圖,對(duì)有向圖進(jìn)行深度優(yōu)先遍歷就形成了DFS樹。其中實(shí)線是DFS的樹邊。紅色數(shù)字表示按照深度優(yōu)先遍歷的順序得到的編號(hào),紅色字母表示該節(jié)點(diǎn)的半必經(jīng)節(jié)點(diǎn)。

3.2 樹邊與非樹邊

如果在DFS樹中存在一條由到的邊,則頂點(diǎn)是頂點(diǎn)的父節(jié)點(diǎn),這條邊稱為樹邊。

記作

如果在有向圖中存在一條到的邊,則頂點(diǎn)是頂點(diǎn)的前驅(qū)節(jié)點(diǎn)。注意要與父節(jié)點(diǎn)相區(qū)別,因?yàn)楦腹?jié)點(diǎn)是在DFS樹上存在由到的邊。到的邊中除去樹邊以外的邊稱作非樹邊。

的前驅(qū)節(jié)點(diǎn)記作

非樹邊記作

如圖2中是的父節(jié)點(diǎn)。到的邊為樹邊

3.3 祖先與完全祖先

是的祖先,如果在DFS樹中存在一條由到的路徑,可以等于。

記作

如圖2中都是的祖先,因?yàn)檫@些點(diǎn)都可以沿著實(shí)線邊(DFS樹邊)到點(diǎn)

是的完全祖先,如果在樹中存在一條由到的路徑,不等于。

記作

如圖2中都是的完全祖先,因?yàn)檫@些點(diǎn)都可以沿著實(shí)線邊(DFS 樹邊)到點(diǎn)。與祖先的唯一區(qū)別就是不包括自身。

3.4 橫跨邊與返祖邊

右子樹的節(jié)點(diǎn)指向左子樹節(jié)點(diǎn)的邊。橫跨邊的起點(diǎn)永遠(yuǎn)大與終點(diǎn)編號(hào),因?yàn)镈FS樹中右子樹的遍號(hào)永遠(yuǎn)大于左子樹的編號(hào)。

記作

如圖2所示,的這四條邊都是橫跨邊

子節(jié)點(diǎn)到其完全祖先的邊叫返祖邊。

記作

如圖2所示,這兩條邊都是返祖邊。

4. 半支配路徑與半支配節(jié)點(diǎn)

在求支配節(jié)點(diǎn)之前,我們首先需要了解半支配路徑,然后求出半必經(jīng)節(jié)點(diǎn)及必經(jīng)節(jié)點(diǎn),最終得到整個(gè)支配節(jié)點(diǎn)樹。

圖片

圖3. 求支配節(jié)點(diǎn)樹路線圖

4.1 半支配路徑

公式表示:

通俗解釋:

在DFS樹中存在一條路徑,如果這條路徑中(不包括起點(diǎn)和終點(diǎn))的每一個(gè)點(diǎn)的編號(hào)都大于終點(diǎn)的編號(hào),則該路徑為一條半支配路徑。

根據(jù)定義可以將半支配路徑分為兩類:

  • 樹邊半支配路徑

樹邊半支配路徑比較特殊,只包含兩個(gè)點(diǎn),這兩個(gè)點(diǎn)在一條樹邊上。

  • 非樹邊半支配路徑

非樹邊半支配路徑即路徑上指向終點(diǎn)的邊為非樹邊,這條非樹邊要么是橫跨邊要么是返祖邊。

如圖4所示,黃色加粗的線為樹邊半支配路徑,綠色和紫色是非樹邊半支配路徑,其中綠色邊含有橫跨邊,紫色邊含有返祖邊。

圖片

圖4. 半支配路徑示意圖

4.2 半支配節(jié)點(diǎn)

公式表示:

通俗解釋:

V的半支配節(jié)點(diǎn)為所有終點(diǎn)為V的半支配路徑中,起點(diǎn)值最小的那個(gè)。

因?yàn)榘胫渎窂接袃深?,一是樹邊半支配路徑,二是非樹邊半支配路徑,因此也可以將半支配?jié)點(diǎn)的求法化簡為這兩類

公式化簡:

根據(jù)圖形理解更加簡單:

其中黃色線對(duì)應(yīng)公式中的第(1)種情況

紫色線和綠色線對(duì)應(yīng)公式中的第(2)種情況

其中的可以取下圖中和兩種情況, 可以是綠色線或紫色線上的任意一個(gè)點(diǎn),包括或。綠色線或紫色線就是公式中的條件

圖片

圖5.支配節(jié)點(diǎn)的三種情況

求半支配節(jié)點(diǎn)的偽代碼

Create a DFS tree T.
semi(w) = w | w ∈ V
for w ∈ V ? {r} in reverse preorder by the DFS
    for v ∈ pred G (w)
        u = eval(v)
        if semi(u) < semi(w)
           semi(w) = semi(u)
    end for
    Link parent(w) and w
 end for

其中的 eval(v)就是在求黃色、紫色、綠色各條線上 semi 最小的點(diǎn)。因?yàn)槭菍?duì) DFS 樹進(jìn)行逆序,因此求 的時(shí)候紫色線和綠色線上各節(jié)點(diǎn)的 semi 值已經(jīng)是已知的了。

5. 支配節(jié)點(diǎn)與支配樹

LLVM在2017年之前采用的是SLT算法,新的版本使用的是semi-NCA算法。兩者都是在上一節(jié)介紹的半必經(jīng)節(jié)點(diǎn)的基礎(chǔ)上求得必經(jīng)節(jié)點(diǎn)。下文會(huì)分別對(duì)這兩種算法進(jìn)行介紹,并比較其時(shí)間復(fù)雜度。

5.1 SLT 算法

SLT算法會(huì)根據(jù)前文求出的半支配節(jié)點(diǎn)進(jìn)一步求出直接支配節(jié)點(diǎn)。

公式表示:

其中在

u

通俗解釋:

在DFS樹中,到的路徑上有一點(diǎn),的sdom值是該路徑上最小的點(diǎn),如果等于則等于,否則等于

下面的兩張圖是對(duì)求 idom 的公式兩種情況的一個(gè)總結(jié),可以讓我們的理解更加直觀。

公式中的情況1圖片公式中的情況2圖片

計(jì)算支配節(jié)點(diǎn)樹的偽代碼:

Create a DFS tree T.
for w ∈ V ? {r} in reverse preorder by the DFS
  Calculate semi dominator for w
  Add w to bucket of semi(w)
  while bucket of parent(w) is not empty do
    v = pop one element from the bucket
    u = eval(v)
    if semi(u) < semi(v) then
      idom(v) = u
    else
      idom(v) = semi(v)
    end if
  end while
end for
for w ∈ V ? {r} in preorder by the DFS do
  if idom(w) != semi(w) then
    idom(w) = idom(idom(w))
  end if
end for

以一個(gè)實(shí)例加深對(duì)SLT算法的理解:

圖片

  • a)此時(shí) semi(4)=2,因此 bucket(2)=4。
  • b)此時(shí) semi(3)=1,因此 bucket(1)=3。此時(shí) parent(3)=2,將 bucket(2)中的4彈出,2到4的路徑上3的semi值最小,滿足代碼中的if 條件,因此idom(4)=3
  • c)此時(shí)semi(2)=0,因此bucket(0)=2。此時(shí)parent(2)=1,將bucket(1)中的3彈出,1到3的路徑上2的semi值最小,滿足代碼中的if條件,因此idom(3)=2
  • d)此時(shí)semi(1)=0,因此 bucket(0)={2,1},此時(shí) parent(1)=0,將 bucket(0)中的棧頂元素 1 彈出,滿足 else 條件,idom(1)=0,繼續(xù)將 bucket(0)中的2彈出,滿足else條件,idom(2)=0
  • e)最后執(zhí)行下一個(gè)循環(huán),直接支配節(jié)點(diǎn)與半支配節(jié)點(diǎn)進(jìn)行比較,此時(shí) idom(3)不等于sdom(3),idom(4)不等于sdom(4),因此idom(3)=idom(2)=0,idom(4)=idom(idom(3))=0

5.2 semi-NCA 算法

與上文介紹的SLT算法相比,semi-NCA算法無疑更容易理解,這也是目前 LLVM正在使用的算法。下面直接上代碼,相信大家一看就能夠理解。

Create a DFS tree T.
Calculate semidominator for w
Create a tree D and initialize it with r as the root.
for v ∈ V ? {r} in preorder by the DFS do
  Ascend the path r *—>DparentT(v) and ?nd the deepest vertex which number is smaller than or equal to sdom(v).
  set this vertex as parent for v in D.
end for

為了方便理解,來看下面這個(gè)簡單實(shí)例:

圖片

semi-NCA算法實(shí)例

  • 圖 a)是已經(jīng)求出的半支配節(jié)點(diǎn)圖,左邊的數(shù)字表示每個(gè)節(jié)點(diǎn)的半支配節(jié)點(diǎn)。
  • 圖 b)是支配節(jié)點(diǎn)樹(代碼中的 D 樹),目前只求出來 0 到 4 節(jié)點(diǎn)的支配節(jié)點(diǎn)。
  • 圖 c)是求節(jié)點(diǎn) 5 支配節(jié)點(diǎn)的一個(gè)實(shí)例。節(jié)點(diǎn) 5 在 DFS 樹中的父節(jié)點(diǎn)是 4。因此在 D 中沿著根節(jié)點(diǎn) 0 到 4 的路徑上找到第一個(gè)小于 semi(5)的節(jié)點(diǎn),此節(jié)點(diǎn)為 0,也就是 5 的直接支配節(jié)點(diǎn)。

小結(jié)

本節(jié)主要介紹了 LLVM 中求支配節(jié)點(diǎn)樹的兩種算法,分別是 SLT 和 semi-NCA 算法。兩種算法的時(shí)間復(fù)雜度和空間復(fù)雜度如下。

算法 時(shí)間復(fù)雜度 空間復(fù)雜度
SLT O(mlogn) O(m+n)
semi-NCA O(n^2) O(m+n)

對(duì)于算法的詳細(xì)分析、證明和實(shí)驗(yàn)結(jié)果可以參考原論文。

6. 后記

本篇文章缺少算法的證明,僅提供一些自己在學(xué)習(xí)過程中對(duì)這兩個(gè)算法感性的認(rèn)識(shí),避免枯燥的公式。希望能夠給需要學(xué)習(xí)這個(gè)算法的人提供一些幫助。

后續(xù)準(zhǔn)備寫一個(gè)編譯器中的圖論算法系列,題目如下:

  • 編譯器中的圖論算法之支配樹
  • 編譯器中的圖論算法之支配邊界

歡迎各位朋友幫忙補(bǔ)充更多的編譯器中用到的圖論算法或者其它感興趣的編譯器中的算法。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    396

    瀏覽量

    17270
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    646

    瀏覽量

    32672
  • TVM
    TVM
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    3642
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    幾款C語言編譯器推薦

    一些剛開始接觸C語言編譯的網(wǎng)友想下載一款C語言編譯器來使用,不過,網(wǎng)絡(luò)上有不少C語言編譯器相關(guān)的軟件,讓人很難抉擇。
    發(fā)表于 09-05 09:19 ?1w次閱讀

    ICC AVR編譯器的安裝與使用

    ICCAVR編譯器的安裝、運(yùn)行、破解、使用 用ICCAVR編譯器產(chǎn)生初始化程序和程序框架
    發(fā)表于 07-09 18:06 ?258次下載

    基于CoSy的編譯器開發(fā)的研究

    CoSy是ACE公司開發(fā)的編譯器構(gòu)造框架[1]。它提供共享工具和引擎來構(gòu)造編譯器編譯器開發(fā)者只專注于目標(biāo)機(jī)相關(guān)代碼的開發(fā)。CoSy框架生成的編譯器具有可擴(kuò)展性和可移植性??梢愿鶕?jù)目
    發(fā)表于 08-19 17:49 ?0次下載
    基于CoSy的<b class='flag-5'>編譯器</b>開發(fā)的研究

    PICC編譯器下載

    PICC編譯器下載
    發(fā)表于 05-25 17:44 ?168次下載

    NEC編譯器培訓(xùn)手冊(cè)

    NEC編譯器培訓(xùn)手冊(cè),開發(fā)者可根據(jù)功能要求對(duì)編譯器進(jìn)行設(shè)計(jì)。
    發(fā)表于 05-03 14:23 ?15次下載

    編譯器是如何工作的_編譯器的工作過程詳解

    隨著計(jì)算機(jī)的發(fā)展,編譯器已經(jīng)發(fā)揮著十分重要的作用。本文主要介紹了編譯器的種類、編譯器的工作原理以及編譯器工作的具體操作過程及步驟詳解。
    發(fā)表于 12-19 12:54 ?1.6w次閱讀

    編譯器原理到底是怎樣的帶你簡單的了解編譯器原理

    編程語言是怎樣工作的 理解編譯器內(nèi)部原理,可以讓你更高效利用它。按照編譯的工作順序,逐步深入編程語言和編譯器是怎樣工作的。本文有大量的鏈接、樣例代碼和圖表幫助你理解編譯器
    的頭像 發(fā)表于 12-23 17:25 ?1.1w次閱讀

    既然C編譯器是C語言寫,那么第一個(gè)C編譯器是怎樣來的?

    既然C編譯器是C語言寫的,那第一個(gè)C編譯器是怎樣來的?
    的頭像 發(fā)表于 02-25 15:47 ?2973次閱讀

    編譯器對(duì)芯片行業(yè)到底有什么意義

    2019年科技行業(yè)有一個(gè)熱點(diǎn)“華為開源方舟編譯器”,編譯器這個(gè)名詞開始不斷的進(jìn)入國人的視野。作為民族自主品牌的驕傲,華為為什么投入巨大的人力開發(fā)方舟編譯器并將它開源,編譯器在華為乃至整
    的頭像 發(fā)表于 02-20 14:22 ?8565次閱讀
    <b class='flag-5'>編譯器</b>對(duì)芯片行業(yè)到底有什么意義

    Verilog HDL 編譯器指令說明

    Verilog HDL 編譯器指令 復(fù)雜一點(diǎn)的系統(tǒng)在進(jìn)行設(shè)計(jì)或者驗(yàn)證時(shí),都會(huì)用到一些編譯器指令,那么什么是編譯器指令? ? Verilog HDL編譯器指令由重音符(‘)開始。在Ver
    的頭像 發(fā)表于 11-03 09:31 ?3421次閱讀
    Verilog HDL <b class='flag-5'>編譯器</b>指令說明

    GH集成開發(fā)環(huán)境和編譯器

    說實(shí)話,以前也用過正版的編譯器,我記得之前用過正版的IAR編譯器license也沒有多貴,而最近用了個(gè)10萬一個(gè)license的編譯器編譯嵌入式代碼,因?yàn)閷?duì)功能安全有要求,而這個(gè)Gre
    的頭像 發(fā)表于 03-16 17:08 ?1615次閱讀

    交叉編譯器安裝教程

    交叉編譯器“交叉”的意思就是在一個(gè)架構(gòu)上編譯另外一個(gè)架構(gòu)的代碼,相當(dāng)于兩種架構(gòu)“交叉”起來了。Ubuntu 自帶的 gcc 編譯器是針對(duì) X86 架構(gòu)的,而我們現(xiàn)在要
    的頭像 發(fā)表于 09-29 09:12 ?3294次閱讀

    領(lǐng)域編譯器發(fā)展的前世今生

    。與此同時(shí),編譯器的開發(fā)人員也從芯片研發(fā)團(tuán)隊(duì)開始延伸到更上層的軟件層面。在很多領(lǐng)域的軟件系統(tǒng),都開始引入編譯技術(shù)來實(shí)現(xiàn)提升開發(fā)效率或運(yùn)行效率等目標(biāo)。本文從領(lǐng)域編譯器的角色著眼,來討論
    的頭像 發(fā)表于 02-03 10:37 ?1503次閱讀

    編譯器的優(yōu)化選項(xiàng)

    一個(gè)程序首先要保證正確性,在保證正確性的基礎(chǔ)上,性能也是一個(gè)重要的考量。要編寫高性能的程序,第一,必須選擇合適的算法和數(shù)據(jù)結(jié)構(gòu);第二,應(yīng)該編寫編譯器能夠有效優(yōu)化以轉(zhuǎn)換成高效可執(zhí)行代碼的源代碼,要做到
    的頭像 發(fā)表于 11-24 15:37 ?749次閱讀
    <b class='flag-5'>編譯器</b>的優(yōu)化選項(xiàng)

    人工智能編譯器與傳統(tǒng)編譯器的區(qū)別

    人工智能編譯器(AI編譯器)與傳統(tǒng)編譯器在多個(gè)方面存在顯著的差異。這些差異主要體現(xiàn)在設(shè)計(jì)目標(biāo)、功能特性、優(yōu)化策略、適用范圍以及技術(shù)復(fù)雜性等方面。以下是對(duì)兩者區(qū)別的詳細(xì)探討,旨在全面解析其內(nèi)在差異。
    的頭像 發(fā)表于 07-17 18:19 ?1265次閱讀