コグノスケ


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

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

2020年5月29日

GCCを調べる - その13-1 - オフセット付きアドレスを禁止する

目次: GCC

メモリからのロード、ストアに問題があるので、おそらくメモリ周りのconstraint指定が間違っていて、本来受け付けてはいけないオペランドまで受け付けていると思われますが、証拠を掴む方法が全くわかりません。

今回追加したdefine_expand, define_insnのうちdefine_expandはconstraintなし、define_insnはmという標準のconstraintを使っています。手がかりになりそうなconstraint mから追ってみます。メモリのconstraintは下記に定義があります。

constraint "m" の定義

// gcc/defaults.h

#ifndef TARGET_MEM_CONSTRAINT
#define TARGET_MEM_CONSTRAINT 'm'
#endif


// gcc/common.md

(define_memory_constraint "TARGET_MEM_CONSTRAINT"
  "Matches any valid memory."
  (and (match_code "mem")
       (match_test "/* hogehoge */ memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
						 MEM_ADDR_SPACE (op))")))  //★★ここに適当なコメントを入れる

メモリのconstraintは若干イレギュラーな定義で、アーキテクチャにより "m" 以外の文字になります(s390のみ "e" を使います)。RISC-VではTARGET_MEM_CONSTRAINTは "m" ですから、特に気にしなくて良いです。

定義の最後にあるmatch_testに続くコードに適当にコメントを入れて、ビルドしてからコメントの文字列でgrepすると、build_gcc/tm-constrs.hのsatisfies_constraint_m() という関数にコピペされていることがわかります。このルールはconstraint "m" だけでなく他も同じです。関数satisfies_constraint_(文字) が自動的に生成され、条件チェックされます。

この関数でブレークしたいですがstatic inlineになっておりブレークが掛からないので、適当にfor_break_tmp() 関数を一つ追加しておき、この関数で止めます。

constraint "m" の判定関数

// build_gcc/tm-constrs.h

static void for_break_tmp(rtx op)  //★★関数を足す
{
}

static inline bool
satisfies_constraint_m (rtx op)  //★★この関数にブレークは設定できないので…
{
  for_break_temp(op);  //★★関数呼び出しを足す

  return (GET_CODE (op) == MEM) && (
#line 26 "./gcc/gcc/common.md"
( /* hogehoge */ memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
						 MEM_ADDR_SPACE (op))));  //★★さっきいれた適当なコメントも一緒にコピーされる
}

無条件だと何度も止まって鬱陶しいので、machine modeで条件ブレークすると良いでしょう。

constraint "m" の判定関数でブレーク
(gdb) b for_break_tmp if op->mode == E_V64SImode

(gdb) r

Breakpoint 1, for_break_tmp (op=0x7ffff7bacab0) at tm-constrs.h:9
9       }

(gdb) bt

#0  for_break_tmp (op=0x7ffff7bacab0)
    at tm-constrs.h:9
#1  0x000000000217dfa8 in satisfies_constraint_m (op=0x7ffff7bacab0)
    at tm-constrs.h:13
#2  0x0000000000ebcc07 in constraint_satisfied_p (x=0x7ffff7bacab0, c=CONSTRAINT_m)
    at ./tm-preds.h:108
#3  0x0000000000ebe8cf in satisfies_memory_constraint_p (op=0x7ffff7bacab0,
    constraint=CONSTRAINT_m)
    at ./gcc/gcc/lra-constraints.c:421
#4  0x0000000000ec7149 in process_alt_operands (only_alternative=-1)
    at ./gcc/gcc/lra-constraints.c:2338
#5  0x0000000000eceb52 in curr_insn_transform (check_only_p=false)
    at ./gcc/gcc/lra-constraints.c:3977
#6  0x0000000000ed4e71 in lra_constraints (first_p=true)
    at ./gcc/gcc/lra-constraints.c:5027
#7  0x0000000000eacae4 in lra (f=0x454f640)
    at ./gcc/gcc/lra.c:2437
#8  0x0000000000e1a557 in do_reload ()
    at ./gcc/gcc/ira.c:5523
#9  0x0000000000e1af95 in (anonymous namespace)::pass_reload::execute (this=0x449fdf0)
    at ./gcc/gcc/ira.c:5709

パスは282r.reloadです。いくつかスタックフレームを遡るとprocess_alt_operands() 関数にたどり着きます。ベクトルレジスタの追加(2020年3月29日の日記参照)のときに見ました、懐かしいですね。それはさておき下記のコードから呼ばれています。

constraint "m" を判定する箇所

static bool
process_alt_operands (int only_alternative)
{

...

	  costly_p = false;
	  do
	    {
	      switch ((c = *p, len = CONSTRAINT_LEN (c, p)), c)
		{

...

		default:
		  cn = lookup_constraint (p);
		  switch (get_constraint_type (cn))
		    {
		    case CT_REGISTER:
		      cl = reg_class_for_constraint (cn);  //★★前回はこちらに来ていた
		      if (cl != NO_REGS)
			goto reg;
		      break;

		    case CT_CONST_INT:
		      if (CONST_INT_P (op)
			  && insn_const_int_ok_for_constraint (INTVAL (op), cn))
			win = true;
		      break;

		    case CT_MEMORY:
		      if (MEM_P (op)
			  && satisfies_memory_constraint_p (op, cn))  //★★今回はこちらに来る
			win = true;
		      else if (spilled_pseudo_p (op))
			win = true;

		      /* If we didn't already win, we can reload constants
			 via force_const_mem or put the pseudo value into
			 memory, or make other memory by reloading the
			 address like for 'o'.  */
		      if (CONST_POOL_OK_P (mode, op)
			  || MEM_P (op) || REG_P (op)
			  /* We can restore the equiv insn by a
			     reload.  */
			  || equiv_substition_p[nop])
			badop = false;
		      constmemok = true;
		      offmemok = true;
		      break;


// opが指すRTLはこんな感じ

(mem/c:V64SI (plus:SI (reg/f:SI 108)
        (const_int 256 [0x100])) [1 v1+0 S256 A2048])

渡されたRTLに対し、satisfies_memory_constraint_p() はconstraint "m" の条件と合致するか調べ、合致していたらwinフラグをtrueにしています。

この辺りを変えれば、オフセット付きアドレスに変化が起きそうです。続きはまた今度。

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

コメント一覧

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



link もっと前
2020年5月29日 >>> 2020年5月29日
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の...」

最近の記事3件

  • 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 もっとみる

こんてんつ

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