Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为ARM NEON编译时出现未知GCC错误(严重)_C_Gcc_Arm_Neon_Codesourcery - Fatal编程技术网

为ARM NEON编译时出现未知GCC错误(严重)

为ARM NEON编译时出现未知GCC错误(严重),c,gcc,arm,neon,codesourcery,C,Gcc,Arm,Neon,Codesourcery,我有一个基于ARM-A8的处理器目标。我正在利用霓虹灯优化我的代码。但是当我编译我的代码时,我得到了这个奇怪的错误。我不知道怎么解决这个问题 我试图在我的主机上使用代码源代码(第2部分)编译以下代码(第1部分)。 我得到了这个奇怪的错误(第三部分)。我做错什么了吗?其他人可以编译这个,看看他们是否也会得到同样的编译错误吗 奇怪的是,在代码中,如果我注释掉或者如果(step_size==4)代码的一部分,那么错误就会消失。但是,遗憾的是,我的优化没有完成,所以我必须拥有它 起初我认为这是CodeS

我有一个基于ARM-A8的处理器目标。我正在利用霓虹灯优化我的代码。但是当我编译我的代码时,我得到了这个奇怪的错误。我不知道怎么解决这个问题

我试图在我的主机上使用代码源代码(第2部分)编译以下代码(第1部分)。 我得到了这个奇怪的错误(第三部分)。我做错什么了吗?其他人可以编译这个,看看他们是否也会得到同样的编译错误吗

奇怪的是,在代码中,如果我注释掉
或者如果(step_size==4)
代码的一部分,那么错误就会消失。但是,遗憾的是,我的优化没有完成,所以我必须拥有它

起初我认为这是CodeSourcey编译器(在我的主机上)的问题,所以我直接在我的目标上编译了这个程序(我的目标运行在Ubuntu上)。我在那里使用了gcc,再一次,我得到了相同的错误,当我注释掉
else if(step_size==4)
部分时,错误消失了

救命啊


第1部分

#include<stdio.h>
#include"arm_neon.h"

#define IMAGE_HEIGHT 480
#define IMAGE_WIDTH  640

float32_t integral_image[IMAGE_HEIGHT][IMAGE_WIDTH];

float32x4_t box_area_compute3(int, int , int , int , unsigned int , float);

inline int min(int, int);

int main()
{

 box_area_compute3(1, 1, 4, 4, 2, 0);

 return 0;
}

float32x4_t box_area_compute3(int row, int col, int num_rows, int num_cols, unsigned int step_size, float three)
{
 unsigned int height = IMAGE_HEIGHT;
 unsigned int width = IMAGE_WIDTH;

 int temp_row = row + num_rows;
 int temp_col = col + num_cols;

 int r1 = (min(row, height))- 1 ;
 int r2 = (min(temp_row, height)) - 1;

 int c1 = (min(col, width)) - 1;
 int c2 = (min(temp_col, width)) - 1;

 float32x4_t v128_areas;

 if(step_size == 2)
 {
  float32x4x2_t top_left, top_right, bottom_left, bottom_right;
  top_left    = vld2q_f32((float32_t *)integral_image[r1] + c1);
  top_right   = vld2q_f32((float32_t *)integral_image[r1] + c2);
  bottom_left  = vld2q_f32((float32_t *)integral_image[r2] + c1);
  bottom_right  = vld2q_f32((float32_t *)integral_image[r2] + c2);

  v128_areas = vsubq_f32(vsubq_f32(vaddq_f32(top_left.val[0], bottom_right.val[0]), top_right.val[0]), bottom_left.val[0]);


 }
 else if(step_size == 4)
 {
  float32x4x4_t top_left, top_right, bottom_left, bottom_right;
  top_left   = vld4q_f32((float32_t *)integral_image[r1] + c1);
  top_right   = vld4q_f32((float32_t *)integral_image[r1] + c2);
  bottom_left  = vld4q_f32((float32_t *)integral_image[r2] + c1);
  bottom_right  = vld4q_f32((float32_t *)integral_image[r2] + c2);

  v128_areas = vsubq_f32(vsubq_f32(vaddq_f32(top_left.val[0], bottom_right.val[0]), top_right.val[0]), bottom_left.val[0]);

 }

 if(three == 3.0)
  v128_areas = vmulq_n_f32(v128_areas, three);

 return v128_areas;

}

inline int min(int X, int Y)
{
 return (X < Y ? X : Y);
}

第三部分

../main.c: In function 'box_area_compute3':
../main.c:65: error: unable to find a register to spill in class 'GENERAL_REGS'
../main.c:65: error: this is the insn:
(insn 226 225 227 5 c:\program files\codesourcery\sourcery g++\bin\../lib/gcc/arm-none-linux-gnueabi/4.4.1/include/arm_neon.h:9863 (parallel [
           (set (reg:XI 148 [ D.17028 ])
               (unspec:XI [
                       (mem:XI (reg:SI 3 r3 [301]) [0 S64 A64])
                       (reg:XI 148 [ D.17028 ])
                       (unspec:V4SF [
                               (const_int 0 [0x0])
                           ] 191)
                   ] 111))
           (set (reg:SI 3 r3 [301])
               (plus:SI (reg:SI 3 r3 [301])
                   (const_int 32 [0x20])))
       ]) 1605 {neon_vld4qav4sf} (nil))
../main.c:65: confused by earlier errors, bailing out
cs-make: *** [main.o] Error 1

我无法测试它,因为我没有用于它的工具链,但是这种类型的错误通常可以通过稍微重写代码来解决。通常情况下,这不应该发生,并且应该报告为bug,但您使用的是特定于处理器的功能,与编译器的其余部分相比,这些功能可能没有经过很好的测试和完善

由于这是一个寄存器溢出错误,并且涉及到多个指针,我高度怀疑编译器可能试图将更多的数据加载到寄存器中,而不是它所需要的数据,因为担心可能会出现一些别名(这可能实际上没有发生)。下面我将讨论这种可能性,并做一些其他的事情,从编译器的角度来看,这些事情可能会降低代码的复杂性(尽管看起来可能不是这样)

#包括
#包括“arm_neon.h”
#定义图像高度480
#定义图像宽度640
浮动32_t积分图像[图像高度][图像宽度];
float32x4\u t box\u area\u compute3(int,int,int,int,unsigned int,float);
内联整数最小值(整数,整数);
int main()
{
盒子面积计算3(1,1,4,4,2,0);
返回0;
}
/*通过将这些函数放在单独的函数中,编译器最初将
*自己想想,不要让问题复杂化
*周围的代码。这可能使其能够优化
*在尝试内联它之前先编写一些代码。
*这也可以使编译器更清楚地看到
*局部变量在使用后就失效了(因为它们是
*调用返回后死亡,并且某些变量的生存期
*实际上不能重叠(希望减少寄存器需求)。
*/
静态内联浮点32x4_t do_it2(浮点32_t*tl、浮点32_t*tr、浮点32_t*bl、浮点32_t*br){
浮动32x4x2 t左上、右上、左下、右下;
浮动32x4_t A,B;
左上=vld2q_f32(tl);
右上=vld2q_f32(tr);
左下=vld2q\U f32(bl);
右下=vld2q\U f32(br);
/*通过将其传播到几个语句中,我创建了几个
*附加序列点。编译器不认为
*在执行任何操作之前,必须取消对所有指针的引用
*计算……也许吧*/
A=vaddq_f32(*顶部左.val,*底部右.val);
B=vsubq_f32(A,*top_right.val);
返回vsubq_f32(B,*左下角);
}
静态内联浮点32x4_t do_it4(浮点32_t*tl、浮点32_t*tr、浮点32_t*bl、浮点32_t*br){
浮动32x4x4 t左上、右上、左下、右下;
浮动32x4_t A,B;
左上=vld4q\U f32(tl);
右上=vld4q\U f32(tr);
左下=vld4q\U f32(bl);
右下=vld4q\U f32(br);
A=vaddq_f32(*顶部左.val,*底部右.val);
B=vsubq_f32(A,*top_right.val);
返回vsubq_f32(B,*左下角);
}
float32x4\u t box\u area\u compute3(整数行、整数列、整数行、整数列、无符号整数步长、浮点三)
{
无符号整数高度=图像高度;
无符号整数宽度=图像宽度;
int temp_row=行+行数;
int temp_col=col+num_cols;
int r1=(最小(行,高度))-1;
int r2=(最小值(温度行,高度))-1;
int c1=(最小(列,宽度))-1;
int c2=(最小值(温度柱,宽度))-1;
浮动32x4_t v128_区域;
float32_t*tl=(float32_t*)积分图像[r1]+c1;
float32_t*tr=(float32_t*)积分图像[r1]+c2;
float32_t*bl=(float32_t*)积分图像[r2]+c1;
float32_t*br=(float32_t*)积分图像[r2]+c2;
开关(步进尺寸){
案例2:
v128_区域=do_it2(tl、tr、bl、br);
打破
案例4:
v128_区域=do_it4(tl、tr、bl、br);
打破
}
如果(三=3.0)
v128_区域=vmulq_n_f32(v128_区域,三个);
返回v128_区域;
}
内联整数最小值(整数X,整数Y)
{
返回(X

我希望这有帮助,并且我没有引入任何错误。

我已经就这个问题联系了代码源,他们认为这是GCC编译器中的一个错误。因此我在汇编中编写了do_it4(){…}函数,而不是使用内部函数。现在它工作正常了!

行:

float32x4x4_t top_left, top_right, bottom_left, bottom_right;

使用所有16个q寄存器!编译器无法处理这一点也不奇怪。您可能已经通过重新写入以使用更少的寄存器来修复此问题。

ARM NEON Cortex-A8支持vfpv3,Cortex-A5支持vfpv4和neon2,(至于:如果您使用-mfloat abi=hard,您将跳过在缺少指令的软件中进行仿真的能力,因此您无法生成针对vfpv4进行优化的代码,但将在vfpv3上运行并进行软件仿真)

是的,我觉得这与寄存器分配有关。当我使用vld4q_f32(…)需要分配4个寄存器,在该分配中,编译器可能出现问题。我认为这是一个编译器错误。您可能应该报告它。感谢您的所有努力,但我很难过地再次指出,我遇到了相同的错误:(。
#include<stdio.h>
#include"arm_neon.h"

#define IMAGE_HEIGHT 480
#define IMAGE_WIDTH  640

float32_t integral_image[IMAGE_HEIGHT][IMAGE_WIDTH];

float32x4_t box_area_compute3(int, int , int , int , unsigned int , float);

inline int min(int, int);

int main()
{

 box_area_compute3(1, 1, 4, 4, 2, 0);

 return 0;
}

/* By putting these in separate functions the compiler will initially
 * think about them by themselves, without the complications of the
 * surrounding code.  This may give it the abiltiy to optimise the
 * code somewhat before trying to inline it.
 * This may also serve to make it more obvious to the compiler that
 * the local variables are dead after their use (since they are
 * dead after the call returns, and that the lifetimes of some variable
 * cannot actually overlap (hopefully reducing the register needs).
 */
static inline float32x4_t do_it2(float32_t *tl, float32_t *tr, float32_t *bl, float32_t * br) {
    float32x4x2_t top_left, top_right, bottom_left, bottom_right;
    float32x4_t A, B;

    top_left = vld2q_f32(tl);
    top_right = vld2q_f32(tr);
    bottom_left = vld2q_f32(bl);
    bottom_right = vld2q_f32(br);

    /* By spreading this across several statements I have created several
     * additional sequence points.  The compiler does not think that it
     * has to dereference all of the pointers before doing any of the
     * computations.... maybe. */
    A = vaddq_f32(*top_left.val, *bottom_right.val);
    B = vsubq_f32(A, *top_right.val);
    return vsubq_f32(B, *bottom_left);
}

static inline float32x4_t do_it4(float32_t *tl, float32_t *tr, float32_t *bl, float32_t * br) {
    float32x4x4_t top_left, top_right, bottom_left, bottom_right;
    float32x4_t A, B;

    top_left = vld4q_f32(tl);
    top_right = vld4q_f32(tr);
    bottom_left = vld4q_f32(bl);
    bottom_right = vld4q_f32(br);

    A = vaddq_f32(*top_left.val, *bottom_right.val);
    B = vsubq_f32(A, *top_right.val);
    return vsubq_f32(B, *bottom_left);
}

float32x4_t box_area_compute3(int row, int col, int num_rows, int num_cols, unsigned int step_size, float three)
{
 unsigned int height = IMAGE_HEIGHT;
 unsigned int width = IMAGE_WIDTH;

 int temp_row = row + num_rows;
 int temp_col = col + num_cols;

 int r1 = (min(row, height))- 1 ;
 int r2 = (min(temp_row, height)) - 1;

 int c1 = (min(col, width)) - 1;
 int c2 = (min(temp_col, width)) - 1;

 float32x4_t v128_areas;

     float32_t *tl = (float32_t *)integral_image[r1] + c1;
 float32_t *tr = (float32_t *)integral_image[r1] + c2;
 float32_t *bl = (float32_t *)integral_image[r2] + c1;
 float32_t *br = (float32_t *)integral_image[r2] + c2;


 switch (step_size) {
    case 2:
      v128_areas = do_it2(tl, tr, bl, br);
      break;

 case 4:
      v128_areas = do_it4(tl, tr, bl, br);
      break;
 }

 if(three == 3.0)
  v128_areas = vmulq_n_f32(v128_areas, three);

 return v128_areas;

}

inline int min(int X, int Y)
{
 return (X < Y ? X : Y);
}
float32x4x4_t top_left, top_right, bottom_left, bottom_right;