gcc

不思議発見

友人から電話がかかってきた。大声で話すものだから、2階に追いやられた。太陽眩しい温室状態。ふと、自分の頭の影が窓の影に近づくと、頭にコブが出来たように大きくなる事に気づいた。不思議だ。

窓ガラスが悪さをしてるかと思って、窓を開けてみたけど同じだ。電話の相手に理由知ってるって聞いてみたが、そんなの知らないと言う。通話後に、頭の上に雑誌をかざして、距離を詰める実験をした。今度は、本の直線部分が曲がって、オイラーの頭にその影が近づいてきた。 これで本の内容を頭に転送完了、なんてならないかな。

冗談はともかく、ぐぐる先生に聞いてみた。

影が伸びる原理は?

影法師のコブ

影が伸びる理由・影と影がくっつく理由はなぜ?

python docstring

perl,rubyと関数類のヘルプを見てきたので、pythonのそれも見て億事にする。ソースにちりばめられているヘルプ情報はdocstringと言うそうな。

>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).

こちらは、手堅く見る方法。

>>> help(str.split)
Help on method_descriptor:

split(self, /, sep=None, maxsplit=-1)
    Return a list of the words in the string, using sep as the delimiter string.

    sep
      The delimiter according which to split the string.
      None (the default value) means split according to any whitespace,
      and discard empty strings from the result.
    maxsplit
      Maximum number of splits to do.
      -1 (the default value) means no limit.

もっと大掛かりなやつとして、 Sphinxの使い方.docstringを読み込んで仕様書を生成 なんてのがある。

sakae@deb:/tmp$ pip3 install --user sphinx

なんてやると、~/.local/ にインストールされる。この中のbinにパスを通して使う。

sphinxの実習

Pythonのtar玉を展開すると、Docの下に原稿が置いてある。折角なんでWebでアクセス出来るようにしてみる。

sakae@deb:/tmp/Python-3.10.0/Doc$ make html
mkdir -p build
Using existing Misc/NEWS file
PATH=./venv/bin:$PATH sphinx-build -b html -d build/doctrees   -W . build/html
Running Sphinx v4.3.0
making output directory... done

Theme error:
no theme named 'python_docs_theme' found (missing theme.conf?)
make: *** [Makefile:51: build] Error 2
sakae@deb:/tmp/Python-3.10.0/Doc$ pip3 install --user python_docs_theme

装飾大事って事でテーマが要求された。で、輸入しておく。

sakae@deb:/tmp/Python-3.10.0/Doc$ make html
mkdir -p build
Using existing Misc/NEWS file
PATH=./venv/bin:$PATH sphinx-build -b html -d build/doctrees   -W . build/html
Running Sphinx v4.3.0
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 488 source files that are out of date
updating environment: [new config] 488 added, 0 changed, 0 removed
reading sources... [  0%] about
reading sources... [  0%] bugs
reading sources... [  0%] c-api/abstract
  :
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [  0%] about
writing output... [  0%] bugs
writing output... [  0%] c-api/abstract
  :
dumping object inventory... done
build succeeded.

The HTML pages are in build/html.
Writing glossary.json

Build finished. The HTML pages are in build/html.

こんな具合で、無事に作成された。後は、firefox build/html/index.html すれば良い。

huffman

ニュートン誌でアルゴリズムの連載をやってて、そこに圧縮の方法ってのが出ていた。面白そうなので、ちょっと追跡する。

ハフマン符号

Huffman Encoding in Haskell

慣れ親しんだC言語でもってんで、下記を参照

C言語でハフマン符号化

『C言語による最新アルゴリズム事典』

そしたら、 Ruby でアルゴリズム なんてのも紹介されてた。 http://www.nct9.ne.jp/m_hiroi/light/ruby06.html

ハフマン符号のアルゴリズム (by scheme)

UTF-8ってそもそもどういう仕組み? これを見ると、ハフマンぽいなあ。

sakae@pen:/tmp/t$ ./a.out e huffman.c z
In : 4821 bytes
Out: 3380 bytes (table: 199 bytes)
Out/In: 0.701
sakae@pen:/tmp/t$ ./a.out e man-gcc z
In : 1107492 bytes
Out: 649938 bytes (table: 121 bytes)
Out/In: 0.587
sakae@pen:/tmp/t$ ./a.out e algo.tar.gz z
In : 125851 bytes
Out: 126109 bytes (table: 319 bytes)
Out/In: 1.002

奥村先生のハフマン圧縮を試してみた。普通?の英文代表として、gccのマニュアルを選んでもみた。これが一番圧縮率が高い。テーブルサイズが小さいって事は、文字種が少ないんだな。 既に圧縮してあるファイルは手の施し様が無くて、サイズが逆に増えているのは、お約束だ。

sakae@pen:/tmp/t$ ./a.out e /usr/share/dict/words z
In : 976241 bytes
Out: 544796 bytes (table: 88 bytes)
Out/In: 0.558

一般人が使うであろう、単語帳の圧縮。これぐらいが限界なのかな。

gcc

インタプリタ・コンパイラと「構文木」(gcc RTL) こんな楽しい記事を見ていたんだ。おいらーも調べてみたいぞ。

だが man gcc しても出てこない。そこで、下記をインストールした。普通の人には不要だろうと言う隔った考えなんだな。

gcc-10-doc/stable,now 10.2.0-1 all [installed,automatic]
gcc-doc-base/stable,now 10.1.0-1 all [installed,automatic]
gcc-doc/stable,now 5:10.1.0-1 i386 [installed]

但し、amd版用にしてるftp.riken.jpには無くて、i386用に使ってる ftp.jaist.ac.jpに置いてあった。新人には用が無いって事か。これも歪んだ考えだな。gccint なんて言う内部解説書もinfoで供給されてるぞ。

gcc-doc (3 Invoking GCC -> 3.18 GCC Developer Options)

'-fdump-tree-all
'-fdump-rtl-all'  or  '-da'

treeの方は前段、rtlの方は後段の詳細を出力する。前段はC言語レベルのソースを変形。後段は、RTLと言うLISPに似たソースを扱かう。

#include <stdio.h>
#define N 10

int main(){
  int sum = 0;
  for(int i=0; i <= N; i++) sum += i;
  printf("%d\n", sum);
  return (sum % 10);
}

こんな、何の変哲も無いコードを試してみる。

sakae@deb:/tmp/t$ cc -O3 -fdump-tree-all sml.c
sakae@deb:/tmp/t$ ls | less
a.out*
sml.c
sml.c.004t.original
sml.c.005t.gimple
sml.c.007t.omplower
 :
sml.c.235t.optimized
sml.c.322t.statistics
sml.c.323t.earlydebug
sml.c.324t.debug

全部で129個の中間コードが出力された。


;; Function main (main, funcdef_no=11, decl_uid=1961, cgraph_uid=12, symbol_order=11) (executed once)

main ()
{
  <bb 2> [local count: 89442696]:
  printf ("%d\n", 55);
  return 5;

}

ループが計算されて、結果だけ出力。mainからの返値も計算済になってる。でも、かろうじてC言語の体裁は保っている。

sakae@deb:/tmp/t$ cc -fdump-rtl-all sml.c
sakae@deb:/tmp/t$ ls
a.out*                      sml.c.278r.dfinit            sml.c.309r.alignments
sml.c                       sml.c.279r.mode_sw           sml.c.311r.mach
sml.c.237r.expand           sml.c.280r.asmcons           sml.c.312r.barriers
sml.c.238r.vregs            sml.c.285r.ira               sml.c.317r.shorten
sml.c.239r.into_cfglayout   sml.c.286r.reload            sml.c.318r.nothrow
sml.c.240r.jump             sml.c.293r.pro_and_epilogue  sml.c.319r.dwarf2
sml.c.252r.reginfo          sml.c.296r.jump2             sml.c.320r.final
sml.c.275r.outof_cfglayout  sml.c.307r.split4            sml.c.321r.dfinish
sml.c.276r.split1           sml.c.308r.stack

-O3 を付けると、もっと沢山のファイルが作成される。鬼のように無駄を省くんだな。

;; Function main (main, funcdef_no=0, decl_uid=1925, cgraph_uid=1, symbol_order=0)
  :
;;
;; Full RTL generated for this function:
;;
(note 1 0 3 NOTE_INSN_DELETED)
(note 3 1 49 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn/f 49 3 2 2 (set (reg:SI 95)
        (reg:SI 2 cx)) -1
     (expr_list:REG_CFA_SET_VDRAP (reg:SI 95)
        (nil)))
(note 2 49 5 2 NOTE_INSN_FUNCTION_BEG)
(insn 5 2 6 2 (set (mem/c:SI (plus:SI (reg/f:SI 77 virtual-stack-vars)
                (const_int -4 [0xfffffffffffffffc])) [1 sum+0 S4 A32])
        (const_int 0 [0])) "sml.c":5:7 -1
     (nil))
    :

RMSの大好きな形になった。これを変形して行って、最後はアセンブラー出力出来る形まで進めるのだな。

sakae@deb:/tmp/t$ cc -O3 -S sml.c
sakae@deb:/tmp/t$ less sml.s
        :
        pushl   $55
        leal    .LC0@GOTOFF(%ebx), %eax
        pushl   %eax
        call    printf@PLT
        addl    $16, %esp
        :

どうもインテルの石は好きになれんな。

see GNU Compiler Collection (GCC) Internals

対抗馬はこちらです。

Clang で学ぶコンパイラ

万人受けするのかな。深入りは禁物か。軽く流すだけで良い。


This year's Index

Home