目次: GCC
メモリからのロード、ストアに問題があるので、おそらくメモリ周りのconstraint指定が間違っていて、本来受け付けてはいけないオペランドまで受け付けていると思われますが、証拠を掴む方法が全くわかりません。
今回追加したdefine_expand, define_insnのうちdefine_expandはconstraintなし、define_insnはmという標準のconstraintを使っています。手がかりになりそうなconstraint mから追ってみます。メモリのconstraintは下記に定義があります。
// 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() 関数を一つ追加しておき、この関数で止めます。
// 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で条件ブレークすると良いでしょう。
(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日の日記参照)のときに見ました、懐かしいですね。それはさておき下記のコードから呼ばれています。
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にしています。
この辺りを変えれば、オフセット付きアドレスに変化が起きそうです。続きはまた今度。
< | 2020 | > | ||||
<< | < | 05 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | - | - | - | - | - | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)