LoginSignup
6
0

More than 1 year has passed since last update.

MacOSで「ElixirでElixirコンパイラを作る」の補足

Last updated at Posted at 2019-07-02

fukuoka.exのhisawayです.
この記事は下記の@piacerex さんのコラムのMac版になります.

Linux版も作成予定です.


動作環境

Mac OS: 10.14.6
Erlang/OTP: 22
Elixir: 1.9.0

LLVM

MacOS付属のXCode4.0からApple LLVMと呼ばれるものが使われています.

wikipediaのXCode(英語)によるとXCode4.0はMacOS 10.6.6(Snow Leopard)以上のバージョンで動作するようなので記事のお試しがしたいだけなら,インストールの必要はなさそうです.

追記

ただし,ErlangをMakeする際に使用するCコンパイラによっては性能(実行速度)が変わるようです.

今日知った衝撃の事実。Elixir は,Erlang を GCC でコンパイルするのか,Clang でコンパイルするのか,Apple Clang でコンパイルするのかによって,性能がかなり異なる。

元記事と全く同じにする場合は本家のClangをインストールしなくてはなりません.

幸いなことにHomebrewでClang及びGCCがインストールできるので,これに甘えましょう.

brew install clang

入っているか確認

cc --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

ちゃんとコマンドラインツールに入ってますね.
ここで出てきたTargetはあとで使います.

LLVM/ClangでC++コードをコンパイル

シンプルにするために0を返すだけのプログラムをコンパイルしましょう.

ret.cpp
int main(){
  return 0;
}
> clang++ ret.cpp -o ret
> ret
> echo $status
0

LLVM IRの生成

std::cout << "Hello" << endl;とかにすると1000行ちょいのファイルが出来上がるので,大人しく0を返すだけのプログラムを使います.

> clang++ hello.cpp -S -emit-llvm -O0
> llc ret.ll
> clang++ ret.s -o ret
> ./ret
> echo $status
ret.ll
; ModuleID = 'ret.cpp'
source_filename = "ret.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"

; Function Attrs: noinline norecurse nounwind optnone ssp uwtable
define i32 @main() #0 {
  %1 = alloca i32, align 4
  store i32 0, i32* %1, align 4 ; 0
  ret i32 0
}

attributes #0 = { noinline norecurse nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}

ここからは②の内容になります.
Elixirコンパイラ②をElixirで作る:LLVM IRをElixirで生成(ASTはElixirマクロ互換)→再帰下降構文解析→ネイティブコード生成

とは言ってもほぼ同じです.

違うのはサポートする対象を表すtarget tripleだけです.
cc --versionからコピペしてくれば動きます.
具体的には,関数emit_prefixが変わります.

> cc --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
def emit_prefix() do
        # 下記の設定は手元PCでは必須では無い模様(お手元でうまく動かないときは文字列中に含めてください)
        # source_filename = "add.cpp"
        # target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"

        """
        target triple = "x86_64-apple-darwin18.6.0"
        """ |> IO.puts 
    end

まとめ

簡単ですが,MacOSで「ElixirでElixirコンパイラ」の補足をしました.

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0