前回の記事で、-O3付きでコンパイルできないという問題が残っていたのだが、それを何とか回避できないか試行してみた。
そもそも-O3とはどのようなオプションなのだろうか?調査してみると、-O2に対して以下の最適化オプションを追加したものが-O3らしい。
Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-loop-vectorize, -ftree-loop-distribute-patterns, -fsplit-paths -ftree-slp-vectorize, -fvect-cost-model, -ftree-partial-pre, -fpeel-loops and -fipa-cp-clone options.
なので、-O3は-O2に対して上記のオプションを追加すれば等価になるということか。じゃあ一つずつ追加していって、エラーが出るものは省けは、だいたい-O3になるんじゃないか。なんて卑怯な手動だ(笑)。
結果として、以下のようにオプションを変更すると、ほぼ-O3と同一のオプションで、コンパイルは成功することが分かった。
-PORT_CFLAGS = -O2 -g $(MACHINE_TARGET) -DITERATIONS=$(ITERATIONS) +PORT_CFLAGS = -O2 -g $(MACHINE_TARGET) -DITERATIONS=$(ITERATIONS) -funroll-loops \ + -finline-functions \ + -funswitch-loops \ + -fpredictive-commoning \ + -fgcse-after-reload \ + -ftree-loop-vectorize \ + -fsplit-paths \ + -ftree-slp-vectorize \ + -fvect-cost-model \ + -ftree-partial-pre \ + -fpeel-loops \ + -fipa-cp-clone +
つまり、-ftree-loop-distribute-patterns
を除去したということになる。これは、
Perform loop distribution of patterns that can be code generated with calls to a library. This flag is enabled by default at -O3. This pass distributes the initialization loops and generates a call to memset zero. For example, the loop DO I = 1, N A(I) = 0 B(I) = A(I) + I ENDDO is transformed to DO I = 1, N A(I) = 0 ENDDO DO I = 1, N B(I) = A(I) + I ENDDO and the initialization loop is transformed into a call to memset zero.
はーん。これでmemsetが呼ばれるということか。とりあえずこれを除去してみた。
2016/12/01 追記。最適化オプション-O2+Plusのサイクル数追加。
命令数 | Rate | サイクル数 | Rate | |
---|---|---|---|---|
最適化オプション追加前 | 308822 | 100% | 433730 | 100% |
最適化オプション-O2 | 264024 | 85.5% | 396837 | 91.5% |
最適化オプション-O2+Plus | 290386 | 94.0% | 398513 | 91.8% |
あれま、実行命令数は増えてしまったな。実行命令数は増えても、サイクル数としてはほぼ変わっていない不思議。IPC経過を観察しても、コンパイルオプションを変更しただけで良い傾向になっている。
そろそろ本当にFPGAに載せる準備をしなければならない。それが出来たらReturnStackPointerなどの実装かな。