[インデックス 13976] ファイルの概要
このコミットでは、Goコンパイラの内部で使用されるヘッダーファイルである src/cmd/5g/gg.h
、src/cmd/6g/gg.h
、および src/cmd/8g/gg.h
が変更されています。具体的には、これらのヘッダーファイルから一部の関数宣言が削除または移動され、コメントの修正が行われています。
コミット
- コミットハッシュ:
617b7cf166a99e1fe3326b6fc6985be9f83e51ca
- 作者: Rémy Oudompheng oudomphe@phare.normalesup.org
- 日付: 2012年9月27日 木曜日 08:34:00 +0200
- コミットメッセージ:
cmd/[568]g: header cleanup. R=golang-dev, r CC=golang-dev https://golang.org/cl/6573059
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/617b7cf166a99e1fe3326b6fc6985be9f83e51ca
元コミット内容
cmd/[568]g: header cleanup.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6573059
変更の背景
このコミットの目的は、Goコンパイラのヘッダーファイルの「クリーンアップ」です。2012年当時のGoコンパイラは、5g
(ARM向け)、6g
(AMD64向け)、8g
(x86向け) といった異なるアーキテクチャをターゲットとする複数のコンパイラで構成されており、これらはPlan 9のツールチェインを起源としていました。
「ヘッダーのクリーンアップ」という表現は、通常、以下のいずれかまたは複数の目的で行われます。
- 未使用の宣言の削除: もはやコードベースのどこからも参照されていない関数や変数の宣言をヘッダーファイルから削除し、コードの肥大化を防ぎ、可読性を向上させます。
- 宣言の適切な配置: 宣言がその機能に最も関連性の高いヘッダーファイルやセクションに移動されていない場合、それを適切な場所に移動します。これにより、モジュール性が向上し、依存関係が明確になります。
- コメントの修正: コードの変更やリファクタリングに伴い、古くなったコメントや誤ったコメントを修正し、コードの意図を正確に反映させます。
- 重複の排除: 複数のヘッダーファイルに同じ宣言が重複して存在する場合、それを一箇所に集約します。
このコミットでは、特に gg.h
という共通のヘッダーファイル群に対して、これらのクリーンアップ作業が行われたと考えられます。これは、コンパイラ内部のコードベースの保守性と理解しやすさを向上させるための、継続的なリファクタリングの一環です。
前提知識の解説
Goコンパイラ (5g
, 6g
, 8g
)
2012年当時、Go言語の公式コンパイラは gc
ツールチェインの一部として提供されており、主に以下の3つのコンパイラが存在しました。
5g
: ARMアーキテクチャ(例: Raspberry Piなどの組み込みシステムやモバイルデバイス)をターゲットとするGoコードをコンパイルするためのコンパイラです。6g
: AMD64(x86-64)アーキテクチャ(現在の一般的なデスクトップPCやサーバー)をターゲットとするGoコードをコンパイルするためのコンパイラです。8g
: 386(x86)アーキテクチャ(32ビットのIntel/AMDプロセッサ)をターゲットとするGoコードをコンパイルするためのコンパイラです。
これらのコンパイラは、Go言語のソースコードを各ターゲットアーキテクチャの機械語に変換する役割を担っていました。現在では、これらのコンパイラは go tool compile
コマンドの内部で抽象化されており、ユーザーが直接 5g
や 6g
を呼び出すことは稀になっています。
gg.h
ヘッダーファイル
gg.h
は、Goコンパイラの内部で使用されるヘッダーファイルです。C言語やC++におけるヘッダーファイルと同様に、他のソースファイルで利用される関数や変数の宣言(プロトタイプ)を含んでいます。これにより、コンパイラの異なるモジュール間で共通のインターフェースを共有し、コンパイル時に必要な情報を提供します。
Goコンパイラの初期の実装は、C言語の影響を強く受けており、このようなヘッダーファイルが多用されていました。src/cmd/[568]g/gg.h
というパスは、各アーキテクチャ固有のコンパイラ (5g
, 6g
, 8g
) のコマンドディレクトリ (src/cmd/5g
, src/cmd/6g
, src/cmd/8g
) の直下に配置されていることを示しています。
src/cmd
ディレクトリ構造
Goプロジェクトのソースコードリポジトリにおいて、src/cmd
ディレクトリは、Go言語のツールチェイン(コンパイラ、リンカ、アセンブラ、その他のユーティリティ)のソースコードを格納する場所です。各サブディレクトリは、特定のツールやコンパイラのフロントエンドに対応しています。例えば、src/cmd/5g
は 5g
コンパイラのソースコードを、src/cmd/6g
は 6g
コンパイラのソースコードを含んでいます。
技術的詳細
このコミットで行われた「ヘッダークリーンアップ」は、主に以下の技術的な変更を含んでいます。
-
gaddoffset
、setconst
、setaddr
関数の宣言削除:src/cmd/5g/gg.h
からgaddoffset
、setconst
、setaddr
の3つの関数宣言が削除されています。src/cmd/6g/gg.h
からgaddoffset
の関数宣言が削除されています。src/cmd/8g/gg.h
からgaddoffset
、setconst
、setaddr
の3つの関数宣言が削除されています。 これらの関数は、おそらくコンパイラの内部で特定のノード(抽象構文木の要素)に対するオフセットの追加、定数値の設定、アドレスの設定などを行うためのものでした。ヘッダーファイルからこれらの宣言が削除されたということは、これらの関数がもはや外部から呼び出される必要がなくなったか、あるいはその機能が別の場所に移管されたことを示唆しています。これは、コンパイラの内部構造がリファクタリングされ、これらの関数がより限定されたスコープで利用されるようになった可能性が高いです。
-
datastring
およびdatagostring
関数の宣言移動:src/cmd/6g/gg.h
からdatagostring
の関数宣言が削除され、gobj.c
セクションに移動されています。src/cmd/8g/gg.h
からdatastring
およびdatagostring
の関数宣言が削除され、gobj.c
セクションに移動されています。datastring
とdatagostring
は、おそらく文字列リテラルやGoの文字列データをオブジェクトファイルに書き込むための関数です。これらの関数がgobj.c
セクションに移動されたことは、それらがオブジェクトファイルの生成(gobj.c
は "Go Object" の略である可能性が高い)に関連する機能として論理的にグループ化されたことを意味します。これにより、ヘッダーファイルの役割がより明確になり、関連する宣言が一箇所に集約されることで、コードの保守性が向上します。
-
コメントの修正:
src/cmd/6g/gg.h
内のコメントで、gen.c
がggen.c
に、cgen
がcgen.c
に修正されています。 これは、ファイル名の誤記を修正するもので、コードの機能には直接影響しませんが、ドキュメントとしての正確性を高め、将来の開発者がコードを理解する上での混乱を防ぎます。
これらの変更は、Goコンパイラの内部構造が進化し、より整理されたモジュール設計へと移行している過程を示しています。不要な宣言の削除や関連する宣言の集約は、コードベースの複雑性を軽減し、長期的なメンテナンスを容易にするための重要なステップです。
コアとなるコードの変更箇所
src/cmd/5g/gg.h
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -117,14 +117,11 @@ void clearp(Prog*);
void proglist(void);
Prog* gbranch(int, Type*, int);
Prog* prog(int);
-void gaddoffset(Node*);
void gconv(int, int);
int conv2pt(Type*);
vlong convvtox(vlong, int);
void fnparam(Type*, int, int);
Prog* gop(int, Node*, Node*, Node*);
-void setconst(Addr*, vlong);
-void setaddr(Addr*, Node*);
int optoas(int, Type*);
void ginit(void);
void gclean(void);
src/cmd/6g/gg.h
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -58,7 +58,7 @@ EXTERN Node* throwreturn;
extern vlong unmappedzero;
/*
- * gen.c
+ * ggen.c
*/
void compile(Node*);
void proglist(void);
@@ -81,7 +81,7 @@ void ginscall(Node*, int);
int gen_as_init(Node*);
/*
- * cgen
+ * cgen.c
*/
void agen(Node*, Node*);
void igen(Node*, Node*, Node*);
@@ -103,7 +103,6 @@ void clearp(Prog*);
void proglist(void);
Prog* gbranch(int, Type*, int);
Prog* prog(int);
-void gaddoffset(Node*);
void gconv(int, int);
int conv2pt(Type*);
vlong convvtox(vlong, int);
@@ -125,7 +124,6 @@ int isfat(Type*);
void sudoclean(void);
int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*);
-void datagostring(Strlit*, Addr*);
void nodfconst(Node*, Type*, Mpflt*);
/*
@@ -139,6 +137,7 @@ void complexgen(Node*, Node*);
* gobj.c
*/
void datastring(char*, int, Addr*);
+void datagostring(Strlit*, Addr*);
/*
* list.c
src/cmd/8g/gg.h
--- a/src/cmd/8g/gg.h
+++ b/src/cmd/8g/gg.h
@@ -122,14 +122,11 @@ void clearp(Prog*);
void proglist(void);
Prog* gbranch(int, Type*, int);
Prog* prog(int);
-void gaddoffset(Node*);
void gconv(int, int);
int conv2pt(Type*);
vlong convvtox(vlong, int);
void fnparam(Type*, int, int);
Prog* gop(int, Node*, Node*, Node*);
-void setconst(Addr*, vlong);
-void setaddr(Addr*, Node*);
int optoas(int, Type*);
int foptoas(int, Type*, int);
void ginit(void);
@@ -141,8 +138,6 @@ void nodreg(Node*, Type*, int);
void nodindreg(Node*, Type*, int);
void nodconst(Node*, Type*, int64);
void gconreg(int, vlong, int);
-void datagostring(Strlit*, Addr*);
-void datastring(char*, int, Addr*);
void buildtxt(void);
Plist* newplist(void);
int isfat(Type*);
@@ -161,6 +156,12 @@ int complexop(Node*, Node*);
void complexmove(Node*, Node*);
void complexgen(Node*, Node*);
+/*
+ * gobj.c
+ */
+void datastring(char*, int, Addr*);
+void datagostring(Strlit*, Addr*);
+
/*
* list.c
*/
コアとなるコードの解説
gaddoffset
, setconst
, setaddr
の削除
これらの関数は、Goコンパイラのコード生成フェーズにおいて、抽象構文木 (AST) のノードやアドレス構造体 (Addr*
) を操作するために使用されていたと考えられます。
gaddoffset(Node*)
: ASTノードに関連するオフセットを追加する機能。setconst(Addr*, vlong)
: 特定のアドレスに定数値を設定する機能。setaddr(Addr*, Node*)
: 特定のアドレスにASTノードの情報を設定する機能。
これらの宣言が gg.h
から削除されたことは、以下のいずれかの理由が考えられます。
- 機能の廃止または統合: これらの関数がもはやコンパイラの現在の設計では必要とされなくなったか、あるいはその機能がより高レベルの抽象化された関数に統合された可能性があります。
- 内部的な利用への変更: これらの関数が、もはやヘッダーファイルを通じて外部に公開される必要がなく、特定のソースファイル内でのみ使用されるようになった可能性があります。これにより、ヘッダーファイルのインターフェースが簡素化され、モジュール間の結合度が低下します。
- より適切なヘッダーへの移動: これらの関数が、より具体的な機能を持つ別のヘッダーファイルに移動された可能性もあります。
いずれにしても、これはコンパイラの内部構造がより整理され、特定の機能がより適切にカプセル化されるようになったことを示唆しています。
datastring
および datagostring
の gobj.c
セクションへの移動
datastring(char*, int, Addr*)
: Cスタイルの文字列(char*
)をデータセクションに書き込むための関数。datagostring(Strlit*, Addr*)
: Goの文字列リテラル(Strlit*
)をデータセクションに書き込むための関数。
これらの関数は、コンパイルされたプログラムのデータセクションに文字列データを配置する役割を担っています。src/cmd/6g/gg.h
と src/cmd/8g/gg.h
からこれらの宣言が削除され、代わりに /* gobj.c */
というコメントブロックの下に再宣言されています。
この変更は、以下の意図があると考えられます。
- 論理的なグループ化:
gobj.c
は「Go Object」に関連するコードを扱うファイルであると推測されます。文字列データをオブジェクトファイルに書き込む機能は、オブジェクト生成のプロセスの一部であるため、これらの関数をgobj.c
に関連するセクションに移動することで、コードの論理的な構造が改善されます。 - 依存関係の明確化: これにより、
datastring
とdatagostring
がgobj.c
の実装に密接に関連していることが明確になります。ヘッダーファイルは、その宣言がどのソースファイルで実装されているかを示すことで、開発者がコードベースをナビゲートしやすくなります。
コメントの修正 (gen.c
-> ggen.c
, cgen
-> cgen.c
)
これは単純なタイポの修正です。gen.c
は ggen.c
の誤記であり、cgen
は cgen.c
の誤記であったと考えられます。このような修正は、コードのドキュメンテーションとしての正確性を高め、将来のコードリーディングやメンテナンスの際に誤解を防ぐために重要です。
全体として、このコミットはGoコンパイラの内部ヘッダーファイルを整理し、コードの可読性、保守性、およびモジュール性を向上させるための、細かではあるが重要なリファクタリング作業を示しています。
関連リンク
- Go Change List (CL): https://golang.org/cl/6573059
参考にした情報源リンク
- cheney.net: Goコンパイラ
5g
,6g
,8g
に関する情報- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQErcGk0d3IE1yQ4PUZqeDEpPRutg3GNxMxdqvTZJfZ20QhuwlHYUH8N6G6RSnwqUFwAep7AFZ5Aoe6DcFV1XNfPCSnyIafWnXUOn90Uza8VYgDRBOP5nZWr5jXZdzS6F_J0PQJdK3iFHsct0nVpHsEgptbLTckbWXqaIvtGDqZHRg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG2h060c2GUlSl7RjDPB_jOo0Z3wvSX-8o9yemcwYWEuxbhzpS_1iu3SxX4Y6RNjeoDnmSYMNoSNBZdWa-pfLUniEEj-Us6y-7YwhFTb3rvJXcSCo0wbGMnYSyO5_hANg==
- googlesource.com:
src/cmd/5g/gg.h
の存在に関する情報 - go.dev: Goツールの再編成に関する情報
- kth.se:
gccgo
に関する情報