コグノスケ


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

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

2020年5月16日

GCCを調べる - その10-1 - ベクトル型を使うとエラー(TARGET_VECTOR_MODE_SUPPORTED_P追加編)

目次: GCC

以前(2020年3月27日の日記2020年3月28日の日記2020年3月29日の日記参照)ベクトルレジスタを扱えるようにした際に、下記の問題が残っていました。

  • 変数がintなのでsizeof(v) が4になる、ベクトルを扱いたい
  • 最適化オプションをO0にするとコンパイラがinternal errorを出す

前回(2020年5月12日の日記参照)はベクトル型に向けてマシンモードを追加しました。引き続き、1つ目の問題に取り組んでいきたいと思います。

ベクトル型は基本型(SI, DI, SF, DFなど)が複数連結されているデータ型です。個数は2のべき乗(2, 4, 8, 16, ...)でなければなりません、3個や10個はダメです。型は通常GCCの実装で定義します。ベクトル型も当然同じでGCCの実装で定義しますが、ベクトル型はやや特殊で、GCCのattributeでも定義することができます。今回はattributeを使ってみます。

ベクトル型を使ったコード

typedef int __v64si __attribute__((__vector_size__(256)));

void _start()
{
	int b[100];
	__v64si v1;

	__asm__ volatile ("vlw.v %0, %1\n"
		: "=&v"(v1) : "A"(b[10]));
}

ベクトル型を使ってインラインアセンブラを書くとエラーが出ます。

ベクトル型を使うとimpossible constraintエラー
$ riscv32-unknown-elf-gcc -Wall -march=rv32gcv b.c -O2 -nostdlib -S

b.c: In function '_start':
b.c:7:2: error: impossible constraint in 'asm'
    7 |  __asm__ volatile ("vlw.v %0, %1\n"
      |  ^~~~~~~

このエラーは以前(2020年3月6日の日記参照)、register constraintに 'v' を追加したときに解析した部分で見ました。詳細は昔の日記を見ていただくとして、以前との差を示します。

エラーになる箇所

// gcc/recog.c

int
asm_operand_ok (rtx op, const char *constraint, const char **constraints)
{

...

	default:
	  cn = lookup_constraint (constraint);
	  switch (get_constraint_type (cn))
	    {
	    case CT_REGISTER:
	      if (!result
		  && reg_class_for_constraint (cn) != NO_REGS  //★★以前引っかかっていたのはこちら
		  && GET_MODE (op) != BLKmode        //★★今回はこちらの条件に引っかかる
		  && register_operand (op, VOIDmode))
		result = 1;
	      break;

新たなマシンモードV64SImodeを追加(2020年5月12日の日記参照)を追加したのに、どうしてBLKmodeが選択されてしまうのでしょう?

オプション --dump-tree-all --dump-rtl-allを付けて、BLKmodeが選ばれるタイミングを追うと、パスexpandが終わった時点でBLKmodeになっていました。

236r.expandの抜粋

(insn 26 7 10 2 (set (mem/c:BLK (plus:SI (reg/f:SI 99 virtual-stack-vars)  ★★mem/c:BLKになっている
                (const_int -1168 [0xfffffffffffffb70])) [1  A128])
        (asm_operands/v:BLK ("vlw.v %0, %1") ("=&v") 0 [
                (mem/c:SI (plus:SI (reg/f:SI 99 virtual-stack-vars)
                        (const_int -872 [0xfffffffffffffc98])) [1 b+40 S4 A64])
            ]
             [
                (asm_input:SI ("A") b.c:7)
            ]
             [] b.c:7)) "b.c":7:2 -1
     (nil))

パスexpandはGIMPLEからRTLという中間表現に変換するパスです。RTLに変換した直後からBLKmodeですから、かなり最初の方からダメだってことがわかります。何が悪いかわからないのでexpand辺りのコードを探ってみます。

BLKmodeになる箇所

// 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/function.c

rtx
assign_temp (tree type_or_decl, int memory_required,
	     int dont_promote ATTRIBUTE_UNUSED)
{
  tree type, decl;
  machine_mode mode;
#ifdef PROMOTE_MODE
  int unsignedp;
#endif

  if (DECL_P (type_or_decl))
    decl = type_or_decl, type = TREE_TYPE (decl);
  else
    decl = NULL, type = type_or_decl;

  mode = TYPE_MODE (type);  //★★これ


// gcc/tree.h

#define TYPE_MODE(NODE) \
  (VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
   ? vector_type_mode (NODE) : (NODE)->type_common.mode)    //★★これ


// gcc/tree.c

/* Vector types need to re-check the target flags each time we report
   the machine mode.  We need to do this because attribute target can
   change the result of vector_mode_supported_p and have_regs_of_mode
   on a per-function basis.  Thus the TYPE_MODE of a VECTOR_TYPE can
   change on a per-function basis.  */
/* ??? Possibly a better solution is to run through all the types
   referenced by a function and re-compute the TYPE_MODE once, rather
   than make the TYPE_MODE macro call a function.  */

machine_mode
vector_type_mode (const_tree t)
{
  machine_mode mode;

  gcc_assert (TREE_CODE (t) == VECTOR_TYPE);

  mode = t->type_common.mode;  //★★このモードはV64SImodeになる
  if (VECTOR_MODE_P (mode)
      && (!targetm.vector_mode_supported_p (mode)  //★★この判定文が偽になる
	  || !have_regs_of_mode[mode]))
    {
      scalar_int_mode innermode;

      /* For integers, try mapping it to a same-sized scalar mode.  */
      if (is_int_mode (TREE_TYPE (t)->type_common.mode, &innermode))  //★★256バイトのIntはないから、偽になる
	{
	  poly_int64 size = (TYPE_VECTOR_SUBPARTS (t)
			     * GET_MODE_BITSIZE (innermode));
	  scalar_int_mode mode;
	  if (int_mode_for_size (size, 0).exists (&mode)
	      && have_regs_of_mode[mode])
	    return mode;
	}

      return BLKmode;  //★★BLKmodeになってしまう
    }

  return mode;
}

条件式にあるtargetm.vector_mode_supported_p() がfalseのため、BLKmodeになってしまうようです。

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

コメント一覧

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



link もっと前
2020年5月16日 >>> 2020年5月16日
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