Mercurial > hg > CbC > CbC_gcc
comparison CbC-memo.ja @ 29:cc07adb17855
deleting old commented out code.
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 26 Nov 2009 13:27:48 +0900 |
parents | |
children | ab0bcb71f44d |
comparison
equal
deleted
inserted
replaced
28:f2ea7e07d030 | 29:cc07adb17855 |
---|---|
1 GCC | |
2 | |
3 | |
4 | |
5 | |
6 [[configureオプションの追加]] | |
7 $ cd gcc | |
8 $ vi configure.ac | |
9 ... | |
10 $ autoheader-2.59 # versionはconfigure.acの中に書いてある奴に合わせる | |
11 $ autoconf-2.59 | |
12 $ vi Makefile.in | |
13 これでconfigureスクリプトが完成するが、このautoconfはtarボールでは成功しない | |
14 svnリポジトリからチェックアウトしないと必要な関数が定義されてないのでエラーになる | |
15 なのでチェックアウトしたものでconfigureを生成したあと、それだけコピーしてこればOK | |
16 TOPディレクトリでは | |
17 $ autogen Makefile.def | |
18 $ autoconf-2.59 | |
19 ただしこれを使うことはないと思われる? | |
20 | |
21 | |
22 [[fastcall i386]] | |
23 1: %ecx | |
24 2: %edx | |
25 3: (%esp) | |
26 4: 4(%esp) | |
27 5: 8(%esp) | |
28 | |
29 __attribute__((noreturn)): 今のところこれでは問題が出ない | |
30 __attribute__((fastcall)): こっちはいろいろ問題あり | |
31 | |
32 | |
33 fastcallで起こる問題: | |
34 せっかく計算したebpが上書きされてしまっている | |
35 ecxに退避してそこにjmpすれば動く (これを直にかける?) | |
36 expand_cbc_gotoを直す必要がある | |
37 08048714 <returner>: | |
38 8048714: 53 push %ebx | |
39 8048715: 83 ec 28 sub $0x28,%esp | |
40 8048718: 89 4c 24 0c mov %ecx,0xc(%esp) | |
41 804871c: 8b 44 24 0c mov 0xc(%esp),%eax | |
42 8048720: 89 44 24 1c mov %eax,0x1c(%esp) | |
43 8048724: 8b 44 24 1c mov 0x1c(%esp),%eax | |
44 8048728: 8b 00 mov (%eax),%eax | |
45 804872a: 01 44 24 0c add %eax,0xc(%esp) | |
46 804872e: 8b 44 24 1c mov 0x1c(%esp),%eax | |
47 8048732: 8b 58 08 mov 0x8(%eax),%ebx | |
48 8048735: 8b 44 24 1c mov 0x1c(%esp),%eax | |
49 8048739: 8b 40 04 mov 0x4(%eax),%eax | |
50 804873c: 8b 54 24 0c mov 0xc(%esp),%edx | |
51 8048740: 89 c1 mov %eax,%ecx | |
52 8048742: 83 c4 28 add $0x28,%esp | |
53 8048745: 5b pop %ebx | |
54 8048746: ff e3 jmp *%ebx | |
55 これを手動で直すと-O0でも-O2でも動くことが確認できた | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 **PROJECT CVS** | |
62 firefly.cr:~one/CVS_DB/CbC_Project/GCC | |
63 | |
64 -checkout | |
65 cvs co CbC_project/GCC | |
66 -commit | |
67 cvs commit | |
68 -import from 3rdparty source | |
69 tar xzvf gcc-xxx.tgz | |
70 cd gcc-xxx | |
71 cvs import -ko -m ".." CbC/project/GCC FSF_GCC REL_4_x_y | |
72 -merge | |
73 cd /temp | |
74 cvs checkout -jREL_4_2_1 -jREL_xxx CbC_project/GCC | |
75 もしくはすでに本流をcheckoutしているディレクトリで | |
76 cvs update -jREL_4_2_1 -jREL_4_2_2 でもできる? (4_2_2に移行時はこれをしたけど...まだ分かんない ) | |
77 cvs update -jREL_4_2_2 -jREL_4_2_3 | |
78 | |
79 | |
80 コンパイル時に実行されるプログラムは主に3つ | |
81 省略すると | |
82 cc1, as, collect2 | |
83 /usr/libexec/gcc/i386/redhat-linux/4.1.1/cc1 test.c -o test.s | |
84 as -o test.o test.s | |
85 /usr/libexec/gcc/i386/redhat/linux/4.1.1/collect2 ..... test.o | |
86 | |
87 cc1とcollect2は | |
88 gcc-core-4.2.0/gcc/内でコンパイルされるもの。 | |
89 必要なのはcc1だ。 | |
90 | |
91 | |
92 | |
93 CbCの実装 | |
94 tail callを使う。 | |
95 | |
96 tail call | |
97 関数の末尾呼び出しを最適化して、callでなくjmpで関数に飛ぶようになる。 | |
98 gcc -O1 -foptimize-sibling-calls か | |
99 gcc -O2 でコンパイルすればこの最適化が行われる。 | |
100 | |
101 最適化条件? (構造体未確認) | |
102 (推測!!) | |
103 返り値が同じ | |
104 呼ばれる関数の引数サイズが呼び出し側関数の引数サイズより小さい | |
105 | |
106 expand_gimple_basic_blockでstatement毎にRTLに変換されているが、 | |
107 ほとんどのstmtはexpand_expr_stmtに送られるけど、 | |
108 tail call の場合は expand_gimple_tailcallに直接送られる | |
109 | |
110 | |
111 **TEST BUILD** | |
112 mkdir build-test | |
113 cd build-test | |
114 ../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/installed --enable-checking=tree,rtl,assert | |
115 デバグのため、下の(a)を実行 | |
116 make | |
117 make install # これまでしないと処理系によってはerrorがいくつか... | |
118 | |
119 (a). 全てのMakefileの-O2 を -O0 に変更 viで :%s/-O2/-O0/gってとこか? | |
120 どうやら --prefix=...って、ちゃんとしないといけない? | |
121 stdio.hをインクルードしてるとエラーが出る。 | |
122 これはオレが失敗したのか?それともconfigureが悪いのか? | |
123 | |
124 $ CFLAGS="-O0 -gdwarf-2 -g3" ../GCC/configure ... | |
125 | |
126 | |
127 stdio.hをインクルードしたらerrorが出る問題 | |
128 firefly: --prefix=$PWD/USR-LOCALあり、別ディレクトリ | |
129 preinstall: NG postinstall: OK installed: OK | |
130 firefly: --prefixなし、別ディレクトリ | |
131 preinstall: NG postinstall: ?? | |
132 firefly: --prefixあり、同ディレクトリ | |
133 preinstall: NG postinstall: OK installed: OK | |
134 firefly(nativePkg): --prefixなし、別ディレクトリ | |
135 preinstall: NG | |
136 | |
137 chani: --prefix=$PWD/installedあり、同ディレクトリ | |
138 preinstall: OK | |
139 chani(nativePkg): --prefixなし、別ディレクトリ | |
140 preinstall: OK | |
141 | |
142 | |
143 | |
144 $PWD/installed/bin/gcc -O2 .... | |
145 $PWD/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 -O2 test01.c | |
146 browse_tree (tree) | |
147 debug_rtx(rtl) | |
148 | |
149 | |
150 | |
151 **GCC DEBUG** | |
152 gdb $BUILD-TEST/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 | |
153 プログラム内で | |
154 p browse_tree (current_function_decl) | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 cc1 | |
161 main.c, toplev.c, | |
162 | |
163 main() in main.c | |
164 | |
165 toplev_main() in toplev.c | |
166 general_init(argv[0]) | |
167 signal設定 | |
168 init_gcc() | |
169 decode_options(argc, argv) | |
170 randomize() | |
171 do_compile() in toplev.c | |
172 timevar_start(TV_TOTAL) | |
173 process_options() | |
174 compile_file() | |
175 | |
176 struct lang_hooks lang_hooks | |
177 この構造体にパーサ等の関数ポインタが含まれている。 | |
178 これはlanghooks-def.hでLANG_HOOKS_INITIALIZERが定義されているが、 | |
179 言語ごとの定義はcならc-objc-common.hで、各メンバの定義が入れ替えられる。 | |
180 | |
181 options | |
182 decode_options -O?などのオプションを処理 | |
183 handle_options その他のオプションを順番に走査 | |
184 コンパイル対象のファイル名を main_input_filenameに入れる | |
185 -で始まる引数があればhandle_optionを呼ぶ | |
186 handle_option オプションを処理する | |
187 | |
188 | |
189 compile_file() | |
190 lang_hooks.parse_file() == c_common_parse_file | |
191 c_parse_file() in c-parser.c Parse a single source file. | |
192 c_parser_translation_unit() in c-parser.c | |
193 c_parser_external_declaration() | |
194 | |
195 | |
196 c_parser_external_declaration() in c-parser.c | |
197 CPPのtokenはここで処理して通常のはc_parser_declaration_or_fndefに渡す | |
198 | |
199 全体を通して、c_parser *parserという変数が関数の第一引数に渡される。 | |
200 これがファイルをparseする際の状態を保持しているっぽい | |
201 | |
202 c_parser_declaration_or_fndef() | |
203 こいつがglobalな関数、変数の宣言を処理する。 | |
204 c_parser_declspecs() 基本type (int, char, strcut...) | |
205 declspecs_add_scspec(specs, tree) extern,inline,staticなどのstorageをspecsにおさめる(specsのフラグをたてる) | |
206 declspecs_add_type(specs, c_typespec t) int, char, longなど第2引数が型名、第1引数にそれを格納 | |
207 finish_declspecs() Complexやunsignedなどの後に来る型名の処理? | |
208 shadow_tag(specs) 名前無しのstructやunionを処理。 | |
209 c_parser_declarator() 名前の前の*の処理 | |
210 c_parser_direct_declarator() idを取得 | |
211 c_parser_direct_declarator_inner() idの後の[]や()をパース | |
212 c_parser_parms_declarator() 引数リストもしくはidリスト(これはoldSTYLEのため) | |
213 c_parser_parms_list_declarator() | |
214 c_parser_parameter_declaration() | |
215 通常の変数なら | |
216 start_decl() | |
217 start_init() c_parser_initializer() finish_init() | |
218 finish_decl() | |
219 | |
220 関数パラメータ | |
221 start_function() 関数のdeclaration treeを作成する | |
222 treeはcurrent_function_declに保存 | |
223 old-styleパラメータ(while c_parser_declaration_or_fndef(parser, f, f, t, f) | |
224 fnbody = c_parser_compound_statement(parser) 関数本体の定義 | |
225 add_stmt(fnbody) fnbodyを専用のstatement listに追加する gimplifyに使われる? | |
226 finish_function() | |
227 current_function_declからfndeclを取得 | |
228 ...(fndecl) = pop_stmt_list(....(fndecl)) statement listからbodyを取得しfndeclにつなげる | |
229 c_genericize(fndecl) convert LD-tree to LI-tree | |
230 c_gimple_diagnostics_recursively(fndecl) | |
231 cgraph_finalize_function(fndecl,false) ファイルにアセンブラを出力? | |
232 cgraph_assemble_pending_functions() in cgraphunit.c | |
233 | |
234 関数とcode segment | |
235 code segmentはパース中の型はcts_CbC_codeとしてdeclspecsに保持している | |
236 finish_declspecsにおいて、treeを構成する際に型をvoid_type_nodeで格納 | |
237 このvoid_typeになんらかのフラグをつける?それともfunction_typeにつける? | |
238 | |
239 | |
240 | |
241 IDの取得 | |
242 c_parser_declarator() 名前の前の*の処理 | |
243 c_parser_direct_declarator() id or (.id)をパース | |
244 c_parser_direct_declarator_inner() idの後の[]や()をパース fnTreeを生成 | |
245 c_parser_parms_declarator() 型なしidリスト(これはoldSTYLEのため) | |
246 c_parser_parms_list_declarator() 型付き引数リストのパース 可変長かもみる | |
247 c_parser_parameter_declaration() | |
248 build_function_declarator() パースした引数とdelcで関数の宣言をつくる | |
249 c_declarator->u.arg_infoに引数を保持 | |
250 | |
251 | |
252 **expand_* treeをパースしてRTLを出力する | |
253 tree_expand_cfg() | |
254 expand_used_vars() | |
255 expand_function_start(current_function_decl) | |
256 cfunの値を設定して行く | |
257 assign_parms() | |
258 ここでcfun->args_sizeが設定されている | |
259 expand_gimple_basic_block() in for-loop | |
260 expand_expr_stmt() in stmt.c | |
261 expand_expr() in expr.h | |
262 expand_expr_real() expr.c | |
263 expand_expr_real_1() | |
264 | |
265 expand_expr_real_1() expr.c:8210 | |
266 expand_mult() expmed.c | |
267 expand_binop() optabs.c | |
268 GEN_FCN (icode) (temp, xop0, xop1); | |
269 下の感じのRTLが返される | |
270 (set (reg:DF 67) (mult:DF (reg:DF 66) (reg/v:DF 64 [ d ]))) | |
271 が、この関数が返すのは (reg:DF 67)だけ | |
272 emit_insn(rtx) | |
273 RTLをDL-listに追加する. rtxはinsnでなければinsnでラッピングされる | |
274 | |
275 | |
276 **PASS LIST** | |
277 関数ごとに出力する場合、 | |
278 cgraph_assemble_pending_functions() flag_unit_at_a_timeが真なら実行 | |
279 cgraph_expand_function() | |
280 tree_rest_of_compilation | |
281 execute_pass_list | |
282 | |
283 まとめて出力する場合 | |
284 compile_file | |
285 lang_hooks.decls.final_write_globals = c_write_global_declarations flag_unit_at_a_timeが偽なら実行 | |
286 cgraph_optimize | |
287 cgraph_expand_all_functions | |
288 cgraph_expand_function | |
289 | |
290 GIMPLE treeから RTL への変換 | |
291 pass.execute = tree_expand_cfg() | |
292 | |
293 RTLからアセンブラへの変換pass final.cで定義 | |
294 pass_final.execute == rest_of_handle_final in final.c | |
295 | |
296 | |
297 最終的な RTL=>"文字列" 変換する pass | |
298 execute_one_pass() | |
299 rest_of_handle_final() | |
300 assemble_start_function() | |
301 final_start_function() | |
302 final() # insnリストを出力 | |
303 final_scan_insn() # 与えられたinsnのアセンブラを出力 | |
304 recog_memoized() # insn_data[code]のcode 決定 | |
305 get_insn_template() # 出力するアセンブラのchar*文字列を返す | |
306 output_asm_insn() # 文字列の%..を修正してファイルに出力 | |
307 final_end_function() | |
308 assemble_end_function() | |
309 | |
310 RTLの仮想レジスタを物理レジスタに置き換える pass | |
311 execute_one_pass() | |
312 instantiate_virtual_regs() | |
313 instantiate_virtual_regs_in_insn() for each instruction | |
314 extract_insn() | |
315 recog_memoized() | |
316 insn_extract() | |
317 ppcではこのrecog_memoizedで-1しか返ってこないことで落ちる | |
318 | |
319 下のmdのmatch_operand 0がaddressにしか対応してないのが問題だと思う | |
320 ;; sibling call patterns | |
321 (define_expand "sibcall" | |
322 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) | |
323 (match_operand 1 "" "")) | |
324 (use (match_operand 2 "" "")) | |
325 (use (reg:SI LR_REGNO)) | |
326 (return)])] | |
327 "" | |
328 " | |
329 { | |
330 #if TARGET_MACHO | |
331 if (MACHOPIC_INDIRECT) | |
332 operands[0] = machopic_indirect_call_target (operands[0]); | |
333 #endif | |
334 | |
335 gcc_assert (GET_CODE (operands[0]) == MEM); | |
336 gcc_assert (GET_CODE (operands[1]) == CONST_INT); | |
337 | |
338 operands[0] = XEXP (operands[0], 0); | |
339 }") | |
340 | |
341 | |
342 targetm.asm_outから出力 | |
343 ターゲットマシンによってtargetm構造体の内容が変わる。 | |
344 | |
345 | |
346 | |
347 /* In all nodes that are expressions, this is the data type of the expression. | |
348 In POINTER_TYPE nodes, this is the type that the pointer points to. | |
349 In ARRAY_TYPE nodes, this is the type of the elements. | |
350 In VECTOR_TYPE nodes, this is the type of the elements. */ | |
351 #define TREE_TYPE(NODE) ((NODE)->common.type) // in tree.h | |
352 このnodeの型を表す(functionなら関数の型、pointerならそいつのさしている型.. | |
353 | |
354 /* The tree-code says what kind of node it is. | |
355 Codes are defined in tree.def. */ | |
356 #define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code) // in tree.h | |
357 このnodeがどんなtreeなのかを表す | |
358 | |
359 | |
360 | |
361 c_parser_compound_statement() | |
362 c_begin_compound_stmt() | |
363 c_parser_compund_statement_nostart() __label__, lvarの処理 | |
364 c_parser_statement_after_labels() | |
365 c_end_compound_stmt() | |
366 | |
367 c_parser_if_statement() | |
368 c_parser_do_statement() | |
369 | |
370 c_parser_paren_condition() ifやwhileの'()'の中をparseする | |
371 | |
372 | |
373 parse expressions | |
374 | |
375 c_parser_unary_expression() increment,decrement, &, *ポインタ、アドレスの処理 | |
376 c_parser_postfix_expression() 数字や変数、文字列などの処理(TCCのunary()か) | |
377 c_parser_postfix_expression_after_primary() 変数とかの後ろの'[]'や'()'の処理(関数や配列の添字) | |
378 | |
379 | |
380 c_parser_* Cのパーサ | |
381 build_* treeの生成 (Cパーサから呼ばれる) | |
382 expand_* tree(gimple)のパーサ | |
383 emit_* rtlの生成 (treeパーサから呼ばれる) | |
384 | |
385 | |
386 | |
387 | |
388 宣言時の新しい識別子 | |
389 token->type==CPP_NAME | |
390 build_id_declarator | |
391 XOBNEWを使って parser_obstackに作られる => gcc_obstack_init in default.h | |
392 変数名等を格納するc_declaratorはparser_obstack上に作られ、 | |
393 | |
394 | |
395 tree.def | |
396 tree.[ch] | |
397 | |
398 union tree_node GTY((ptr_alias (union lang_tree_node), | |
399 desc ("tree_node_structure (&%h)"))) | |
400 { | |
401 struct tree_common GTY ((tag ("IS_COMMON"))) common; | |
402 struct tree_int_cst GTY ((tag ("IS_INT_CST"))) common; | |
403 struct tree_real_cst GTY ((tag ("IS_REAL_CST"))) common; | |
404 .. | |
405 .. | |
406 }; | |
407 c-tree.h: | |
408 struct c_expr{ | |
409 tree value; | |
410 enum tree_code original_code; | |
411 } | |
412 | |
413 | |
414 tokenizer | |
415 | |
416 c_parser_peek_token() int c-parser.c 現在参照すべきtoken を返す | |
417 c_lex_one_token() in c-parser.c | |
418 c_lex_with_flags() in c-lex.c | |
419 cpp_get_token() in libcpp(macro.c) | |
420 c_parser_next_token_is( parser, token0) tokenを取得し、それがtoken0ならtrue | |
421 c_parser_consume_token( parser) 次のtokenを取ってくる | |
422 | |
423 parser->tokens[0,1] (c_token) | |
424 この[0]に現在のtokenの情報がある。 | |
425 [1]はnext? | |
426 新たなtokenはlibcppのcpp_get_tokenによって取得する。 | |
427 | |
428 cppでは'!'や'*'などの一つ一つのtokenとなんらかの文字列を返す | |
429 予約語等の処理はgccがやる. | |
430 token | |
431 struct c_token{ | |
432 enum cpp_ttype type: 8; /* libcppで得られるtokenのtype, '<','==', name, '['などなど */ | |
433 enum c_id_kind id_kind: 8; /* type==CPP=NAMEの時のみ */ | |
434 enum rid keyword: 8; /* Cの予約語(int, if, typedef, gotoなど) */ | |
435 pragma_kind: 7; | |
436 in_systemheader: 1; | |
437 tree value; | |
438 location_t location; | |
439 } | |
440 enum cpp_ttype in libcpp/include/cpplib.h | |
441 { | |
442 TTYPE_TABLE ==>> CPP_EQ, CPP_NOT, ... , CPP_NAME, ..., CPP_PADDING, | |
443 N_TTYPES, | |
444 | |
445 /* Positions in the table. */ | |
446 CPP_LAST_EQ = CPP_LSHIFT, | |
447 CPP_FIRST_DIGRAPH = CPP_HASH, | |
448 CPP_LAST_PUNCTUATOR= CPP_ATSIGN, | |
449 CPP_LAST_CPP_OP = CPP_LESS_EQ | |
450 }; | |
451 本来予約語もCPP_NAMEに含まれるが、無理矢理CPP_KEYWORDを作っている | |
452 CPP_KEYWORDはc-parser.cで独自に定義、N_TTYPES+1 | |
453 typedef enum c_id_kind { | |
454 C_ID_ID, /* An ordinary identifier. */ | |
455 C_ID_TYPENAME, /* An identifier declared as a typedef name. */ | |
456 C_ID_CLASSNAME, /* An identifier declared as an Objective-C class name. */ | |
457 C_ID_NONE /* Not an identifier. */ | |
458 } c_id_kind; | |
459 | |
460 | |
461 enum c_declarator_kind { /* in c-tree.h */ | |
462 cdk_id, /* An identifier. */ | |
463 cdk_function, /* A function. */ | |
464 cdk_array, /* An array. */ | |
465 cdk_pointer, /* A pointer. */ | |
466 cdk_attrs /* Parenthesized declarator with nested attributes. */ | |
467 }; | |
468 struct c_declarator { /* in c-tree.h */ | |
469 enum c_declarator_kind kind; /* The kind of declarator. */ | |
470 struct c_declarator *declarator; /* Except for cdk_id, the contained declarator. For cdk_id, NULL. */ | |
471 location_t id_loc; /* Currently only set for cdk_id. */ | |
472 union { | |
473 tree id; /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract declarator. */ | |
474 struct c_arg_info *arg_info; /* For functions. */ | |
475 struct { /* For arrays. */ | |
476 tree dimen; /* The array dimension, or NULL for [] and [*]. */ | |
477 int quals; /* The qualifiers inside []. */ | |
478 tree attrs; /* The attributes (currently ignored) inside []. */ | |
479 BOOL_BITFIELD static_p : 1; /* Whether [static] was used. */ | |
480 BOOL_BITFIELD vla_unspec_p : 1; /* Whether [*] was used. */ | |
481 } array; | |
482 int pointer_quals; /* For pointers, the qualifiers on the pointer type. */ | |
483 tree attrs; /* For attributes. */ | |
484 } u; | |
485 }; | |
486 | |
487 /* A type specifier keyword "void", "_Bool", "char", "int", "float", | |
488 "double", or none of these. */ | |
489 enum c_typespec_keyword { //でも使われてるのはdeclspec | |
490 cts_none, | |
491 cts_void, | |
492 cts_CbC_code, いる? | |
493 cts_bool, | |
494 cts_char, | |
495 cts_int, | |
496 cts_float, | |
497 cts_double, | |
498 cts_dfloat32, | |
499 cts_dfloat64, | |
500 cts_dfloat128 | |
501 }; | |
502 enum c_typespec_kind { | |
503 ctsk_resword, | |
504 ctsk_tagref, | |
505 ctsk_tagfirstref, | |
506 /* A definition of a tag such as "struct foo { int a; }". */ | |
507 ctsk_tagdef, | |
508 ctsk_typedef, | |
509 ctsk_objc, | |
510 ctsk_typeof | |
511 }; | |
512 struct c_typespec { | |
513 enum c_typespec_kind kind; | |
514 tree spec; | |
515 }; | |
516 struct c_declspecs { /* c-tree.c */ | |
517 /* The type specified, if a single type specifier such as a struct, | |
518 union or enum specifier, typedef name or typeof specifies the | |
519 whole type, or NULL_TREE if none or a keyword such as "void" or | |
520 "char" is used. Does not include qualifiers. */ | |
521 tree type; | |
522 /* The attributes from a typedef decl. */ | |
523 tree decl_attr; | |
524 /* When parsing, the attributes. Outside the parser, this will be | |
525 NULL; attributes (possibly from multiple lists) will be passed | |
526 separately. */ | |
527 tree attrs; | |
528 /* Any type specifier keyword used such as "int", not reflecting | |
529 modifiers such as "short", or cts_none if none. */ | |
530 enum c_typespec_keyword typespec_word; | |
531 /* The storage class specifier, or csc_none if none. */ | |
532 enum c_storage_class storage_class; | |
533 BOOL_BITFIELD declspecs_seen_p : 1; | |
534 BOOL_BITFIELD type_seen_p : 1; | |
535 BOOL_BITFIELD typedef_p : 1; | |
536 BOOL_BITFIELD default_int_p; | |
537 BOOL_BITFIELD long_p : 1; | |
538 BOOL_BITFIELD long_long_p : 1; | |
539 BOOL_BITFIELD short_p : 1; | |
540 BOOL_BITFIELD signed_p : 1; | |
541 : | |
542 } | |
543 | |
544 | |
545 | |
546 | |
547 **TAIL CALL OPTIMIZATION** | |
548 execute_tail_calls in tree-tailcall.c | |
549 tree_optimize_tail_calls_1(true) | |
550 たいした調査もせず、簡単にフラグCALL_EXPR_TAILCALLをたててるだけ。 | |
551 | |
552 expand_call 1834-3115 in calls.c | |
553 initialize_argument_information(); | |
554 引数処理 | |
555 引数をレジスタやスタックのどこに保存するかを決める | |
556 tree actparmsで示された引数をargs, args_sizeに格納する | |
557 1011行目 We can't use sibcalls if a callee-copied argument is stored in the current function's frame. | |
558 if statement 2200行目: try_tail_call=0 | |
559 targetm.function_ok?for?sibcall(fndecl, exp) | |
560 args_size.constant > (current_function_args_size - current_function_pretend_args_size) | |
561 emit_call_1(); | |
562 SIBLING_CALL_P(..) = ( (ecf_flag & ECF_SIBLING) != 0); | |
563 | |
564 expand_callでtailcall可能かどうかの判定を詳しく行っているようだ | |
565 bool try_tail_call = CALL_EXPR_TAILCALL(exp); | |
566 2252あたりのfor文が怪しいが、900行ある。 | |
567 | |
568 2252 in calls.c | |
569 for(pass = try_tail_call ? 0:1; pass<2; pass++) 2253-3087 | |
570 2回ループ。 | |
571 1回目はtailcall用。 | |
572 2回目は普通のcalling | |
573 生成後にどちらかを選ぶ? | |
574 2227 args_size.constant > (current_function_args_size - current_function_pretend_args_size) | |
575 | |
576 hard_function_value | |
577 check_sibcall_argument_overlap | |
578 prepare_call_address | |
579 load_register_parameters | |
580 | |
581 | |
582 | |
583 Language Dependent Tree | |
584 v | |
585 GENERIC | |
586 v | |
587 GIMPLE | |
588 | |
589 GENERIC trees + LD trees | |
590 v | |
591 GIMPLE | |
592 | |
593 | |
594 **RTL** | |
595 RTL expression | |
596 クラス: RTX_OBJ, RTX_CONST_OBJ, _COMPARE _COMM_COMPARE _UNARY ... in rtx.def | |
597 オペランド: e(expression), i(integer), w, s, E, ... | |
598 | |
599 RTLへのアクセス | |
600 GET_CODE (RTX) (enum rtx_code) (RTX)->code | |
601 RTXのコード(種類)を返す | |
602 GET_RTX_CLASS (code) | |
603 このrtxコードのクラスを返す | |
604 GET_RTX_LENGTH (code) | |
605 このrtxコードのオペランドの数を返す | |
606 GET_RTX_FORMAT (code) | |
607 オペランドの種類を文字列で返す | |
608 i.e. "iuuBieieee" on CALL_INSN | |
609 XEXP(RTX, N) X->u.fld[N].rt_rtx | |
610 RTX のN番目のオペランドをexpressionとして取得する | |
611 XINT(RTX, N) X->u.fld[N].rt_int | |
612 RTX のN番目のオペランドをintegerとして取得する | |
613 XVEC(RTX, N) X->u.fld[N].rt_rtvec | |
614 RTX のN番目のオペランドをrtvectorとして取得する | |
615 XVECEXP(RTX, N, M) XVEC(RTX,N)->elem[M] | |
616 RTX のN番目のオペランドをrtvectorとし、その M番目の要素を返す | |
617 XVECLEN(RTX, N) XVEC(RTX,N)->num_elem | |
618 RTX のN番目のオペランドをrtvectorとし、そのサイズを返す | |
619 | |
620 struct rtvec_def GTY(()) { | |
621 int num_elem; /* number of elements */ | |
622 rtx GTY ((length ("%h.num_elem"))) elem[1]; | |
623 }; | |
624 | |
625 | |
626 typedef struct trx_def *rtx; //gcc/coretypes.h | |
627 struct rtx_def; //gcc/rtl.h | |
628 struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), | |
629 chain_prev ("RTX_PREV (&%h)"))) | |
630 { | |
631 /* The kind of expression this is. */ | |
632 ENUM_BITFIELD(rtx_code) code: 16; | |
633 | |
634 /* The kind of value the expression has. */ | |
635 ENUM_BITFIELD(machine_mode) mode : 8; | |
636 | |
637 /* 1 in a MEM if we should keep the alias set for this mem unchanged | |
638 when we access a component. | |
639 1 in a CALL_INSN if it is a sibling call. | |
640 1 in a SET that is for a return. | |
641 In a CODE_LABEL, part of the two-bit alternate entry field. */ | |
642 unsigned int jump : 1; | |
643 /* In a CODE_LABEL, part of the two-bit alternate entry field. | |
644 1 in a MEM if it cannot trap. */ | |
645 unsigned int call : 1; | |
646 /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere. | |
647 1 in a SUBREG if it references an unsigned object whose mode has been | |
648 from a promoted to a wider mode. | |
649 1 in a SYMBOL_REF if it addresses something in the per-function | |
650 constants pool. | |
651 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call. | |
652 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */ | |
653 unsigned int unchanging : 1; | |
654 /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile. | |
655 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE | |
656 if it has been deleted. | |
657 1 in a REG expression if corresponds to a variable declared by the user, | |
658 0 for an internally generated temporary. | |
659 1 in a SUBREG with a negative value. | |
660 1 in a LABEL_REF or in a REG_LABEL note for a non-local label. | |
661 In a SYMBOL_REF, this flag is used for machine-specific purposes. */ | |
662 unsigned int volatil : 1; | |
663 /* 1 in a MEM referring to a field of an aggregate. | |
664 0 if the MEM was a variable or the result of a * operator in C; | |
665 1 if it was the result of a . or -> operator (on a struct) in C. | |
666 1 in a REG if the register is used only in exit code a loop. | |
667 1 in a SUBREG expression if was generated from a variable with a | |
668 promoted mode. | |
669 1 in a CODE_LABEL if the label is used for nonlocal gotos | |
670 and must not be deleted even if its count is zero. | |
671 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled | |
672 together with the preceding insn. Valid only within sched. | |
673 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and | |
674 from the target of a branch. Valid from reorg until end of compilation; | |
675 cleared before used. */ | |
676 unsigned int in_struct : 1; | |
677 /* At the end of RTL generation, 1 if this rtx is used. This is used for | |
678 copying shared structure. See `unshare_all_rtl'. | |
679 In a REG, this is not needed for that purpose, and used instead | |
680 in `leaf_renumber_regs_insn'. | |
681 1 in a SYMBOL_REF, means that emit_library_call | |
682 has used it as the function. */ | |
683 unsigned int used : 1; | |
684 /* 1 in an INSN or a SET if this rtx is related to the call frame, | |
685 either changing how we compute the frame address or saving and | |
686 restoring registers in the prologue and epilogue. | |
687 1 in a REG or MEM if it is a pointer. | |
688 1 in a SYMBOL_REF if it addresses something in the per-function | |
689 constant string pool. */ | |
690 unsigned frame_related : 1; | |
691 /* 1 in a REG or PARALLEL that is the current function's return value. | |
692 1 in a MEM if it refers to a scalar. | |
693 1 in a SYMBOL_REF for a weak symbol. */ | |
694 unsigned return_val : 1; | |
695 | |
696 /* The first element of the operands of this rtx. | |
697 The number of operands and their types are controlled | |
698 by the `code' field, according to rtl.def. */ | |
699 union u { | |
700 rtunion fld[1]; | |
701 HOST_WIDE_INT hwint[1]; | |
702 struct block_symbol block_sym; | |
703 struct real_value rv; | |
704 } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; | |
705 }; | |
706 | |
707 | |
708 FUNCTION_TYPEの実態はtree_type | |
709 make_node_stat(FUNCTION_TYPE)で作成される | |
710 TREE_TYPE | |
711 TYPE_ARG_TYPES ->type.values | |
712 TYPE_UID ->type.uid | |
713 TYPE_ALIGN ->type.align | |
714 TYPE_USER_ALIGN ->type.user_align | |
715 TYPE_MAIN_VARIANT ->type.main_variant | |
716 TYPE_ATTRIBUTES ->type.attributes | |
717 | |
718 こいつの lang_flag_6 ビットフィールドをcode segmentかどうかのフラグとする。 | |
719 #define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type.lang_flag_5) //tree.h | |
720 #define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 (TYPE) //c-tree.h | |
721 code segmentを作ったらCbC_IS_CODE_SEGMENT(type) = 1 でセット できる? | |
722 | |
723 | |
724 | |
725 | |
726 | |
727 | |
728 **GENERIC TREE** | |
729 関数の型 | |
730 <function_type 0xb7b7d9b4 | |
731 type <real_type 0xb7b72a6c double DF | |
732 size <integer_cst 0xb7b60528 constant invariant 64> | |
733 unit size <integer_cst 0xb7b60540 constant invariant 8> | |
734 align 64 symtab 0 alias set -1 precision 64 | |
735 pointer_to_this <pointer_type 0xb7b72b80>> | |
736 QI | |
737 size <integer_cst 0xb7b601f8 type <integer_type 0xb7b7205c bit_size_type> constant invariant 8> | |
738 unit size <integer_cst 0xb7b60210 type <integer_type 0xb7b72000 unsigned int> constant invariant 1> | |
739 align 8 symtab 0 alias set -1 | |
740 arg-types <tree_list 0xb7b7c8a0 | |
741 | |
742 関数の宣言 | |
743 <function_decl | |
744 type <function_type ... >> | |
745 | |
746 関数の引数 | |
747 <tree_list | |
748 value <integer_type | |
749 size <integer_cst ...> | |
750 unit size <integer_cst ...> | |
751 align 32 .... <integer_cst ...> | |
752 chain <tree_list ...>> | |
753 | |
754 配列 | |
755 <array_type 0xb7f04170 | |
756 type <integer_type 0xb7e7f284 int public SI ... > | |
757 BLK | |
758 size <integer_cst 0xb7f02f18 type <integer_type 0xb7e7f05c bit_size_type> constant invariant 320> | |
759 unit size <integer_cst 0xb7f05030 type <integer_type 0xb7e7f000 unsigned int> constant invariant 40> | |
760 align 32 symtab 0 alias set -1 | |
761 domain <integer_type 0xb7f04114 | |
762 type <integer_type 0xb7e7f000 unsigned int public unsigned sizetype SI size <integer_cst 0xb7e6d3f0 32> unit size <integer_cst 0xb7e6d180 4> | |
763 align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7e6d468 0> max <integer_cst 0xb7e6d9f0 -1>> | |
764 SI size <integer_cst 0xb7e6d3f0 32> unit size <integer_cst 0xb7e6d180 4> | |
765 align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7e6d198 0> max <integer_cst 0xb7f02fc0 9>>> | |
766 | |
767 関数呼び出し | |
768 <call_expr 0xb7e52078 | |
769 type <real_type 0xb7e55a6c double DF ...> | |
770 side-effects arg 0 <addr_expr 0xb7ed2080 | |
771 type <pointer_type 0xb7eda170 type <function_type 0xb7ecff18> | |
772 unsigned SI | |
773 size <integer_cst 0xb7e433f0 constant invariant 32> | |
774 unit size <integer_cst 0xb7e43180 constant invariant 4> | |
775 align 32 symtab 0 alias set -1> | |
776 constant invariant | |
777 arg 0 <function_decl 0xb7ed15b0 test type <function_type 0xb7ecff18> | |
778 addressable used public external decl_5 QI defer-output file test_tree.c line 2>> | |
779 arg 1 <tree_list 0xb7edb138 | |
780 value <integer_cst 0xb7edb030 constant invariant 97> | |
781 chain <tree_list 0xb7edb168 | |
782 value <integer_cst 0xb7edb060 constant invariant 98> | |
783 chain <tree_list 0xb7edb180 | |
784 value <integer_cst 0xb7edb090 constant invariant 10> | |
785 chain <tree_list 0xb7edb198 | |
786 value <real_cst 0xb7edb0c0 type <real_type 0xb7e55a6c double> | |
787 constant invariant 2.5e+0>>>>>> | |
788 | |
789 | |
790 build_function_call(tree fndecl, tree exprlist) | |
791 FUNCTION_DECLとEXPRのリストからCALL_EXPRを作って返す | |
792 | |
793 convert_arguments(arglist, params, function, fundecl); | |
794 check_function_arguments(); | |
795 | |
796 | |
797 配列の作り方 | |
798 icst : INTEGER_CST | |
799 itype: INTEGER_TYPE | |
800 | |
801 icst = build_int_cst (NULL_TREE, size-1); | |
802 itype = build_index_type (icst); | |
803 array = build_array_type | |
804 | |
805 //build_range_type(size_type, integer_zero_node, exp) | |
806 | |
807 | |
808 | |
809 **PPC** | |
810 http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/ASMIntroduction/chapter_1_section_1.html | |
811 http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-SW17 | |
812 http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html | |
813 http://www.freescale.co.jp/pdf/MPCFPE32BJ_R1a.pdf | |
814 http://www.nk.rim.or.jp/~jun/ppcasm/ppcasm01.html | |
815 | |
816 | |
817 | |
818 | |
819 | |
820 **ソースコード読み会 準備** | |
821 cd ~/public_html | |
822 mkdir gcc; cd gcc | |
823 checkout CbC_project/GCC; CbC_project/GCC | |
824 ./configure --... | |
825 make | |
826 gtags | |
827 htags -Ffx -t 'GCC source tour' | |
828 cd ../../ | |
829 tar -czv CbC_project --exclude **/CVS -f GCC-source-....tar.gz | |
830 | |
831 | |
832 | |
833 normal tail call | |
834 (call_insn/j 24 23 0 (parallel [ | |
835 (call (mem:SI (symbol_ref:SI ("cs0") [flags 0x403] <function_decl 0x42e03980 cs0>) [0 S4 A8]) | |
836 (const_int 256 [0x100])) | |
837 (use (const_int 0 [0x0])) | |
838 (use (reg:SI 125)) | |
839 (return) | |
840 ]) -1 (nil) | |
841 (expr_list:REG_EH_REGION (const_int 0 [0x0]) | |
842 (nil)) | |
843 (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) | |
844 (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) | |
845 (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) | |
846 (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) | |
847 (nil)))))) | |
848 | |
849 indirect tail call | |
850 (call_insn/j 25 24 0 (parallel [ | |
851 (call (mem:SI (reg/f:SI 129) [0 S4 A8]) | |
852 (const_int 256 [0x100])) | |
853 (use (const_int 0 [0x0])) | |
854 (use (reg:SI 130)) | |
855 (return) | |
856 ]) -1 (nil) | |
857 (nil) | |
858 (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) | |
859 (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) | |
860 (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) | |
861 (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) | |
862 (nil)))))) | |
863 | |
864 | |
865 | |
866 CFLAGS='-O0 -gdwarf-2 -g3' ../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/INSTALL-DIR --enable-checking=tree,rtl,assert --disable-shared --disable-threads --with-headers --with-system-zlib --with-newlib --enable-version-specific-runtime-libs --disable-libssp --target=spu | |
867 | |
868 ../toolchain/gcc/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --disable-shared --disable-threads --disable-checking --with-headers --with-system-zlib --with-newlib --enable-languages=c,c++,fortran --disable-nls --enable-version-specific-runtime-libs --disable-libssp --program-prefix=spu- --target=spu | |
869 | |
870 | |
871 | |
872 | |
873 $ cvs checkout CbC_project/GCC | |
874 $ mkdir tmp; cd tmp | |
875 $ wget http://www.bsc.es/projects/deepcomputing/linuxoncell/cellsimulator/sdk3.0/SRPMS/spu-gcc-4.1.1-107.src.rpm | |
876 $ rpm2cpio spu-gcc--4.1.1-107.src.rpm | cpio -i -v | |
877 $ tar xjvf gcc-r886.tar.bz2 | |
878 $ cat *.diff | patch -d ../CbC_project/GCC -p2 | |
879 $ cp toolchain/gcc/config.sub ../CbC_project/GCC/ | |
880 $ cp toolchain/gcc/gcc/config.gcc ../CbC_project/GCC/gcc/ | |
881 $ cd ../CbC_project/GCC | |
882 $ | |
883 | |
884 | |
885 change bit_merge to vec_merge in gcc/config/spu/spu.md | |
886 split0_completed; in recog.c, rtl.h, final.c | |
887 SPU_FLOAT_FORMAT | |
888 : |