コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2020年5月23日 >>> 2020年5月23日
link もっと後

2020年5月23日

GCCを調べる - その11-2 - オプションO0のエラーを引き起こすRTL(define_expand追加編)

目次: GCC

前回(2020年5月22日の日記参照)の続きです。エラーの原因となる代入操作RTLはどこから出てきているのでしょう。RTLを遡っていくとexpandから出力されていることがわかります。expandはRTLの最初のパスで、GIMPLEからRTLに変換するためのパス(パス番号236)です。最初から間違っているということですね。

236r.expand
;;★★asm文に相当する箇所

(insn 74 7 10 2 (set (reg:V64SI 109 [ v1 ])
        (asm_operands/v:V64SI ("vlw.v %0, %1
") ("=&v") 0 [
                (mem/c:SI (plus:SI (reg/f:SI 99 virtual-stack-vars)
                        (const_int -360 [0xfffffffffffffe98])) [1 b+40 S4 A64])
            ]
             [
                (asm_input:SI ("A") b.c:7)
            ]
             [] b.c:7)) "b.c":7:2 -1
     (nil))

;;★★自動的に出力される代入操作らしきRTL

(insn 10 74 11 2 (set (mem/c:SI (reg/f:SI 108) [1 v1+0 S4 A2048])
        (subreg:SI (reg:V64SI 109 [ v1 ]) 0)) "b.c":7:2 -1
     (nil))
(insn 11 10 12 2 (set (mem/c:SI (plus:SI (reg/f:SI 108)
                (const_int 4 [0x4])) [1 v1+4 S4 A32])
        (subreg:SI (reg:V64SI 109 [ v1 ]) 4)) "b.c":7:2 -1
     (nil))
(insn 12 11 13 2 (set (mem/c:SI (plus:SI (reg/f:SI 108)
                (const_int 8 [0x8])) [1 v1+8 S4 A64])
        (subreg:SI (reg:V64SI 109 [ v1 ]) 8)) "b.c":7:2 -1
     (nil))

...

ベクトル型V64SIのまま処理してほしいのに、4バイトごとに分割されて代入処理されています。この分割はどこで行われているか調べます。GCCはinsn RTLを出力するときは必ずemit_insn() という関数で出力することを利用します。

  • 代入操作の先頭のinsnはUID 10です。ダンプファイルで確認するならinsnの隣にある数字(insn '10' ←これ74 11 2 …)がUIDです。
  • emit_insn() を書き換えて、INSN_UID(x) == 10のときに適当に作った関数hoge() に飛ばすようにします。
  • gdbで関数hoge() にブレークを掛けると、ちょうど目当てのRTLを出力した瞬間に実行が止まります。

ブレークで実行が止まったら、バックトレースを取れば呼び出しまでの経路がわかります。

代入操作の先頭insnを出力したときのバックトレース
(gdb) bt
#0  hoge () at ./gcc/gcc/emit-rtl.c:5103
#1  0x000000000097ebf9 in emit_insn (x=0x7ffff7aaa400)
    at ./gcc/gcc/emit-rtl.c:5118
#2  0x00000000009ff017 in emit_move_insn_1 (x=0x7ffff7bada80, y=0x7ffff7bada98)
    at ./gcc/gcc/expr.c:3754
#3  0x00000000009ffa28 in emit_move_insn (x=0x7ffff7bada80, y=0x7ffff7bada98)
    at ./gcc/gcc/expr.c:3858

★★↓いかにも分割していそうな、怪しい名前

#4  0x00000000009fee38 in emit_move_multi_word (mode=E_V64SImode, x=0x7ffff7bada68, y=0x7ffff7bada50)
    at ./gcc/gcc/expr.c:3720
#5  0x00000000009ff505 in emit_move_insn_1 (x=0x7ffff7bada68, y=0x7ffff7bada50)
    at ./gcc/gcc/expr.c:3791
#6  0x00000000009ffa28 in emit_move_insn (x=0x7ffff7bada68, y=0x7ffff7bada50)
    at ./gcc/gcc/expr.c:3858
#7  0x0000000000a0cc8d in store_expr (exp=0x7ffff7ffb480, target=0x7ffff7bada68, call_param_p=0,
    nontemporal=false, reverse=false)
    at ./gcc/gcc/expr.c:5932
#8  0x0000000000a09064 in expand_assignment (to=0x7ffff7aa7750, from=0x7ffff7ffb480, nontemporal=false)
    at ./gcc/gcc/expr.c:5517
#9  0x000000000076c911 in expand_asm_stmt (stmt=0x7ffff7b8f4e0)
    at ./gcc/gcc/cfgexpand.c:3198
#10 0x000000000076f89a in expand_gimple_stmt_1 (stmt=0x7ffff7b8f4e0)
    at ./gcc/gcc/cfgexpand.c:3685
#11 0x00000000007705f0 in expand_gimple_stmt (stmt=0x7ffff7b8f4e0)
    at ./gcc/gcc/cfgexpand.c:3853
#12 0x000000000077e7f1 in expand_gimple_basic_block (bb=0x7ffff7aba2d8, disable_tail_calls=false)
    at ./gcc/gcc/cfgexpand.c:5893
#13 0x0000000000781a25 in (anonymous namespace)::pass_expand::execute (this=0x449bbf0, fun=0x7ffff7baa000)

バックトレースの中に怪しい名前の関数emit_move_multi_word() があります。いかにも複数のinsnを出力しそうな名前です。emit_move_multi_wordまでを追うと、下記のような経路を辿っています。

代入が分割されるところ

// gcc/cfgexpand.c

static void
expand_asm_stmt (gasm *stmt)
{

...

  for (i = 0; i < noutputs; ++i)
    {
      tree val = output_tvec[i];
      tree type = TREE_TYPE (val);
      bool is_inout, allows_reg, allows_mem, ok;
      rtx op;

...

      if ((TREE_CODE (val) == INDIRECT_REF && allows_mem)
	  || (DECL_P (val)
	      && (allows_mem || REG_P (DECL_RTL (val)))
	      && ! (REG_P (DECL_RTL (val))
		    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
	  || ! allows_reg
	  || is_inout
	  || TREE_ADDRESSABLE (type))
	{

...

	}
      else
	{
	  op = assign_temp (type, 0, 1);
	  op = validize_mem (op);
	  if (!MEM_P (op) && TREE_CODE (val) == SSA_NAME)
	    set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (val), op);

	  generating_concat_p = old_generating_concat_p;

	  push_to_sequence2 (after_rtl_seq, after_rtl_end);
	  expand_assignment (val, make_tree (type, op), false);  //★★これ
	  after_rtl_seq = get_insns ();
	  after_rtl_end = get_last_insn ();
	  end_sequence ();
	}


// gcc/expr.c

/* Expand an assignment that stores the value of FROM into TO.  If NONTEMPORAL
   is true, try generating a nontemporal store.  */

void
expand_assignment (tree to, tree from, bool nontemporal)
{

...

  /* Compute FROM and store the value in the rtx we got.  */

  push_temp_slots ();
  result = store_expr (from, to_rtx, 0, nontemporal, false);  //★★これ
  preserve_temp_slots (result);
  pop_temp_slots ();
  return;
}

rtx_insn *
emit_move_insn (rtx x, rtx y)
{
  machine_mode mode = GET_MODE (x);
  rtx y_cst = NULL_RTX;
  rtx_insn *last_insn;
  rtx set;

...

  last_insn = emit_move_insn_1 (x, y);  //★★これ

  if (y_cst && REG_P (x)
      && (set = single_set (last_insn)) != NULL_RTX
      && SET_DEST (set) == x
      && ! rtx_equal_p (y_cst, SET_SRC (set)))
    set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));

  return last_insn;
}

rtx_insn *
emit_move_insn_1 (rtx x, rtx y)
{
  machine_mode mode = GET_MODE (x);
  enum insn_code code;

  gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);

  code = optab_handler (mov_optab, mode);
  if (code != CODE_FOR_nothing)    //★★CODE_FOR_nothingになるのが怪しい
    return emit_insn (GEN_FCN (code) (x, y));    //★★こっちに行けばいいのだろうか??

  /* Expand complex moves by moving real part and imag part.  */
  if (COMPLEX_MODE_P (mode))
    return emit_move_complex (mode, x, y);    //★★もしくはこっち??

...

  return emit_move_multi_word (mode, x, y);    //★★この関数が呼ばれ、分割される
}

せっかく辿っておいてこんなこというのは若干気が引けますが、なぜこの経路を辿るのか?コードを見ても全くわかりません。特にexpand_asm_stmt() からemit_move_insn() までは、各関数が非常に長く、訳のわからないif文が山ほどあります。GCCってどうして動いてるんでしょうね?大丈夫?これ??

GCCのコードの酷さはさておき、emit_move_multi_word() と他の関数への分岐点になっている、emit_move_insn_1() が怪しそうです。次回以降、この関数を中心に調べます。

編集者:すずき(2023/09/24 11:49)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2020年5月23日 >>> 2020年5月23日
link もっと後

管理用メニュー

link 記事を新規作成

<2020>
<<<05>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント5件

  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」
  • link 21年3月13日
    すずきさん (03/05 15:13)
    「あー、このプログラムがまずいんですね。ご...」
  • link 21年3月13日
    emkさん (03/05 12:44)
    「キャストでvolatileを外してアクセ...」
  • link 24年1月24日
    すずきさん (02/19 18:37)
    「簡単にできる方法はPowerShellの...」

最近の記事20件

  • link 24年4月17日
    すずき (04/18 22:44)
    「[VSCodeとMarkdownとPlantUMLのローカルサーバー] 目次: LinuxVSCodeのPlantUML Ex...」
  • link 23年4月10日
    すずき (04/18 22:30)
    「[Linux - まとめリンク] 目次: Linuxカーネル、ドライバ関連。Linuxのstruct pageって何?Linu...」
  • link 20年2月22日
    すずき (04/17 02:22)
    「[Zephyr - まとめリンク] 目次: Zephyr導入、ブート周りHello! Zephyr OS!!Hello! Ze...」
  • link 24年4月16日
    すずき (04/17 02:05)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その2 - インストール時のバイナリ書き換え] 目次: Zep...」
  • link 24年4月15日
    すずき (04/17 01:47)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その1 - 移動させると動かなくなる] 目次: ZephyrZ...」
  • link 24年4月11日
    すずき (04/17 00:37)
    「[VScodeとAsciiDocとKrokiローカルサーバー] 目次: LinuxAsciiDoc ExtensionはAsc...」
  • link 24年4月12日
    すずき (04/16 00:12)
    「[台湾東部沖地震に寄付] ささやかではありますが台湾東部沖地震に寄付しました。日本の赤十字社→台湾の赤十字(正式名称...」
  • link 22年9月3日
    すずき (04/16 00:08)
    「[MarkDownのその向こう] 目次: Linux簡単なドキュメントやメモはMarkDownで書くことが多いですが、気合を入...」
  • link 22年9月4日
    すずき (04/16 00:08)
    「[Asciidocをさらに活用] 目次: Linux前回(2022年9月3日の日記参照)、Asciidocのプレビュー環境の設...」
  • link 24年3月19日
    すずき (04/16 00:07)
    「[モジュラージャックの規格] 目次: Arduino古くは電話線で、今だとEthernetで良く見かけるモジュラージャックとい...」
  • link 23年6月2日
    すずき (04/16 00:07)
    「[Arduino - まとめリンク] 目次: Arduino一覧が欲しくなったので作りました。 M5Stackとesp32とA...」
  • link 24年4月9日
    すずき (04/12 12:44)
    「[初めて作ったボード動作せず(手で直した)] 目次: Arduino以前(2024年3月24日の日記参照)発注して、全く動ない...」
  • link 24年4月2日
    すずき (04/12 11:00)
    「[KiCadが動かなくなったのでビルド] 目次: ArduinoDebian Testingなマシンをapt-get upgr...」
  • link 24年4月3日
    すずき (04/12 11:00)
    「[初めて作ったボード動作せず(燃えた)] 目次: Arduino以前(2024年3月24日の日記参照)発注したPCBが届いたの...」
  • link 24年3月24日
    すずき (04/12 11:00)
    「[PCBを設計して注文] 目次: Arduinoシューティングの練習でいつもお世話になっているTARGET-1秋葉原店に、6つ...」
  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
  • link 24年3月18日
    すずき (03/19 11:47)
    「[画面のブランクを無効にする] 目次: LinuxROCK 3 model CのDebian bullseyeイメージは10分...」
  • link 24年3月3日
    すずき (03/19 11:07)
    「[解像度の設定を保存する] 目次: LinuxRaspberry Pi 3 Model B (以降RasPi 3B)のHDMI...」
  • link 24年3月14日
    すずき (03/16 23:03)
    「[JavaとM5Stamp C3とBluetooth LE - Bluetoothデバイスとの通信] 目次: ArduinoM...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/18 22:44