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 :