要增加一种新的后端,支持buildin的向量指令已经有不少文章提及,这里不再赘述。我们这里主要探讨如何修改后端的.c和.h文件,使得gcc的-ftree-vectorize能够完成相应的自动向量化分析。
在已经支持buildin向量指令的基础上,至少已经完成了向量类型的扩展、向量寄存器的定义等工作,下面重点是需要将后端处理器支持的向量模式以及向量运算传递给前端的树优化分析。
1. 支持的向量模式及向量大小主要通过对应的.c文件中的以下两个宏定义:
TARGET_VECTORIZE_PREFERRED_SIMD_MODE
TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
如gcc 9.2.3的mips.c中,以上两个宏定义如下:
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE mips_preferred_simd_mode
#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
mips_autovectorize_vector_sizes
此时,进一步查看这两个宏定义的函数内容如下:
/* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
static machine_mode
mips_preferred_simd_mode (scalar_mode mode)
{
if (TARGET_PAIRED_SINGLE_FLOAT
&& mode == SFmode)
return V2SFmode;
if (!ISA_HAS_MSA)
return word_mode;
switch (mode)
{
case E_QImode:
return V16QImode;
case E_HImode:
return V8HImode;
case E_SImode:
return V4SImode;
case E_DImode:
return V2DImode;
case E_SFmode:
return V4SFmode;
case E_DFmode:
return V2DFmode;
default:
break;
}
return word_mode;
}
/* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
static void
mips_autovectorize_vector_sizes (vector_sizes *sizes)
{
if (ISA_HAS_MSA)
sizes->safe_push (16); /*此处告诉了前端,如果使用的是支持MSA的后端,在向量化时寄存器长度可以达到16字节*/
}
2. 支持的向量运算主要在对应的md文件中定义
如要支持加法的向量运算,在mips-msa.md文件中就会针对对应的模式,给出如下的相应定义。(注意,这里的add<mode>3除了<mode>是后端增加的外,其他的add是gcc的模板标准的指令名,这样在tree优化的时候就能够根据名字展开对应的向量模式了)
;; Integer operations
(define_insn "add<mode>3"
[(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
(plus:IMSA
(match_operand:IMSA 1 "register_operand" "f,f,f")
(match_operand:IMSA 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
"ISA_HAS_MSA"
{
switch (which_alternative)
{
case 0:
return "addv.<msafmt>\t%w0,%w1,%w2";
case 1:
{
HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
operands[2] = GEN_INT (-val);
return "subvi.<msafmt>\t%w0,%w1,%d2";
}
case 2:
return "addvi.<msafmt>\t%w0,%w1,%E2";
default:
gcc_unreachable ();
}
}
[(set_attr "alu_type" "simd_add")
(set_attr "type" "simd_int_arith")
(set_attr "mode" "<MODE>")])