問題タブ [llvm-clang]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
llvm - レジスタをスタックに保存しないようにclangに指示するにはどうすればよいですか?
目標
私は現在avr-llvm(ターゲットとしてAVRをサポートするllvm)を試しています。私の主な目標は、(gccのものと比較して)より優れたオプティマイザーを使用して、より小さなバイナリーを実現することです。AVRについて少し知っている場合は、メモリが少ないことを知っています。
私は現在、ATTiny45、4KBフラッシュ、および256バイト(KBではなくバイトだけです!)のSRAMを使用しています。
問題
単純なCプログラム(以下を参照)をコンパイルして、生成されるアセンブリコードと、マシンコードのサイズがどのように変化しているかを確認しようとしていました。「clang-Oz-Stest.c」を使用して、アセンブリ出力を生成し、最小サイズに最適化しました。私の問題は、このメソッドが決して返されないことを知っている、不必要に保存されたレジスタ値です。
私の質問...
必要に応じて、コンテンツを保存/復元せずに、任意のレジスタを壊すことができることをllvmに伝えるにはどうすればよいですか?それをさらに最適化する方法(スタックのより効率的なセットアップなど)はありますか?
詳細/例
これが私のテストプログラムです。上記のように、「clang-Oz-Stest.c」を使用してコンパイルされました。
ご覧のとおり、uint8_t型の「揮発性」変数が1つだけあります(揮発性に設定しないと、すべてが最適化されます)。この変数は1に設定されています。最後に無限ループがあります。次に、アセンブリの出力を見てみましょう。
うん!これは、このような単純なプログラムの多くのマシンコードです。私はちょうどいくつかのバリエーションをテストし、AVRのリファレンスマニュアルを調べました...それで私は何が起こるかを説明することができます。それぞれの部分を見てみましょう。
これが「牛肉」です。これは、cプログラムの目的を実行しているだけです。Y + 1(スタックポインタ+1)でメモリに格納されている値「1」でr24をロードします。そしてもちろん、私たちの無限のループがあります:
注:エンドレスループが必要であることに注意してください。それ以外の場合__attribute__ ((noreturn))
は無視され、スタックポインタ+保存されたレジスタは後で復元されます。
その直前に、「Y」のポインタが設定されます。
ここで何が起こるかです:
- Y(レジスタペアr28:r29は「Y」に相当)はポート61および62からロードされ、これらのポートはいくつかの「レジスタ」、つまりSPLおよびSPH(「S」の「L」owおよび「H」ighバイト)にマップされます。タック「P」ointer)
- ロードされた値がデクリメントされます(sbiw r29:r28)
- スタックポインタの変更された値は、ポートに保存されます。そして私は問題を避けるために推測します:割り込みは以前に無効にされています。「cli/sti」[レジスタ63(SREG)に格納されている]の状態はr0に保存され、後でポート63に復元されます。
このスタックレジスタの設定は非効率的なようです。スタックポインタをインクリメントするには、スタックに「r0」をプッシュする必要があります。次に、SPH / SPLの値をr29:r28にロードするだけです。ただし、これには、ソースコードのllvmのオプティマイザにいくつかの変更が必要になる可能性があります。上記のコードは、3バイトを超えるスタックをローカル変数用に予約する必要がある場合にのみ意味があります(-O3を最適化する場合でも、-Ozの場合は最大6バイトで意味があります)。ただし、そのためにはllvmのソースに触れる必要があると思います。したがって、これは範囲外です。
さらに興味深いのは、この部分です。
main()は戻ることを意図していないため、これは意味がありません。これは、ばかげた命令のためにRAMとフラッシュメモリを浪費するだけです(一部のデバイスで使用できるSRAMは64、128、または256バイトしかないことに注意してください)。
これをもう少し詳しく調べました。メインリターン(無限ループがないなど)をスタックポインタに戻すと、最後に「ret」命令があり、レジスタr28とr29が「popr29、pop」を介してスタックから復元されます。 28"。ただし、コンパイラは、関数 "main"のスコープが決して残されていない場合、スタックに格納せずにすべてのレジスタを壊してしまう可能性があることを知っておく必要があります。
2バイトのRAMについて話すと、この問題は少し「ばかげている」ように見えます。しかし、プログラムが残りのレジスタの使用を開始した場合にどうなるかを考えてみてください。
これらすべてが、現在の「コンパイラ」に対する私の見方を本当に変えました。今日は、アセンブラーによる最適化の余地はあまりないと思いました。しかし、あるようです...
それで、それでも問題は...
この状況を改善する方法を知っていますか(バグレポート/機能リクエストの提出を除く)?
つまり、見落としている可能性のあるコンパイラスイッチがいくつかあるだけですか...?
追加情報
使用__attribute__ ((OS_main))
はavr-gccで動作します。
出力は次のとおりです。
これは(私の意見では)サイズ(6命令または12バイト)で最適であり、このサンプルプログラムの速度でも最適です。llvmに相当する属性はありますか?(clangバージョン '3.2(trunk 160228)(LLVM 3.2svnに基づく)'はOS_taskについても、OS_mainについても何も知りません)。
ios - iOSでNEON積和演算を使用する
私がコンパイルしているのarmv7
は、NEONの積和演算の組み込み関数が、別々の積和と加算に分解されているように見えます。
これは、最新の4.5までのXcodeのいくつかのバージョン、iOS SDK 5〜6、およびXcodeとコマンドラインの両方を介して直接構築するさまざまな最適化設定で経験しました。
たとえば、いくつかtest.cpp
を含むものを構築および分解します
と
結果は
の予想される使用の代わりにvmla.f32
。
何が間違っているのですか?
c - -fcatch-undefined-behaviorは、サイズより1要素以上大きいローカル配列アクセスのみをキャッチします
clangのcatch-undefined-behaviorフラグについて質問があります。Cで書かれた大きなプロジェクトで試してみました。ある時点で、ユーザーから提供された整数値(i)が到着します。次に、次のコードを追加しました。
しかし、gdbを使用してコードを実行すると、変数iの値が4以上の場合にのみ停止します。したがって、値3をiに渡すと、停止せずに範囲外の配列にアクセスします。
これは-fcatch-undefined-behaviorの既知の制限ですか?または、アクセスがスタックフレームの外側にあるかどうかだけをチェックし、ローカルアレイの外側にはないかどうかをチェックしますか?
よろしくクリスチャン
PS:コンパイラ/リンカーとしてclang +llvm3.0を使用しています。ターゲットはx86です。プログラムは、WindowsXPボックスのxubuntu12.04仮想マシン内で実行されます。
llvm - llvmのCloneFunctionのvmap引数に何を渡すのですか?
別の関数の正確なコピーを複製しようとしています。インターネットでCloneFunctionの使用例を見つけることができませんでした。
c++ - Clangが機能していません。未定義のシンボルエラー。コードはgccで正常にコンパイルされます
Clangについて良いことを聞いたので、Clangを試してみることにしました。そして、C++11の機能のいくつかを試してみたかったのです。それで、いつものように、私は単純なhelloworldプログラムから始めました。
GCCを使用して正常にコンパイルされたものは、Clangではコンパイルされません。代わりに、このエラーが発生します。
linux - LLVMとclangをビルドしようとする際の問題
自分のマシン(Ubuntu 12.04)でLLVMとclangをビルドしようとしています。手順6(LLVMとclangのビルド)まで、 http://clang.llvm.org/get_started.htmlの指示に従いました。私が作るとき、私は潜在的に互換性のないプラグインバージョンについての警告の全体の負荷を受け取ります(dragoneggと関係がありますか?)。しかし、これらのメッセージではすべてが失敗します。
ですから、あなたが私に与えることができるどんな助けも本当に役に立ちます。
ありがとう
cygwin - cygwin で llvm と clang をビルドする方法
cygwinのソース コードからLLVMと clangをビルドできますか?
LLVM と Clang をビルドするのにどのくらいかかりますか? VirtualBoxでビルドしようとしているので、2時間くらいかかります。
makefile - clangでc99からc89へのコンバーターをコンパイルするには?
私は VisualStudio の Windows で ffmpeg をコンパイルしようとしていますが、ステップの 1 つは、この投稿に従って clang を使用して c99-to-c89コードをコンパイルすることです。なんとかclang.exeを作成できましたが、それを使用してc99からc89へのコードをコンパイルするにはどうすればよいですか?
c99-to-c89 の makefile を少し変更したので、CC
変数は cl.exe ではなく、clang.exe コンパイラを指すようになりました。
しかし、make
コマンドを実行すると、 clang: error: unsupported use of internal gcc -Z option '-Z7'
. CFLAGS
andに問題があるとLDFLAGS
思いますが、makefileとclangの知識が不足しているため、修正方法がわかりません。
clang - プラグマclang診断による-Werrorの無効化
すべての警告をエラーとして扱うために使用-Werror
して、非推奨の宣言警告を抑制したくありません:
どうやってするの ?