tohereはじめにHaskell用コンパイラであるGHCは、驚くほど多彩な情報出力機能を標準で搭載しています。出力できる情報は非常に沢山ありますが、ここでは、以下のいくつかの方法について簡単にまとめて紹介します。実行オブジェクトの実行時における情報の出力方法なお、本記事では、stackコマンド経由ではなく、素のGHCを使う場合について説明しています。--コマンドの様に読み替えてください。LTS)環境によるものです。ghciでの対話操作による情報の出力方法ここでは、GHCの対話環境(REPL)であるghciコマンドを用いた、情報の出力方法について紹介します。+vコマンド)種(kind)の情報の出力(:kコマンド)名前の内容についての情報の出力(:iコマンド)その他いろいろなコマンド以下、各々の例について説明します。tohere型(type)の情報の出力(:tコマンド)GHCの対話環境であるghci上で、:tコマンド(または省略しない形の:typeコマンド)を実行することにより、変数や関数などについての型の情報を表示できます。lengthコマンドの実行例です。length次の様に出力されます。a型の値を入力して、Int型の値を返す関数である」ことを示しています。「型変数tはFoldableクラスに属する」ことを示しています。+dコマンド)GHC8.2で導入された新しい機能です。+dコマンド)を実行することにより、デフォルトの型を考慮して、型の情報を分かりやすく出力できます。length次の様に出力されます。aの部分がリスト型として具体化されて出力されています。+vコマンド)GHC8.2で導入された新しい機能です。+vコマンド)を実行することにより、型についての情報をより詳しく出力できます。length次の様に出力されます。a.の部分が詳しく出力されています。tohere種(kind)の情報の出力(:kコマンド):kコマンド(または省略しない形の:kindコマンド)を実行することにより、種(カインド)についての情報を出力できます。Maybe次の様に出力されます。*上の例では、Maybe型は、*の種を入力し、*の種を返す型であることを出力します。tohere名前の内容についての情報の出力(:iコマンド):iコマンド(または省略しない形の:infoコマンド)を実行することにより、その名前の定義情報などを出力できます。length次の様に出力されます。‘Data.Foldable’上の例では、lengthの定義内容(関数であり、Foldableクラスに属しており、Data.Foldableモジュール内で定義されていること)が出力されています。tohereその他、ghciのいろいろなコマンド他にもghciのコマンドにより、様々な情報を対話的に出力させることが出来ます。コマンドのヘルプghciのコマンドの詳細は、こちらを参照してください。ghciのコマンドや、型や種(カインド)については、こちらやこちらも参考になります。コンパイル時における情報の出力方法ここでは、GHCのコンパイル時における、情報の出力方法について紹介します。以下、各々の例について説明します。tohereコンパイル時の各ステージごとの中間コードの出力GHCは、コンパイル時に、中間言語変換などの複数のパイプラインステージを経ながら、最終的にアセンブリコードを生成します。コンパイル時に情報出力用のオプションを指定することにより、それらの各ステージごとの中間コードを出力できます。以下の単純なソースの場合について例を示します。y以下、GHCのコンパイル・パイプラインにおける、パーサーやリネームなどの各ステージ後のコード出力例を示します。tohereパーサー後GHCのコンパイルにおける、パーサーのステージ直後のコードを出力するには、-ddump-parsedオプションを指定します。Func1.hsパーサー後のコードが、以下の様に出力されます。y上の例では、元のソースと同じコードが表示されました。以下は、リネームのステージ直後のコードを出力する、-ddump-rnオプションの例です。Func1.hs以下の様に出力されます。y_aRg上の例では、ユニークな識別子に変換されたコードが出力されています。上の例では、ソースファイルの最終更新時刻が、オブジェクトファイルよりも古い場合でも強制的に再コンパイルさせる-fforce-recompを指定しています。以下、いくつかのステージ後の中間コードの出力例を、続けて示します。:上の例では、Haskell言語の構文から、GHCの内部表現の1つであるCore言語に変換されたコードが出力されています。Core言語は、非常にシンプルな要素で構成された関数型言語です。:上の例では、さらに、GHCの内部表現の1つであるSTG言語に変換されたコードが出力されています。STG言語は、非常にシンプルな要素で構成された、GHCの動作モデルと結びついた関数型言語です。:上の例では、さらに、GHCの内部表現の1つであるCmm言語に変換されたコードが出力されています。minus)言語は、C言語とアセンブリ言語の中間的な位置づけの、手続き型言語です。:上の例では、最終的なターゲットCPU用のアセンブリ言語の命令コードが出力されています。詳細は省略しますが、他にも様々なステージの情報を出力させることが出来ます。中間コードの出力方法の詳細は、こちらを参照してください。中間言語については、こちらも参考になります。tohere型情報の出力コンパイル時に得られる型情報を出力することが出来ます。以下の単純なソースの場合について例を示します。bコンパイル時に得られる型情報を出力するには、-ddump-typesオプションを指定します。Func2.hs以下の様に出力されます。integer-gmp-1.0.1.0]それぞれの型の情報が出力されています。tohere正格性情報の出力コンパイル時に得られる正格性についての情報を出力することが出来ます。以下の単純なソースの場合について例を示します。恣意的な例ですが、関数f3の第1引数は正格(かつ関数内で使用されている)、第2引数は非正格(かつ関数内で使用されている)、第3引数は非正格(かつ関数内で使用されていない)という場合の例です。yコンパイル時に得られる、関数の各引数についての正格性の情報を出力するには、-ddump-str-signaturesオプションを指定します。正格性についての最適化を行うために、-Oオプションも併せて指定します。Func3.hs正格性についての情報が、以下の様に出力されます。<S(S),1*U(1*U)><L,1*U(U)><L,A>m上の例によると、第1引数は、<S(S),1*U(1*U)>の部分により表されています。ここでのS(S)は、引数が正格(Strict)であることを示しています。1*U(1*U)は、引数が関数内で使用(Use)されていることを示しています。第2引数は、<L,1*U(U)>の部分により表されています。Lは引数が非正格(non-strict)であることを示しています。1*U(U)は、引数が関数内で使用(Use)されていることを示しています。第3引数は、<L,A>の部分により表されています。Lは引数が非正格(non-strict)であることを示しています。Aは、引数が関数内で不使用(Absence)であることを示しています。正格性解析については、こちらも参考になります。tohereその他、コンパイル時のいろいろなオプション他にも、コンパイル時に様々な情報を出力させることが出来ます。コンパイル時にコンパイラの詳細情報を出力コンパイル時のオプションの詳細は、こちらを参照してください。実行オブジェクトの実行時における情報の出力方法ここでは、GHCによりコンパイルされた実行オブジェクトについて、実行時に情報を出力する方法を紹介します。以下、各々の例について説明します。tohere実行時の統計情報の出力GHCによりコンパイルされた実行オブジェクトについて、実行時の統計情報を出力できます。以下のソースの場合について例を示します。[1..10000000]まずは、普通にコンパイルを行います。ここでは、通常の例を示すために、標準的な最適化を行う-Oオプションを指定しています(プロファイル取得に必須ではありません。-sオプションを指定します。(+RTS以降の引数が、GHCのランタイムシステム(RTS)に引き渡されます。ここでは、-sが統計情報出力のためのオプションです。-s以下の様に、実行時の統計情報が出力されます。elapsed上の例では、全体の実行時間やヒープの割当量やGCの概況等が出力されています。表示内容の詳細については、こちらを参照してください。tohere時間プロファイルの出力GHCによりコンパイルされた実行オブジェクトについて、実行時の時間プロファイル情報を出力できます。以下のソースの場合について例を示します。-fprof-autoオプションを指定します。-rtsoptsは、実行オブジェクトの実行時に、GHCのランタイムシステム(RTS)用の引数を使用可能にするオプションです。-profは、プロファイル用のコードを埋め込むためのオプションです。-fprof-autoは、プロファイルを取得する対象を自動で設定するオプションです。-pオプションを指定します。(-pが時間プロファイル情報出力のためのオプションです。-pこれにより、時間プロファイル情報が、Prog2.profファイルに以下の様に出力されます。:上の例では、mainやf1やf2などについて、関数ごとの実行時間が出力されています。時間プロファイルの表示内容の詳細については、こちらを参照してください。時間プロファイルについては、こちらや、こちらも参考になります。tohere空間プロファイルの出力GHCによりコンパイルされた実行オブジェクトについて、実行時の空間プロファイル情報、つまり、ヒープメモリの使用状況等を出力できます。以下のソースの場合について例を示します。-fprof-autoオプションを指定します。-rtsoptsは、実行オブジェクトの実行時に、GHCのランタイムシステム(RTS)用の引数を使用可能にするオプションです。-profは、プロファイル用のコードを埋め込むためのオプションです。-fprof-autoは、プロファイルを取得する対象を自動で設定するオプションです。ここでは、メモリ使用状況を分かりやすくするために、最適化のレベルを下げる-O0オプションを指定しています(プロファイル取得に必須ではありません)。-hcオプションを指定します。(-hcが時間プロファイル情報出力のためのオプションです。-i0.1これにより、プロファイル情報が、Prog3.hpファイルに生成されます。上の例では、-iオプションにより、プロファイルを取得する間隔を秒単位で指定しています。この例では、0.1秒単位にプロファイル情報を取得しています。秒数は、状況に併せて調整してください。以下の様に、GHCに標準で付属しているhp2psコマンドを実行することにより、生成されたプロファイル情報を、、PostScriptファイルに変換できます。Prog3.hpさらに、OSプラットフォームに応じたコマンドなどにより、PostScriptファイルをPDFに変換します。ここでは、ps2pdfコマンドを使用しています。Prog3.pdfこれにより、以下の様に、空間プロファイルがグラフィカルに表示されます。空間プロファイルの表示内容の詳細については、こちらを参照してください。空間プロファイルについては、こちらや、こちらも参考になります。tohere実行時イベントの出力GHCによりコンパイルされた実行オブジェクトについて、実行時のイベント情報を出力できます。実行時のイベントとは、GHCのランタイムシステム(RTS)におけるスレッドスケジューラやGCなどの動作情報や、ユーザー指定による動作情報です。以下のソースの場合について例を示します。-eventlogオプションを指定します。-eventlogが、イベントログを出力するためのオプションです。-lオプションを指定します。(-lが実行時イベントを出力するためのオプションです。-lこれにより、実行時のイベント情報が、Prog4.eventlogファイルにバイナリ形式で出力されます。バイナリ形式の出力を表示するには2種類の方法があります。ThreadscopeコマンドによりGUIで表示する方法と、ghc-eventsコマンドによりテキスト形式で表示する方法です。どちらも、コマンドを別途インストールする必要があります。以下は、1つめの方法であるThreadScopeを用いた表示例です。こちらからthreadscopeのバイナリを入手するか、以下の方法により、threadscopeコマンドをインストールしてください。threadScopeそして、以下のコマンドによりThreadscopeを起動します。Prog4.eventlog以下の様にGUIが起動し、スレッドの稼動状態やGCの状態を可視化できます。上の例では、緑の部分がスレッドの稼働中、橙の部分がGCの稼働中を表しています。同時に1つスレッドのみが稼働していることが分かります(物理CPUが1個に制限されたハードウェアでの実行例です。以下は、2つめの方法であるghc-eventsを用いた表示例です。以下の方法により、ghc-eventsコマンドをインストールしてください。ghc-eventsそして、以下のコマンドにより、イベントの内容をテキスト形式で表示できます。Prog4.eventlog以下の様に、テキスト形式でイベント状況が詳細に表示されます。:上の例では、スレッドの生成や停止の状況が詳細に出力されています。実行時イベントログ機能の詳細については、こちらを参照してください。実行時イベントログ機能については、こちらも参考になります。tohereコードカバレッジの出力GHCによりコンパイルされた実行オブジェクトについて、実行時のコードカバレッジ情報を出力できます。以下のソースの場合について例を示します。40コードカバレッジを取得するためには、以下の様にまず、コンパイル時に、-fhpcオプションを指定します。Prog5.hsさらに、コンパイルされた実行オブジェクトを起動するだけで、実行時のコードカバレッジを出力できます。./Prog5これにより、コードカバレッジ情報が、Prog5.tixファイルにバイナリ形式で出力されています。reportコマンドを実行することで、コードカバレッジの概況をテキスト形式で出力できます。Prog5以下の様に、コードカバレッジの概況がテキスト形式で出力されます。markupコマンドを実行することで、HTMLファイルの形式で情報を出力することもできます。Prog5以下の様に、モジュールごとに詳細なHTMLファイルが生成されます。hpc_index_exp.html生成されたHTMLファイルでは、モジュールごとの概況が以下の様に表示されます。モジュール内の詳細状況も以下の様に表示されます。上の例では、f4は、評価(実行)されていないパスである事が分かります。コードカバレッジの詳細については、こちらを参照してください。コードカバレッジについては、こちらも参考になります。tohereスタックトレースの出力GHCによりコンパイルされた実行オブジェクトについて、実行時のエラー発生時のスタックトレース情報を出力できます。以下のソースの場合について例を示します。-fprof-autoオプションを指定します。-rtsoptsは、実行オブジェクトの実行時に、GHCのランタイムシステム(RTS)用の引数を使用可能にするオプションです。-profは、プロファイル用のコードを埋め込むためのオプションです。-fprof-autoは、プロファイルを取得する対象を自動で設定するオプションです。-xcオプションを指定します。(-xcがスタックトレース出力のためのオプションです。-xcこれにより、エラー時のスタックトレース情報が、次の様に出力されます。mainの順に呼び出されてきたことが分かります。スタックトレースの詳細については、こちらを参照してください。スタックトレースについては、こちらも参考になります。その他、実行時のオプションの詳細は、こちらを参照してください。tohere補足さらに、以下の様に、コンパイラ自身についての、情報を出力する方法もあります。Hacking!以上です。ライセンスの下に提供されています。Analyticsでアクセス情報を収集しています。集めた情報は統計的に処理した上で、当ウェブサイトの改善のための参考情報としてのみ使用します。