在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

LLVM16的新增功能介紹

jf_9aVl32Dp ? 來源:Pablo Barrio ? 2023-05-18 10:07 ? 次閱讀

除了對今年架構的標準支持外,我們還完成了對可擴展矩陣擴展(SME和SME2)的匯編級支持。在CPU方面,此版本擴展了Armv9-A內核系列,支持我們的Cortex-A715和Cortex-X3 CPU。

A-profile 2022更新:Armv8.9-A和Armv9.4-A

現在,除了將在下一個LLVM版本中支持的保護調用堆棧(GCS)之外,所有擴展都可以進行匯編和反匯編。Arm C語言擴展(ACLE)也用兩個新的內部函數__rsr128和__wsr128進行了擴展;這些使得新的128位系統寄存器更容易訪問。LLVM現在支持這些內部函數。

轉換加固擴展(THE)是Armv9.4-A的主要安全改進之一,也是虛擬內存系統體系結構(VMSA)的一部分。其目的是防止在攻擊者獲得內核權限的情況下對虛擬內存的轉換表進行任意更改。新的讀取-檢查-寫入(RCW)指令已添加到體系結構中,以允許在禁用普通寫入的同時對此類表進行受控修改。

盡管這些指令是針對內核而非用戶空間開發人員的,但RCW指令可以很好地映射到C++中128位數據類型上的各種原子操作。更具體地說,fetch_and、fetch_or和exchange可以直接用這些指令來實現。

這個功能對任何使用原子操作的人都很有用,所以我們在LLVM 16中添加了代碼生成支持。在LRCPC3和LSE2擴展也可用的目標中,這些專用指令直接從C++代碼生成,而不需要匯編或內部函數。

以下是std::atomic::fetch_and的示例:

#include 


std::atomic<__uint128_t> global;


void sink(__uint128_t);


void ldclrpal_example(__uint128_t x) {
    __uint128_t res = global.fetch_and(x);
    sink(res);
}


void ldclrp_example(__uint128_t x) {
    __uint128_t res = global.fetch_and(x, std::memory_order_relaxed);
    sink(res);
}

使用-march=armv9.4a+lse128+rcpc3-O3編譯,生成的程序集顯示正在生成的新指令:

ldclrpal_example(unsigned __int128):
        mvn     x1, x1
        mvn     x0, x0
        adrp    x8, global
        add     x8, x8, global
        ldclrpal        x0, x1, [x8]
        b       sink(unsigned __int128)
ldclrp_example(unsigned __int128):
        mvn     x1, x1
        mvn     x0, x0
        adrp    x8, global
        add     x8, x8, global
        ldclrp  x0, x1, [x8]
        b       sink(unsigned __int128)

多版本控制功能

如今,許多平臺都有一個單一的二進制部署模型:每個應用程序都是通過一個二進制文件分發的。這使得開發人員很難針對多個體系結構功能。為了解決這個問題,LLVM 16提供了一種針對特定體系結構特征的方便方式,而不需要處理特征檢測和其他細節。這個新功能被稱為函數多版本控制。

提供了一個新的宏__HAVE_FUNCTION_MULTI_VERSIONING來檢測功能的可用性。如果存在,我們可以要求編譯器通過標記__attribute__((target_clones())來生成給定函數的多個版本。函數的最合適版本將在運行時調用。

在下面的示例中,一個函數被標記為要為Advanced SIMD(又名NEON)和SVE構建。如果SVE在目標上可用,則將使用SVE版本。

#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
__attribute__((target_clones("sve", "simd")))
#endif
float foo(float *a, float *b) {
   // 
}

在某些情況下,開發人員希望為每個功能提供不同的代碼。這也可以通過使用__attribute__((target_version()))來實現。在下面的例子中,我們為同一個函數提供了兩個版本。同樣,如果SVE可用,將調用SVE版本。宏__HAVE_FUNCTION_MULTI_VERSIONING允許編寫與具有和不具有函數多版本控制的編譯器兼容的代碼。

#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
__attribute__((target_version("sve")))
static void foo(void) {
    printf("FMV uses SVE
");
}
#endif


// this attribute is optional
// __attribute__((target_version("default")))
static void foo(void) {    
    printf("FMV default
");
    return;
}

此功能依賴于編譯器rt(-rtlib=編譯器rt),并且在默認情況下啟用,但可以使用標志-mno fmv禁用它。請注意,函數多版本控制仍處于測試狀態。ACLE規范非常歡迎通過打開新問題或創建pull請求來提供反饋。

性能改進

復數自動矢量化

LLVM 16包括對復數上的公共運算的自動矢量化的支持。這些分別利用了Armv8-A和Armv8-M體系結構的高級SIMD(Neon)和MVE指令集中可用的指令。例如,代碼:

#include 
#define N 512


void fma (_Complex float a[restrict N], _Complex float b[restrict N],
           _Complex float c[restrict N]) {
  for (int i=0; i < N; i++)
    c[i] = a[i] * b[i];
}

輸出以下匯編代碼:

fma: // @fma
  mov x8, xzr
.LBB0_1: // =>This Inner Loop Header: Depth=1
  add x9, x0, x8
  add x10, x1, x8
  movi v2.2d, #0000000000000000
  movi v3.2d, #0000000000000000
  ldp q1, q0, [x9]
  add x9, x2, x8
  add x8, x8, #32
  cmp x8, #1, lsl #12 // =4096
  ldp q5, q4, [x10]
  fcmla v3.4s, v1.4s, v5.4s, #0
  fcmla v2.4s, v0.4s, v4.4s, #0
  fcmla v3.4s, v1.4s, v5.4s, #90
  fcmla v2.4s, v0.4s, v4.4s, #90
  stp q3, q2, [x9]
  b.ne .LBB0_1
  ret

請注意FCMLA指令的使用,該指令對復數向量執行融合乘加向量運算和可選的復數旋轉。

默認啟用功能專業化和SPEC2017內部改進

在為速度進行優化時,默認情況下在所有優化級別都啟用了功能的專業化。通行證的優化啟發式和編譯時屬性已經得到了改進,并且被認為通常足夠有益,可以默認啟用。

這種優化在各種AArch64平臺上特別將SPEC2017 intrate中的505.mcf_r基準提高了約10%。這有助于將SPEC2017年intrate C/C++基準在AArch64提高3%。

請注意,SPEC2017性能提升還得益于SelectOpt通道和其他高級模式識別的默認調整和啟用。

5af8aab4-ed4d-11ed-90ce-dac502259ad0.png

SVE和自動矢量化的改進

SVE的自動矢量化一直是一個非常活躍的發展領域。例如,到目前為止,在條件的不同分支中訪問的指針的矢量化是非常基本的:大多數時候,它會被計算為成本太高。現在,指針上的基本運算包含在矢量器的成本模型中。這意味著現在可以在更好的情況下對以下代碼進行矢量化:

void foo(float *dst, float *src, int *cond, long disp) {
  for (long i=0; i<1024; i++) {
    if (cond[i] != 0) {
      dst[i] = src[i];
    } else {
      dst[i] = src[i+disp];
    }
  }
}

也就是說,在合成示例中,找到合適的環境以使矢量化有利可圖是很棘手的,并且生成的代碼非常長。如果你想看看矢量化的代碼是什么樣子的,你可以調整成本模型。使用-march=v9a-O3-Rpass=loop vectorize-mllvm-force target instruction cost=1編譯前面的示例。

通過減少對顯式合并操作的需求,尾部折疊循環的矢量化也得到了改進。例如,以下代碼:

float foo(float *a, float *b) {
  float sum = 0.0;
  for (int i = 0; i < 1024; ++i)
    sum += a[i] * b[i];
  return sum;
}

用-march=armv9-a-Ofast-mllvm-sve tail folding=all編譯,這表明現在發出了預測的FMLA:

.LLVM_15_LOOP:
    ld1w    { z2.s }, p1/z, [x0, x8, lsl #2]
    ld1w    { z3.s }, p1/z, [x1, x8, lsl #2]
    add    x8, x8, x10
    fmul    z2.s, z3.s, z2.s
    sel    z2.s, p1, z2.s, z0.s
    whilelo    p1.s, x8, x9
    fadd    z1.s, z1.s, z2.s
    b.mi    .LLVM_15_LOOP
 
.LLVM_16_LOOP:
    ld1w    { z1.s }, p1/z, [x0, x8, lsl #2]
    ld1w    { z2.s }, p1/z, [x1, x8, lsl #2]
    add    x8, x8, x10
    fmla    z0.s, p1/m, z2.s, z1.s
    whilelo    p1.s, x8, x9
    b.mi    .LLVM_16_LOOP

此外,通過減少對顯式反向運算的需要,改進了具有反向迭代計數的循環的矢量化。以這個循環為例:

void foo(int *a, int *b, int* c) {
  for (int i = 1024; i >= 0; --i) {
    if (c[i] > 10)
      a[i] = b[i] + 5;
  }
}

使用-march=armv9-a-O3編譯后,LLVM 16輸出不再反轉加載的數據,也不再反轉用于條件的謂詞:

.LLVM_15_LOOP:
    ld1w    { z0.s }, p0/z, [x16, x9, lsl #2]
    ld1w    { z1.s }, p0/z, [x17, x9, lsl #2]
    rev    z0.s, z0.s
    rev    z1.s, z1.s
    cmpgt    p1.s, p0/z, z0.s, #10
    cmpgt    p2.s, p0/z, z1.s, #10
    rev    p1.s, p1.s
    rev    p2.s, p2.s
    ld1w    { z0.s }, p1/z, [x14, x9, lsl #2]
    ld1w    { z1.s }, p2/z, [x15, x9, lsl #2]
    add    z0.s, z0.s, #5                  // =0x5
    add    z1.s, z1.s, #5                  // =0x5
    st1w    { z0.s }, p1, [x12, x9, lsl #2]
    st1w    { z1.s }, p2, [x13, x9, lsl #2]
    sub    x9, x9, x10
    cmp    x18, x9
    b.ne    .LLVM_15_LOOP
 
.LLVM_16_LOOP:
    ld1w    { z0.s }, p0/z, [x13, x9, lsl #2]
    ld1w    { z1.s }, p0/z, [x14, x9, lsl #2]
    cmpgt    p1.s, p0/z, z0.s, #10
    cmpgt    p2.s, p0/z, z1.s, #10
    ld1w    { z0.s }, p1/z, [x15, x9, lsl #2]
    ld1w    { z1.s }, p2/z, [x16, x9, lsl #2]
    add    z0.s, z0.s, #5                  // =0x5
    add    z1.s, z1.s, #5                  // =0x5
    st1w    { z0.s }, p1, [x17, x9, lsl #2]
    st1w    { z1.s }, p2, [x18, x9, lsl #2]
    sub    x9, x9, x10
    cmp    x12, x9
    b.ne    .LLVM_16_LOOP

LLVM 16上SVE的其他性能改進包括:

。DUP的使用在各種場景中都得到了極大的改進,尤其是對于128位LD1RQ變體。

。乘法-加法和乘法子指令可以更廣泛地使用。

。對PTEST指令的需求已經大大減少。

。擴展循環負載消除現在是類型不可知的,因此可以檢測更多的情況。

。SLP成本模型得到了改進。

Spec2017與Flang一起構建

去年12月,我們通過LLVM/Frang在O3上實現了所有Fortran速率基準測試的里程碑。主要關注點是啟用四個失敗的基準測試(521.wrf_r、527.cam4_r、549.fotonik3d_r、554.roms_r)。主要改進之一是通過使用復雜方言消除了對外部復雜數學庫的依賴。

此外,通過改進前端和LLVM之間的信息共享,以及改進對快速數學的支持,還獲得了一些性能。

您可以通過將-DLLVM_ENABLE_PROJECTS=“Flang;clang;mlir”傳遞給CMake來構建Flang。flang可執行文件稱為flang-new;確保通過選項-flang實驗exec來生成可執行文件。

Target-gated ACLE 內聯

最初是由Highway庫引發的,目標(“”)屬性在最新的clang中得到了一些改進,旨在使其與GCC的實現保持一致。

現在支持的格式是:

。arch=字符串根據-march=arch+feature命令行選項指定函數的體系結構特性。

。cpu=字符串根據-mcpu=cpu+feature命令行選項指定目標cpu和任何隱含屬性。

。tune=字符串指定函數的tune cpu cpu,如-mtune。

。+<feature>,+no<feature>啟用或禁用特定功能,以與GCC目標屬性兼容。

。<feature>,no-<feature>啟用或禁用特定功能,以便與以前的clang版本向后兼容。

隨著上述變化,ACLE內部函數的實現也進行了修改,使其不再基于預處理器宏。相反,它們是基于當前目標啟用的。這允許在單個函數中提供內部函數,而不需要為同一目標編譯整個文件。以下示例說明了函數sve2_log上屬性的使用:

#include 
#include 


void base_log(float *src, int *dst, int n) {
    for(int i = 0; i < n; i++)
        dst[i] = log2f(src[i]);
}


void __attribute__((target("sve2")))
sve2_log(float *src, int *dst, int n) {
    int i = 0;
    svbool_t p = svwhilelt_b32(i, n);
    while(svptest_any(svptrue_b32(), p)) {
        svfloat32_t d = svld1_f32(p, src+i);
        svint32_t l = svlogb_f32_z(p, d);
        svst1_s32(p, dst+i, l);
        i += svcntb();
        p = svwhilelt_b32(i, n);
    }
}

llvm objdump的改進

在LLVM 16中,Arm目標的LLVM objdump的輸出在可讀性和正確性方面得到了改進,使其成為基于LLVM的工具鏈上GNU objdump的更合適的替代品。

big-endian對象文件的反匯編現在可以正常工作。以前,每個指令字都被意外地進行了字節交換,并被分解為完全不同的東西。

此外,在反匯編中遇到的無法識別的指令會以更有用的方式進行處理。以前,反匯編程序只前進一個字節,然后從奇數地址重試。此策略在具有可變長度指令的體系結構上是有意義的,但在Arm上則不然。新的行為是推進整個指令,以便文件的其余部分可能會被正確地反匯編。

LLVM 16包括Arm架構的其他質量改進,包括Thumb與Arm反匯編的錯誤修復,以及現在包含正確字節的.byte指令。對指令編碼進行了一些可讀性改進,使Arm和32位Thumb更容易區分:現在您可以看到Arm指令有一個8位數字,Thumb有兩個4位數字,中間有一個空格。

支持AArch64上的嚴格浮點

AArch64已經實現了嚴格的浮點語義。clang命令行選項-ffp model=strict現在在AArch64目標上被接受,而不是被忽略并發出警告。舉個例子,只有在安全的情況下才執行FP除法:

float fn(int n, float x, float y) {
  if (n == 0) {
    x += 1;
  } else {
    x += y/n;
  }
  return x;
}

在LLVM 15上,使用-O2進行編譯會生成以下代碼:

fn(int, float, float):                               // @fn(int, float, float)
        scvtf   s3, w0
        fmov    s2, #1.00000000
        cmp     w0, #0
        fdiv    s1, s1, s3
        fadd    s1, s1, s0
        fadd    s0, s0, s2
        fcsel   s0, s1, s0, ne
        ret

它將執行兩個分支,包括除法,然后在fcsel中選擇正確的結果。盡管保留了代碼的功能,但當n=0時,它會導致偽FE_DIVBYZERO浮點異常。在LLVM 16上,使用-O2-ffp模型=嚴格編譯會產生以下代碼:

fn(int, float, float):                               // @fn(int, float, float)
        cbz     w0, .LBB0_2
        scvtf   s2, w0
        fdiv    s1, s1, s2
        fadd    s0, s0, s1
        ret
.LBB0_2:
        mov     w8, #1
        scvtf   s1, w8
        fadd    s0, s0, s1
        ret

其中兩個不同的執行分支保持分離,從而防止FP異常的發生。

由于支持嚴格的FP,現在也接受了選項-frapping math和-frounding math。一方面,-ftrapping數學確保代碼不會引入或刪除任何類型的FP異常可能導致的副作用。其中包括軟件可以通過檢查FPSR異步檢測到的異常。類似地,-founding數學避免應用假設特定FP舍入行為的優化。

在編譯器rt和LLD中支持早期的Arm體系結構

LLD現在可以用作ARMv4和ARMv4T的鏈接器:它現在發出與ARMv4和ARMv4T兼容的thunk,而不是ARMv4的不兼容BX指令或ARMv4或ARMv4T的BLX指令。

與此相關的是,為ARMv4T、ARMv5TE和ARMv6添加了對編譯器rt內置程序的支持,從而解鎖了對這些體系結構的運行時支持。

由于這項啟用工作,現在可以為這些32位Arm架構提供一個完整的基于LLVM的工具鏈。因此,Linux內核現在增加了對使用LLD構建Clang的支持,Rust程序不再需要依賴GNU鏈接器。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5359

    瀏覽量

    120814
  • ARM處理器
    +關注

    關注

    6

    文章

    361

    瀏覽量

    41834
  • 編譯器
    +關注

    關注

    1

    文章

    1640

    瀏覽量

    49198
  • SIMD
    +關注

    關注

    0

    文章

    35

    瀏覽量

    10311
  • GNU
    GNU
    +關注

    關注

    0

    文章

    143

    瀏覽量

    17517

原文標題:LLVM16的新增功能

文章出處:【微信號:Arm軟件開發者,微信公眾號:Arm軟件開發者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    OrCAD V16.3 新增功能

    OrCAD V16.3 新增功能
    發表于 09-21 22:58

    OpenHarmony 3.0 LTS 新增特性功能

    內容:標準系統新增特性功能用戶程序框架支持服務能力(ServiceAbility,DataAbility)和線程模型。支持文件安全訪問,即文件轉成URI和解析URI打開文件的能力。支持設備管理PIN碼
    發表于 09-30 08:24

    .NET Core 3.0(預覽版 2)的新增功能是什么

    .NET Core 3.0(預覽版 2)的新增功能是什么? .NET Core 3.0(預覽版 2)的新增功能有哪些?
    發表于 10-15 07:17

    在Swift中使用LLVM的四個要點

    本文主要內容是演示如何在Swift中使用LLVM,其包含了如下四個要點: 獲取最新版本的LLVM使用CMake和llvm-config編譯程序編寫簡單的Swift程序,編譯并與LLVM
    發表于 10-13 16:55 ?0次下載
    在Swift中使用<b class='flag-5'>LLVM</b>的四個要點

    Vivado Design Suite 2015.3新增量編譯功能介紹

    了解Vivado實現中2015.3中的新增量編譯功能,包括更好地處理物理優化和自動增量編譯流程。
    的頭像 發表于 11-20 06:56 ?2881次閱讀

    Vivado Design Suite 2018.1設計套件中的新增功能介紹

    本視頻重點介紹了Vivado設計套件2018.1版本中的新增功能,包括對操作系統以及器件的支持情況,還有高層次增強功能,以及各種功能改進以加
    的頭像 發表于 11-20 06:28 ?2582次閱讀
    Vivado Design Suite 2018.1設計套件中的<b class='flag-5'>新增</b><b class='flag-5'>功能</b><b class='flag-5'>介紹</b>

    iOS 16新增安全檢查功能 保護用戶的個人安全

    新增安全檢查功能保護用戶的個人安全,可快速關閉其他人的訪問權限和停止位置共享并重置所以app的系統隱私權限。
    的頭像 發表于 06-07 10:46 ?950次閱讀
    iOS <b class='flag-5'>16</b><b class='flag-5'>新增</b>安全檢查<b class='flag-5'>功能</b> 保護用戶的個人安全

    llvm-mctoll將二進制文件轉換為LLVM IR

    ./oschina_soft/llvm-mctoll.zip
    發表于 06-22 11:35 ?0次下載
    <b class='flag-5'>llvm</b>-mctoll將二進制文件轉換為<b class='flag-5'>LLVM</b> IR

    OLLVM和LLVM功能介紹

    LLVM是lowlevel virtual machine的簡稱,它誕生于2003.10伊利諾伊大學香檳分校,創始人是ChrisLattner,它是一個完整的編譯器框架,它兼容大部分主流開發語言例如
    的頭像 發表于 09-19 15:42 ?7695次閱讀

    LLVM源碼淺析-1

    作為一個優秀的開源編譯器框架,llvm的代碼比gcc代碼的可讀性更好。因此無論是學習c++,還是學習編譯原理、設計模式、數據結構,都是一個很好的學習目標。
    的頭像 發表于 03-02 16:06 ?2180次閱讀
    <b class='flag-5'>LLVM</b>源碼淺析-1

    LLVM國際開源軟件社區發布正式支持LoongArch架構的版本

    發行版將可以直接基于上游社區版本進行構建,標志著LoongArch軟件生態建設將迎來快速發展的新階段。 LLVM介紹 LLVM是如今設計和開發編譯器的最重要的框
    的頭像 發表于 03-21 09:45 ?1774次閱讀

    什么是LLVMLLVM的優勢和特點有哪些?

    LLVM是一個開源的編譯器基礎設施項目,它以"Low-Level Virtual Machine"的縮寫命名,盡管名稱中包含了"虛擬機"一詞,但LLVM不僅僅是一個虛擬機,而是一個綜合的編譯器工具鏈。
    的頭像 發表于 06-11 15:54 ?1w次閱讀

    UCA認證和DGT 發布最新V16應急警示燈(Help Falsh)新增GPS通訊功能要求

    西班牙交通部對V16應急警示燈(Help falsh)新增GPS通訊功能要求: 西班牙交通部DGT新增了對V16應急警示燈(Help fa
    的頭像 發表于 08-24 09:34 ?1509次閱讀
    UCA認證和DGT 發布最新V<b class='flag-5'>16</b>應急警示燈(Help Falsh)<b class='flag-5'>新增</b>GPS通訊<b class='flag-5'>功能</b>要求

    iPhone16系列新增相機按鈕AI功能

    對于即將開啟的蘋果秋季發布會大家肯定都非常關注蘋果新款手機iPhone16系列的AI功能;據悉iPhone16系列新增相機按鈕AI功能;此外
    的頭像 發表于 09-10 15:55 ?1380次閱讀

    SOLIDWORKS 2025新增功能介紹

    在工程設計領域,SOLIDWORKS一直是創新的代名詞,其不斷推出的新版本總能帶給用戶驚喜。2025年的SOLIDWORKS再次不負眾望,帶來了一系列令人矚目的新增功能,旨在提升設計效率、增強用戶體驗,并推動工程設計的邊界。
    的頭像 發表于 11-21 13:56 ?226次閱讀
    主站蜘蛛池模板: 999影院成 人在线影院| 欧美区亚洲区| 免费久久久久| 国产精品福利一区| 成 人 免费 黄 色 视频| 在线观看视频播放| 国产人成午夜免费噼啪视频| 18欧美乱大交| 国产做爰一区二区| 亚洲成人在线免费| 四虎久久精品国产| 欧美黄色一级视频| 精品欧美小视频在线观看| 国产精品永久免费自在线观看| 91成人在线播放| 手机看片福利1024| 国产成人悠悠影院| kkk4444免费观看| 国产精品丝袜在线观看| 亚洲国产成人精品青青草原100| 四虎影午夜成年免费精品| 农村三级毛片| 都市激情亚洲综合| 天天射天天干天天操| 国产伦精品一区二区三区网站| 中文字字幕码一二区| 中国日韩欧美中文日韩欧美色| 色姑娘网| 国产普通话一二三道| 天天看天天碰| 日本人xxxxxxxxxⅹ69| 国语对白一区二区三区| 色综合久久久久久久久五月性色| 亚洲 欧美 日韩 丝袜 另类| 免费在线观看你懂的| 国产综合久久久久影院| 黄色三级国产| 亚洲88av| 2018天天干天天操| 国产美女精品久久久久中文| 色狠狠xx|