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