2015年8月8日 星期六

Target Triple

剛好前鎮子有討論到 Target Triple 是啥鬼東西, 就順便整理一下,

在使用 Cross Compiler 的時候常常 gcc 前面會有一串名字,

例如 arm-none-linux-gnueabi-gcc 中的 arm-none-linux-gnueabi,

這東西其實真要說還真的沒啥正式的規則,

"通常"規則是 <target>[<endian>][-<vender>]-<os>[-<extra-info>]

然後這規則是自行歸納而來的並非啥正式規則

vendor 部份只是常見是可以塞 vendor 而已, 但沒有一定塞 vendor 的資訊
extra-info 部份大部份是在拿來描述用的 ABI 或著是 library 相關資訊

下面開使用一堆例子來用這規則來解讀
先以常見 x86 的平台為例子:
Fedora 22 上的 gcc (下 -v 可以看到)
Target: x86_64-redhat-linux
<target>-<vendor>-<os> 的形式

Ubuntu 14.04/i686 gcc
Target: i686-pc-linux-gnu
也是<target>-<vendor>-<os> 的形式

Android Toolchain:
Target: arm-linux-androideabi
<target>-<os>-<extra-info>
androideabi : 雖然 Android 本身是 Linux 但其 ABI 細節跟一般 linux 不太一樣

Linaro ELF toolchain:
Target: arm-none-eabi
<target>-<vender>-<extra-info>
vender = none
extra-info = eabi

Linaro Linux toolchain:
Target: arm-linux-gnueabihf
<target><endian>-<os>-<extra-info>
extra-info:
gnu: 沒啥特別意義
eabi: EABI
hf : Hard float, 預設有 FPU

Linaro big-endian Linux toolchain:
Target: armeb-linux-gnueabihf
<target><endian>-<vender>-<extra-info>
endian = be = big-endian

Buildroot 2015-02
Target: arm-buildroot-linux-uclibcgnueabi
<target>-<vender>-<os>-<extra-info>
extra-info:
uclibc 用 uclibc (通常預設是 glibc, uclibc 有些細節與 glibc 不同)
gnu : 無意義
eabi : 採用 EABI

NDS32 Toolchain:
Target: nds32le-elf
<target><endian>-<os>
Andes 家的,應該淺顯易懂不用解釋

由以上眾多 pattern 大概可以歸納出一些事情:
vender 那欄可以看上面的例子這部份完全可以亂填
os 那來可填可不填,不填"通常"代表 Non-OS (Bare-metal)

然後這鬼東西其實沒啥正式的規則
每個 target 可以按照自己開心的方式去處理
詳細部份可以參考 <gcc-src>/gcc/config.gcc [1]裡面有各種神秘規則

Reference

[1] https://github.com/gcc-mirror/gcc/blob/master/gcc/config.gcc

2015年4月23日 星期四

GCC 5 Releas Note

以下是 GCC 5 更新的部份, 主要整理自官方 Release 頁面, 但由於個人能力有限, target 相關僅翻譯 x86, arm, aarch64 以及 nds32, 語言相關方面則只翻譯 C/C++ 還有 Go 的部份:

提醒!

  • C 語言的預設模式將從 -std=gnu89 轉換為 -std=gnu11 (譯註1)
  • Graphite framework 不再使用 CLooG,而改用 ISL 0.14 或 0.12.2 版,詳情請參閱公開安裝說明。
  • 未來的版本將會移除非標準的 type traits : has_trivial_default_constructor,has_trivial_copy_constructor 以及 has_trivial_copy_assign,現階段不推薦使用,建議改成標準提供的 is_trivially_default_constructible, is_trivially_copy_constructible 以及 is_trivially_copy_assignable。

譯註1:如果手上的 code 升級後編不過的話可以加個 -std=gnu89,不過建議方式是去看 GCC 抱怨啥,然後去修正程式碼。

一般性的最佳化改善

連結時期最佳化(Link-time optimization LTO)的改善:

  • 加入新的最佳化: Identical Code Folding (ICF,使用 -fipa-icf 開啟),跟 gold linker 的 Identical Code Folding 相比這玩意兒不需要開啟 Function Section,ICF 會在 inlining 前執行,並且會跨函數分析來達到程式碼重用 (Code Re-use),但某方面而言一些 gold 可以作 ICF 的函數, GCC 不一定可以作,主要是 GCC 必須考量正確的別名資訊(honor aliasing information)。在開啟 LTO 的情況下 Firefox 大約可以合併約 31000 個函數,佔整體的 14% (譯註2)。
  • Devirtualization 最佳化改善了 speculative devirtualization 以及動態型別偵測,在 FireFox 中在 LTO 階段大約 50% 的虛擬函數呼叫可以被 speculative devirtualization。
  • 新的 comdat 在地化(localization) 最佳化讓 linker 可以消除更多的 Dead Code,尤其是 C++ 的那些 Inline function。
  • 透過 Virtual tables (譯註3) 的最佳化,減少 Dynamic Linking 的時間。
  • 新增 -fno-semantic-interposition 的選項,可以透過禁止 Export Symbol 被外部的 Shared Library 蓋掉 (interposition) 來進一步最佳化程式(譯註4)。
  • Write-only 的變數現在會自動偵測並且可以被最佳化掉(譯註5)。
  • Profile Feedback 的 Function Inliner 現在也可被 --param inline-insns-auto 以及 --param inline-insns-single 這兩個參數限制行為了。
  • IPA Reference 分析速度大幅提昇,使得 -fipa-reference 可以同時跟 -fprofile-generate 一起使用變得可能了,這也解決了 Chromium 用 LTO 建置的瓶頸。
  • Symbol Table 跟 Call-Graph 的 API 用 C++ 重寫並且大幅簡化!
  • 跨函數常數傳遞 (Interprocedural Constants Propagation) 現在也會順便傳遞指標的 Alignment 資訊,如果有此資訊的話,迴圈自動向量化的最佳化可以少產生處理 Misalignments 的程式。

譯註2:相關數據可參考 Mailing list 上的討論,大致上可以省 2% 左右的 Code size,跟 gold 的 ICF 一起用的話約可省 6.8%。

譯註3:拿來放 Virtual function 的表

譯註4:保證呼叫的函數如果本地端有定義的話,一定會採用本地的,效果類似 Linker 的 -Bsymbolic,不同的地方在於這可以讓 GCC 有在分析時有更多的資訊。

譯註5:例如有一個程式如下

static int foo;

void bar(){
  foo = 20;
}
在 GCC 5 中會產生,不做任何事就直接 return:
bar:
 rep ret
但在 GCC 5 前,則會很老實的把 20 放到 foo 去:
bar:
 movl $20, foo(%rip)
 ret

連結時期最佳化(Link-time optimization LTO)的改善:

  • 實做 One Definition Rule based 的 C++ 型別合併機制,型別合併可以大幅改善 devirtualization 以及別名分析(alias analysis)的效果,輸出 ODR 的額外資訊大約會需要額外的 2-6% 的記憶體空間以及 Object File 小幅增加,可由 -flto-odr-type-merging 這個選項控制要不要用。
  • 命令列最佳化選項以及平台相依選項現在會根據每個函數輸出,這項改變將使得在 LTO 可以允許 Translation Units 間使用不同得最佳化選項 (例如 -ffast-math, -mavx 或 -finline 等),相對於之前版本的 GCC ,在 Link 階段給的命令列最佳化選項以及平台相依選項都會直接被忽略掉。 要特別注意的是這項規則只適用於那些最佳化以及平台相依的屬性,一些影響整體 Code Gen 的選項例如 -fPIC,警告類的選項,會影響靜態變數的最佳化(例如 -fcommon),除錯資訊輸出或著是 --param 的參數,將會影響整個 LTO 最佳化,而不是適用於部份 Translation Units,這類選項建議在編譯以及鍊結時期都採用一致的選項。
  • GCC bootstrap 現在預設產生用 Slim LTO 的 Object File
  • 記憶體使用以及鍊結時間大幅改善:Tree Merge 的速度提昇,以及改善 GIMPLE 層的記憶體使用量,並且支援 on-demand 的串流化。

回饋導向最佳化(Feedback directed optimization) 的改善:

  • 新的 auto-FDO 模式將可以使用較低成本的 Profiling 工具 (perf),來取代傳統又慢又貴的侵入式的 Profiling 方式 (-fprofile-generate), 在 x86-64 上 SPEC2006 用新的 auto-FDO 可改善約 4.7%,比傳統的 FDO 方式多改善了約 7.3%。
  • 改善 C++ 的 Inline 以及 Extern Inline 函數的 Profile 的精準度,。
  • 增加新的 gcov-tool ,可用來操作 Profile 輸出(譯註6)。
  • Profile 現在更能容忍原始碼的小幅度更動(可透過 --param profile-func-internal-id 來控制)。

譯註6:主要是可以合併不同次輸出的 Profile

暫存器分配 (Register allocation) 的改善:

  • 新增一個 Control-flow sensitive 的全域暫存器重現化 (Rematerialization) 的最佳化到 LRA 中,可由 -flra-remat 控制開關,LRA 會在有利可圖的情況下嘗試去重新計算該值,而不是直接 Spill 跟 Restore,這個最佳化在 SPEC2000 上,ARM 可改善約 1%,x86-64 則改善約 0.5%。
  • 重用 PIC 暫存器,而不是將該暫存器鎖死不用,目前實做在 x86/x86-64 平台上,這將改善 PIC 程式的效能,共享程式庫(Shared Library) 的程式可大幅改善,目前只有 x86/x86-64 有開啟,不過此項基礎設施已經內建在暫存器分配器裡面,未來其它平台也可使用。
  • 新的簡易跨函數暫存器分配,當暫存器分配器知道呼叫的函數不會使用到 Caller-saved 暫存器時,將不會產生 Save/Restore 的指令在函數呼叫前後,可由 -fipa-ra 選項控制開關。
  • LRA 現在在有利可圖的情況下更有效的利用向量暫存器 (Vector Register) 來暫存 (Spill) 一般暫存器的值,而不是直接暫存到記憶體中,這在現代的 Intel 處理器中大部份是會賺的。

UndefinedBehaviorSanitizer 新增選項:

  • -fsanitize=float-divide-by-zero: 偵測浮點數除以零的情況。
  • -fsanitize=float-cast-overflow: 偵測浮點數轉到整數有無溢位 (Overflow)。
  • -fsanitize=bounds: 偵測所有的陣列存取有無越界存取。
  • -fsanitize=alignment: 偵測 Alignment 資訊,檢查有無 Misalignment 的物件。
  • -fsanitize=object-size: 物件大小的檢查,檢查有無越界存取。
  • -fsanitize=vptr: 檢查所有的 C++ 函數呼叫,成員變數存取以及父子間轉型的時候型別是否正確。

指標邊界檢查器 (Pointer Bounds Checker):

  • 新的越界指標檢查器,可透過 -fcheck-pointer-bounds 開啟,透過執行時期的檢查來偵測是否越界,目前只在有 Intel MPX 指令集的 x86/x86-64 GNU/Linux 平台上可以用,詳情請參閱 Wiki 頁面

新語言以及語言相關的改善:

OpenMP 4.0 規格中的 offloading 功能目前支援 C, C++, and Fortran:

  • 基礎建設 (適合任何 Vendor)
  • OpenMP 4.0 Example 所提供的 Offloading 的皆有包含在測試裡面。
針對未來的 Intel Xeon Phi 系列產品:
  • 執行時期函數庫 (Run-time library)
  • 模擬器 (Emulator)

C 家族

  • -fdiagnostics-color= 的預設值現在可以在建置 GCC 的時候可透過 --with-diagnostics-color= 設定,可用的值為 never, always, auto 以及 auto-if-env,新的預設值 auto 只有在輸出是 stderr 以及 stderr 是終端機輸出的情況下會上色。 GCC 4.9 的預設值是 auto-if-env,在 GCC_COLORS 這個環境變數非空字串的時候等價於 auto 模式,GCC 4.9 在 GCC_COLORS 這個環境變數沒設定的情況下將會預設關閉彩色輸出。
  • 加入新選項 -Wswitch-bool:若 switch 內的值是布林值的話 GCC 就會抱怨。(譯註7)
  • 加入新選項 -Wlogical-not-parentheses:當左邊的運算元 (left hand side operand) 旁邊有 Logical Not 而且沒有用括號包起來的話就會噴警告。(譯註8)
  • 加入新選項 -Wsizeof-array-argument:當把 sizeof 運算子用在宣告為陣列的參數時,就會噴警告。(譯註9)
  • 加入新選項 -Wbool-compare:當布林表示式 (Boolean Expressions) 拿去跟非 True/False 的整數值比較時會噴警告。(譯註10)
  • 完整的 Cilk Plus 支援, Cilk Plus 是 C/C++ 資料/任務平行化的語言擴充。
  • 新的屬性 (attribute) no_reorder 來避免 GCC 重排選定符號的順序,例如特定的符號 (Symbol) 或內嵌組合語言 (inline assembler),這可以讓 Linux kernel 在開 LTO 時避免因開啟 -fno-toplevel-reorder 而關掉許多最佳化。
  • 新的前置處理器指令 __has_include 以及 __has_include_next ,可以測試是否該標頭檔 (Header File) 是否可用。 例如我們要測試 這個標頭檔是否可用:
    #ifdef __has_include
    #  if __has_include(<optional>)
    #    include <optional>
    #    define have_optional 1
    #  elif __has_include(<experimental/optional>)
    #    include <experimental/optional>
    #    define have_optional 1
    #    define experimental_optional
    #  else
    #    define have_optional 0
    #  endif
    #endif
    
    其中 __has_include 以及 __has_include_next 的搜索路徑等價於 #include 以及 #include_next 的搜索路徑規則。
  • 新的內建巨集 (Macro) __has_attribute 可以用來判斷是否支援某個屬性 (Attribute),等價於 C++ 中的 __has_cpp_attribute,但 __has_attribute 適用於所有 C 語言家族的語言。
    int
    #ifdef __has_attribute
    #  if __has_attribute(__noinline__)
      __attribute__((__noinline__))
    #  endif
    #endif
    foo(int x);
    
    如果該屬性存在的話,會回傳一個非零的值,標準的 C++ 屬性則會回傳一個日期,其它則會回傳 1,__has_attribute 以及 __has_cpp_attribute 都會試著在前後加上雙底線去解析看看,C++11 及其後代中的屬性將可能會有作用域 (Scoped) 。
  • 新增一組新的內建函數 __builtin_add_overflow, __builtin_sub_overflow 以及 __builtin_mul_overflow,可用來檢查是否運算結果是否溢位,並且與 Clang 相容。這組內建函數會吃兩個整數 (兩個不需要同型別) ,然後會被延展成無限精確度的有號 +,- 或著 *,並且將期結果存回最後一個的參數,如果存進去的值與無限精準度運算的結果相等的話就會回傳 False (代表沒有溢位),否則回傳 True (代表發生溢位),最後一個參數的型別也可跟前兩個參數的型別不一樣,下面這個例子將展示 calloc 中用 __builtin_mul_overflow 來計算其大小:
    void *
    calloc (size_t x, size_t y)
    {
      size_t sz;
      if (__builtin_mul_overflow (x, y, &sz))
        return NULL;
      void *ret = malloc (sz);
      if (ret) memset (res, 0, sz);
      return ret;
    }
    
    在 i?86 或 x86-64 以上會被展開成一個乘法指令以及一個 jo (Jump On Overflow) 的指令
  • -fextended-identifiers 預設在 C++ 以及 C99 之後開啟,已修正許多 Extended Identifiers 的問題。(譯註11)

譯註7: -Wswitch-bool 的範例: $ cat switch.cpp

int foo (bool v){
  switch (v) {
    case true:
      return 10;
    case false:
      return 20;
  }
}
$ gcc switch.cpp
switch.cpp: In function 'int foo(bool)':
switch.cpp:2:12: warning: switch condition has type bool [-Wswitch-bool]
   switch (v) {
            ^

譯註8: -Wlogical-not-parentheses 的範例:

$ cat lnp.cpp
int lnp(int a)
{
  return !a > 0;
}
$ gcc lnp.cpp -Wlogical-not-parentheses -c
lnp.cpp: In function 'int lnp(int)':
lnp.cpp:3:13: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
   return !a > 0;
             ^

譯註9: -Wsizeof-array-argument 的範例: $ cat sz-of-array.c

int foo(int a[])
{
  return (int) sizeof (a);
}
$ gcc sz-of-array.c -c
sz-of-array.c: In function 'foo':
sz-of-array.c:3:23: warning: 'sizeof' on array function parameter 'a' will return size of 'int *' [-Wsizeof-array-argument]
   return (int) sizeof (a);
                       ^
sz-of-array.c:1:13: note: declared here
 int foo(int a[])
             ^

譯註10: -Wbool-compare 的範例: $ cat bool-cmp.cpp

bool bool_cmp(int a, int b)
{
  return (a > b) != 2;
}
$ g++ bool-cmp.cpp -c -Wall
bool-cmp.cpp: In function 'bool bool_cmp(int, int)':
bool-cmp.cpp:3:18: warning: comparison of constant '2' with boolean expression is always true [-Wbool-compare]
   return (a > b) != 2;
                  ^
值得注意的是如果如果值是 1 的話就不會發出警告: $ cat bool-cmp.cpp
bool bool_cmp(int a, int b)
{
  return (a > b) != 1;
}
$ g++ bool-cmp.cpp -c -Wall

譯註11: 以為是可以用中文當變數名稱了嗎,不,目前 GCC 的支援情況絕對比想像中破爛: FAQ#utf8_identifiers

C

  • 預設模式改為 -std=gnu11
  • 加入新選項 -Wc90-c99-compat ,當你使用到 C99 有但 C90 沒有的功能的時候會噴出警告。
  • 加入新選項 -Wc99-c11-compat ,當你使用到 C11 有但 C99 沒有的功能的時候會噴出警告。
  • 加入新選項 -Wno-incompatible-pointer-types ,此選項可關閉不同型別的指標間互轉的警告
  • 加入新選項 -Wno-int-conversion ,此選項可關閉整數與指標間互轉的警告。
  • 加入新選項 -Wno-discarded-qualifiers ,此選項可關閉不同 qualifiers 間互轉的警告 (譯註12)。
  • 加入新選項 -Wno-discarded-array-qualifiers ,此選項可關閉多維陣列間有無 const 轉換的警告。
  • 現在 C 語言前端產生更精確更可讀的診斷訊息。
  • 在 LTO 模式下,-pg 選項僅影響有下該選項編譯的檔案。

譯註12: 例如將 const int * 轉到 int *

C++

  • G++ 現在支援 C++14 的 variable template。
  • -Wnon-virtual-dtor 不會對標上 final 的 class 抱怨了。
  • 過深的 template 具現化現在列為錯誤,避免過多的診斷訊息,通常這類訊息對找出問題沒有幫助。
  • G++ 以及 libstdc++ 目前實做了在 C++ 標準中建議的功能測試巨集 (Feature-testing Macro)。
  • G++ 現在允許 typename 當作 template 的參數了
    template<template<typename> typename X> struct D; // OK
    
  • G++ 現在支援 C++ 針對非靜態資料成員 (Non-static Data Member) Aggregates 式的初始化。
    struct A { int i, j = i; };
    A a = { 42 }; // a.j is also 42
    
  • G++ 現在支援 C++14 的 extended constexpr。
    constexpr int f (int i)
    {
      int j = 0;
      for (; i > 0; --i)
        ++j;
      return j;
    }
    
    constexpr int i = f(42); // i is 42
    
  • G++ 現在支援 C++14 的 sized deallocation 函數。
    void operator delete (void *, std::size_t) noexcept;
    void operator delete[] (void *, std::size_t) noexcept;
    
  • 新增對於違反 One Definition Rule 的警告提示,在 LTO 的時候會偵測是否有不批配的型別定義以及 Virtual Table,可由 -Wodr 控制開關。
  • 新增新的警告提示 -Wsuggest-final-types 以及 -Wsuggest-final-methods,可用來提示開發者要在哪邊加 final 以增進程式效率,可以用在編譯時期使用,但在 LTO 下會更有用。
  • G++ 不再之支援 N3639 的可變長度陣列,那玩意兒已經從 C++14 中移除,但 GNU 的 VLA 一樣有支援,所以要用的話記得用 -std=gnu++14, -std=gnu++11 或 -std=gnu++98 模式。
  • G++ 支援在 C 的可變長度參數中傳遞 Non-Trivially-Copyable 的類別,不過要切記這在標準中是實做相依 (Implementation-Defined) 的,Calling Convention 方面比照一般參數方式。

Runtime Library (libstdc++)

  • 預設使用新的 std::string 實做,使用短字串最佳化,捨棄 copy-on-write 的參考計數 (Reference Counting) 機制。
  • 預設使用新的 std::list 實做,size() 的時間複雜度變為 O(1) 。
  • 完整的 C++11 支援,包含以下新功能: - std::deque 以及 std::vector 符合 allocator-aware container 的要求了。 - iostream 類別現在可移動 (movable) 以及可交換 (swappable) 了。 - 支援 std::align 以及 std::aligned_union。 - 支援 type traits : std::is_trivially_copyable, std::is_trivially_constructible 及 std::is_trivially_assignable 等等。 - 支援 I/O 操作子 (I/O manipulator):std::put_time, std::get_time, std::hexfloat 和 std::defaultfloat。 - 區域設定感知能力 (Generic Locale-aware) 的 std::isblank。 - Unicode 轉換支援 locale facets。 - std::shared_ptr 一律採用 Atomic Operation。 - std::notify_all_at_thread_exit() 以及其它 future 的相關函數實做完成。
  • 支援 C++11 在 ios_base::fixed|ios_base::scientific 已經設定的情況下 hexfloat 操作子 (manipulator) 的行為。這項改變影響所有的模式例如 C++98,要避免顯示十六進位的浮點數的話可透過 str.unsetf(std::ios_base::floatfield) 來清除相關的 str.flags()。
  • 完整的 C++14 實驗性支援,包含以下功能:
  • 改善一些實驗性的函數庫包含:
    • class std::experimental::any;
    • function template std::experimental::apply;
    • function template std::experimental::sample;
    • function template std::experimental::search and related searcher types;
    • variable templates for type traits;
    • function template std::experimental::not_fn.
  • 新的亂數產生器:logistic_distribution 以及 uniform_on_sphere_distribution。
  • 新增容器以及 std::unique_ptr 的 GDB Xmethods

Go

  • GCC 5 完整實做 Go 1.4.2了。
  • 建置 GCC 5 時如果開啟 Go 支援的話會多安裝兩個程式:go 跟 gofmt。

libgccjit

GCC 5 可以把整個 GCC 建置成一個共享程式庫讓開發者可以將 GCC 嵌入至其它的程式中 (例如直譯器),可以拿來 Just-In-Time 的編譯成機械碼。

目前共享程式庫提供 C 的 API 並且有提供包裝過後的 C++ API, 另外也有第三方支援 Python 及 D 的 binding。

舉例來說這項新功能可以讓直譯器編譯一個函數從 Byetcode 變成機械碼。

另外也可以來來當作 Ahead-Of-Time 編譯技術的一部分,讓 GCC 可以跟其它現有的語言前端組合起來,例如官方的 Wiki 頁面提供一個 brainfuck 的範例

libgccjit 目前採用 GPLv3 (或著任何後繼版本)。

目前這部份屬於實驗性質的玩意兒。

新的 Target 以及 Target 相關改善:

AArch64

  • 針對 Cortex-A57 處理器的 Code Gen 大幅改善,可使用 -mcpu=cortex-a57 或 -mtune=cortex-a57 來啟用相關最佳化,有更精準的指令排程 (Instruction Scheduling),以及許多內部編譯器的參數調整調整。
  • 針對 Cortex-A53 erratum 835769 的 Workaround 可用 -mfix-cortex-a53-835769 來啟動,另外在建置 GCC 的時候也可下 --enable-fix-cortex-a53-835769 來預設開啟此 Workaround。
  • 當使用 -mcpu=cortex-a53, -mcpu=cortex-a57 or -mcpu=cortex-a57.cortex-a53 時,加密指令集不再預設開啟,要啟用的話就要在 -mcpu 或 -march 後面在加個 +crypto ,例如 -mcpu=cortex-a53+crypto。
  • 支援 Cortex-A72 及其與 Cortex-A53 的 big.LITTLE 組合 (cortex-a72.cortex-a53),以及 Cavium ThunderX (thunderx), Applied Micro X-Gene 1 (xgene1), 還有 Samsung Exynos M1 (exynos-m1),可透過 -mcpu=cortex-a72,-mcpu=cortex-a72.cortex-a53,-mcpu=thunderx,-mcpu=xgene1 以及 -mcpu=exynos-m1 來開啟相關支援。
  • 移除過渡期選項 -mlra 以及 -mno-lra ,AArch64 現在使用 Local Register Allocator (LRA)。

ARM

  • Thumb-1 的組合語言現在使用 Unified Syntax,並且加入一個新選項 -masm-syntax-unified ,來指定 Inline Assembly 是使用 Unified Syntax,預設這個選項是關閉的,不過未來將會改變這項預設值。
  • 當在組態時 (Configure-Time) 指定了 --with-cpu 又指定 --with-tune 或 --with-arch。
  • 針對 Cortex-A57 處理器的 Code Gen 大幅改善,可使用 -mcpu=cortex-a57 或 -mtune=cortex-a57 來啟用相關最佳化,有更精準的指令排程 (Instruction Scheduling),以及許多內部編譯器的參數調整調整。
  • 支援 Cortex-A72 及其與 Cortex-A53 的 big.LITTLE 組合 (cortex-a72.cortex-a53),以及 Cavium ThunderX (thunderx), Applied Micro X-Gene 1 (xgene1), 還有 Samsung Exynos M1 (exynos-m1),可透過 -mcpu=cortex-a72,-mcpu=cortex-a72.cortex-a53,-mcpu=thunderx,-mcpu=xgene1 以及 -mcpu=exynos-m1 來開啟相關支援。
  • 移除 -mwords-little-endian 選項。
  • -mapcs, -mapcs-frame, -mtpcs-frame 以及 -mtpcs-leaf-frame 這幾個適用於 OABI 的選項,將不建議使用 (Deprecated)。
  • 移除過渡期選項 -mlra 以及 -mno-lra ,ARM 現在使用 Local Register Allocator (LRA)。

IA-32/x86-64

  • 支援 Intel 處理器 Skylake 的新指令集 AVX-512{BW,DQ,VL,IFMA,VBMI} ,包含 Inline Assembly,以及 Intrinsics 還有基礎的自動向量化支援,可透過 -mavx512vl, -mavx512bw, -mavx512dq, -mavx512ifma 以及 -mavx512vbmi 來開啟.
  • 支援新的 MPX 指令集,可透過 -mmpx 開啟,這套指令集需要編譯器,執行時期函數庫以及 OS 的支援,透過執行時期的指標邊界檢查可有效增強軟體的可靠度,在 GCC 中透過 Pointer Checker 以及 libmpx 來支援其功能。
  • 加入新選項 -mrecord-mcount 來針對 -pg 選項來產生 Linux Kernel Style 的 mcount 或 __fentry__ 呼叫,以及新選項 -mnop-mcount 會產生 nop 放在 函數的開頭來,以利之後更改,這項功能可以拿來當作低成本追蹤 (Low Overhead Tracing) 或 Hot Code Patching。
  • 加入新選項 -malign-data 來控制 GCC 如何 align 變數,-malign-data=compat 用來與 GCC 4.8 及之前的版本相容,-malign-data=abi 則是會根據 psABI 來對齊,-malign-data=cacheline 則會試著對齊 cache line,目前 -malign-data=compat 是預設值。
  • 加入新選項 -mskip-rax-setup,可以用在當關閉 SSE 時,不需要設定 RAX 暫存器的狀態,這個選項可以用來最佳化 Linux Kernel。

NDS32

  • 更動可變動參數傳遞的 ABI,偏好會先放在暫存器裡面而不是 Stack 上。
  • 移除選項 -mforce-fp-as-gp, -mforbid-fp-as-gp, 以及 -mex9 ,因為在 binutils 的 nds32 port 上相關支援還沒上…
  • 加入新選項 -mcmodel=[small|medium|large] 來控制 Code Models, -mgp-direct 這個選項則不建議使用。

其它改善

  • gcc-ar, gcc-nm, gcc-ranlib 的 Wrapper 現在支援 -B 相關的選項,並且會傳遞給編譯器作為參考.
  • 新增選項 -freport-bug 來產生編譯器開發者友善的錯誤回報訊息。