GCCとLLVMの内部の比較

Takahiro Shimizu

このセッションの内容

このセッションの目的

アジェンダ

GCCとLLVM

コンパイルの流れ

字句解析

(4 + 3 ) * 2
// ==> [(] [4][+][3][)][*][2]

構文解析

 [(] [4][+][3][)][*][2]
	
    *
  +   2
4   3 

中間コード生成

最適化

今回のトレース箇所

デバッグの準備

CbC_gcc/configure CFLAGS="-g3 -O0" --prefix=$PWD \
    --disable-nls --disable-bootstrap --enable-languages=c \
    --enable-checking=tree,rtl,assert,types
cmake -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:PATH=`pwd` ~/hg/CbC/LLVM_original

デバッグ方法(gcc)

$cat test.sh
lldb -- gcc/cc1 test.c

デバッグ方法(clang)

$ bin/clang -v  test.c
clang version 7.0.0
Target: x86_64-apple-darwin17.6.0
Thread model: posix
InstalledDir: /Users/anatofuz/workspace/cr/build_llvm/bin
 "/Users/anatofuz/workspace/cr/build_llvm/bin/clang-7.0" -cc1 -triple x86_64-apple-macosx10.13.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -main-file-name test.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -target-linker-version 351.8 -v -resource-dir /Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0 -fdebug-compilation-dir /Users/anatofuz/workspace/cr/build_llvm -ferror-limit 19 -fmessage-length 120 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime=macosx-10.13.0 -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/jk/3jyh2t9j0lj11j4wks3r8bj40000gn/T/test-2169da.o -x c test.c
clang -cc1 version 7.0.0 based upon LLVM 7.0.0svn default target x86_64-apple-darwin17.6.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
 "/usr/bin/ld" -demangle -lto_library /Users/anatofuz/workspace/cr/build_llvm/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 10.13.0 -o a.out /var/folders/jk/3jyh2t9j0lj11j4wks3r8bj40000gn/T/test-2169da.o -lSystem /Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0/lib/darwin/libclang_rt.osx.a

デバッグ方法(clang)

lldb – bin/clang -cc1 -triple x86_64-apple-macosx10.13.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -main-file-name test.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -target-linker-version 351.8 -v -resource-dir /Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0 -fdebug-compilation-dir /Users/anatofuz/workspace/cr/build_llvm -ferror-limit 19 -fmessage-length 120 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime=macosx-10.13.0 -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -x c test.c

gccのparser

$ sh test.sh
(lldb) target create "gcc/cc1"
Current executable set to 'gcc/cc1' (x86_64).
(lldb) settings set -- target.run-args  "test.c"
(lldb) b c_parser_expression
Breakpoint 1: where = cc1`c_parser_expression(c_parser*) + 23 [inlined] c_parser_peek_token(c_parser*) at c-parser.c:9230, address = 0x0000000100070967
(lldb) run
Process 12348 launched: '/Users/anatofuz/workspace/cr/build_gcc/gcc/cc1' (x86_64)
 maincc1 was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 12348 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100070967 cc1`c_parser_expression(c_parser*) [inlined] c_parser_peek_token(parser=0x0000000143d45000) at c-parser.c:439 [opt]
   436 	c_token *
   437 	c_parser_peek_token (c_parser *parser)
   438 	{
-> 439 	  if (parser->tokens_avail == 0)
   440 	    {
   441 	      c_lex_one_token (parser, &parser->tokens[0]);
   442 	      parser->tokens_avail = 1;
Target 0: (cc1) stopped.

gccのparser

(lldb) n
Process 12348 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100070997 cc1`c_parser_expression(parser=0x0000000143d45000) at c-parser.c:9233 [opt]
   9230	  location_t tloc = c_parser_peek_token (parser)->location;
   9231	  struct c_expr expr;
   9232	  expr = c_parser_expr_no_commas (parser, NULL);
-> 9233	  if (c_parser_next_token_is (parser, CPP_COMMA))
   9234	    expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
   9235	  while (c_parser_next_token_is (parser, CPP_COMMA))
   9236	    {
Target 0: (cc1) stopped.
(lldb) p expr
(c_expr) $1 = {
  value = 0x0000000143c14040
  original_code = ERROR_MARK
  original_type = 0x0000000000000000
  src_range = (m_start = 16672, m_finish = 17440)
}
(lldb) p debug_tree(expr.value)
 <call_expr 0x143c14040
    type <integer_type 0x143c195e8 int public SI
        size <integer_cst 0x143c01f30 constant 32>
        unit-size <integer_cst 0x143c01f48 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x143c195e8 precision:32 min <integer_cst 0x143c01ee8 -2147483648> max <integer_cst 0x143c01f00 2147483647>
        pointer_to_this <pointer_type 0x143c21a80>>
    side-effects
    fn <addr_expr 0x143d34660
        type <pointer_type 0x143d243f0 type <function_type 0x143c99a80>
            unsigned DI
            size <integer_cst 0x143c01cf0 constant 64>
            unit-size <integer_cst 0x143c01d08 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x143d24498>
        constant
        arg:0 <function_decl 0x143ca2500 printf type <function_type 0x143c99a80>
            addressable used public external built-in decl_3 decl_5 QI defer-output test.c:1:12
            align:8 warn_if_not_align:0 built-in: BUILT_IN_NORMAL:BUILT_IN_PRINTF>
        test.c:5:5 start: test.c:5:5 finish: test.c:5:10>
    arg:0 <nop_expr 0x143d34680
        type <pointer_type 0x143c26348 type <integer_type 0x143c262a0 char>
            unsigned DI size <integer_cst 0x143c01cf0 64> unit-size <integer_cst 0x143c01d08 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x143c26348>
        readonly constant
        arg:0 <addr_expr 0x143d34620 type <pointer_type 0x143d24f18>
            readonly constant
            arg:0 <string_cst 0x143d34600 type <array_type 0x143d24e70>
                readonly constant static "Hello %d\012\000">
            test.c:5:12 start: test.c:5:12 finish: test.c:5:23>
        test.c:5:12 start: test.c:5:12 finish: test.c:5:23>
    arg:1 <plus_expr 0x143d25348 type <integer_type 0x143c195e8 int>

        arg:0 <var_decl 0x142352f30 a type <integer_type 0x143c195e8 int>
            used read SI test.c:4:9 size <integer_cst 0x143c01f30 32> unit-size <integer_cst 0x143c01f48 4>
            align:32 warn_if_not_align:0 context <function_decl 0x143d26500 main> initial <integer_cst 0x143c1e3f0 4>>
        arg:1 <parm_decl 0x143d45100 ac type <integer_type 0x143c195e8 int>
            used read SI test.c:3:14 size <integer_cst 0x143c01f30 32> unit-size <integer_cst 0x143c01f48 4>
            align:32 warn_if_not_align:0 context <function_decl 0x143d26500 main> arg-type <integer_type 0x143c195e8 int> chain <parm_decl 0x143d45180 av>>
        test.c:5:26 start: test.c:5:25 finish: test.c:5:28>
    test.c:5:5 start: test.c:5:5 finish: test.c:5:29>

llvmのparser

$sh lldb.sh            
(lldb) target create "bin/clang"
Current executable set to 'bin/clang' (x86_64).
(lldb) settings set -- target.run-args  "-cc1" "-triple" "x86_64-apple-macosx10.13.0" "-Wdeprecated-objc-isa-usage" "-Werror=deprecated-objc-isa-usage" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "test.c" "-mrelocation-model" "pic" "-pic-level" "2" "-mthread-model" "posix" "-mdisable-fp-elim" "-masm-verbose" "-munwind-tables" "-target-cpu" "penryn" "-dwarf-column-info" "-debugger-tuning=lldb" "-target-linker-version" "351.8" "-v" "-resource-dir" "/Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0" "-fdebug-compilation-dir" "/Users/anatofuz/workspace/cr/build_llvm" "-ferror-limit" "19" "-fmessage-length" "120" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fobjc-runtime=macosx-10.13.0" "-fmax-type-align=16" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-x" "c" "test.c"
(lldb) b ParseExpression
Breakpoint 1: 2 locations.
(lldb) run
Process 12147 launched: '/Users/anatofuz/workspace/cr/build_llvm/bin/clang' (x86_64)
clang -cc1 version 7.0.0 based upon LLVM 7.0.0svn default target x86_64-apple-darwin17.6.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Users/anatofuz/workspace/cr/build_llvm/lib/clang/7.0.0/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
Process 12147 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
    frame #0: 0x0000000105a9df53 clang`clang::Parser::ParseExpression(this=0x0000000114053400, isTypeCast=MaybeTypeCast) at ParseExpr.cpp:126
   123 	///         expression ',' assignment-expression ...[opt]
   124 	/// \endverbatim
   125 	ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
-> 126 	  ExprResult LHS(ParseAssignmentExpression(isTypeCast));
   127 	  return ParseRHSOfBinaryExpression(LHS, prec::Comma);
   128 	}
   129
Target 0: (clang) stopped.

llvmのパース

(lldb) step
Process 12147 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x0000000105a9dfa8 clang`clang::Parser::ParseAssignmentExpression(this=0x0000000114053400, isTypeCast=MaybeTypeCast) at ParseExpr.cpp:163
   160
   161 	/// \brief Parse an expr that doesn't include (top-level) commas.
   162 	ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
-> 163 	  if (Tok.is(tok::code_completion)) {
   164 	    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
   165 	    cutOffParsing();
   166 	    return ExprError();
Target 0: (clang) stopped.
(lldb) p Tok
(clang::Token) $0 = (Loc = 2151358386, UintData = 1, PtrData = 0x0000000116020184, Kind = numeric_constant, Flags = 0)

pass

gccのpass実行プロセス

llvmのpass実行プロセス

インライン展開の最適化 (gcc)

インライン展開の最適化(llvm)

gccのコード生成

llvmのコード生成