在优化代码中调用库后避免额外加载

时间:2011-12-12 10:47:58

标签: gcc powerpc

使用两个函数指针key_eqkey_hash实现数据结构。当这些函数指针只设置一次并且从未修改过时,我希望gcc直接在函数地址中编译而不是加载struct成员,但是单个puts("")调用会破坏gcc的常量传播(正确的术语?)

以下是ppc asm的简短片段。可以看到存储了字段key_hash,我们称之为libc puts,然后加载key_hash。如果删除puts,则会正确传播常量。这是不可避免的吗?

    lis 9,hasheq_string@ha   # tmp174,                                       
    la 0,hasheq_string@l(9)  # tmp173,, tmp174                               
    stw 3,16(1)      # h.flags,                                              
    lis 9,hashf_string@ha    # tmp176,                                       
    lis 3,.LC0@ha    # tmp178,                                               
    stw 0,36(1)      # h.key_eq, tmp173                                      
    la 0,hashf_string@l(9)   # tmp175,, tmp176                               
    la 3,.LC0@l(3)   #,, tmp178                                              
    stw 0,40(1)      # h.key_hash, tmp175                                    
    bl puts  #                                                               
    lwz 0,40(1)      # h.key_hash, h.key_hash                                
    mr 3,31  #, tmp164                                                       
    stw 31,32(1)     # h._key, tmp164                                        
    mtctr 0  #, h.key_hash                                                   
    bctrl    #   

我很抱歉没有使用C测试用程序,我很难再现它,但短三行“存储,bl put,load”序列引出了问题,这是不可能的围绕?

1 个答案:

答案 0 :(得分:1)

GCC可能保守地假设对puts的调用可能会读/写内存,因此调用函数可能需要key_hash中的值,并且在调用之前和之后不同。

此代码:

struct S
{
  int f;
};

void bar ();

int
foo (struct S *s)
{
  s->f = 314;
  bar ();
  return s->f + 2;
}

产生“签名”序列:

foo:
    mflr 0
    stwu 1,-32(1)
    stw 29,20(1)
    mr 29,3
    stw 0,36(1)
    li 0,314
    stw 0,0(3)  ;;
    bl bar      ;; here we go
    lwz 3,0(29) ;;
    lwz 0,36(1)
    addi 3,3,2
    lwz 29,20(1)
    mtlr 0
    addi 1,1,32
    blr

但是,通过一个小的修改(手动标量替换聚合?):

struct S
{
  int f;
};

void bar ();

int
foo (struct S *s)
{
  int i;

  s->f = i = 314;
  bar ();
  return i + 2;
}

获得了预期的结果:

foo:
    mflr 0
    stwu 1,-16(1)
    stw 0,20(1)
    li 0,314
    stw 0,0(3)
    bl bar
    lwz 0,20(1)
    li 3,316    ;; constant propagated and folded
    addi 1,1,16
    mtlr 0
    blr