gfortran 如何处理无法访问的代码?

How does gfortran handle unreachable code?

让我们考虑一下 Fort运行 95 段代码(假设它包含在名为 main.f95 的文件中):

module params
    implicit none
    real*4, parameter :: r4_dum = 1
    real, parameter :: r_dum = 1
    logical, parameter :: r32bit = (kind(r4_dum)==kind(r_dum))
    contains
        subroutine print_state
            implicit none
            print*,'r32bit: ', r32bit
        end subroutine print_state
end module

module convert
    contains
        subroutine r32_to_64bit(r4, r8)
            implicit none
            real*4, intent(in) :: r4
            real*8, intent(out) :: r8
            r8 = dble(r4)
        end subroutine r32_to_64bit
end module convert

program test
    use params, only: r32bit, print_state
    use convert, only: r32_to_64bit
    implicit none
    real :: myReal
    real*8 :: work8

    call print_state
    if (r32bit) then
        call r32_to_64bit(myReal, work8)
    else
        work8 = myReal
    endif
end program test

如您所见,if (r32bit)else 部分无法访问。我 运行 以下内容:

% gfortran -O3 -Wunreachable-code -fdump-tree-optimized main.f95

查看gfortran是否找到无法到达的部分并删除无用的b运行ching,但这给出了一个非常空的输出。在目前的情况下,gfortran 似乎没有删除代码中无法访问的部分。

所以,我的问题如下:是什么阻止了 gfortran 检测到此 else 部分无用并摆脱它?

我的编译器(gfortran 4.7 和 5.3 -O3 -fdump-tree-optimized)执行代码消除:

main (integer(kind=4) argc, character(kind=1) * * argv)
{
  static integer(kind=4) options.1[9] = {68, 1023, 0, 0, 1, 1, 0, 0, 31};

  <bb 2>:
  _gfortran_set_args (argc_2(D), argv_3(D));
  _gfortran_set_options (9, &options.1[0]);
  print_state ();
  return 0;

}

并打印出正确答案

> ./a.out 
 r32bit:  T

您不能指望优化会修复无效的无法访问的代码。该代码仍然无效,甚至无法访问。


当我添加一些诊断时

if (r32bit) then
    call r32_to_64bit(myReal, work8)
    print *, '+'
else
    work8 = myReal
    print *, '-'
endif

依然正确消除:

test ()
{
  struct __st_parameter_dt dt_parm.1;

  <bb 2>:
  print_state ();
  dt_parm.1.common.filename = &"dead_elim.f90"[1]{lb: 1 sz: 1};
  dt_parm.1.common.line = 34;
  dt_parm.1.common.flags = 128;
  dt_parm.1.common.unit = 6;
  _gfortran_st_write (&dt_parm.1);
  _gfortran_transfer_character_write (&dt_parm.1, &"+"[1]{lb: 1 sz: 1}, 1);
  _gfortran_st_write_done (&dt_parm.1);
  dt_parm.1 ={v} {CLOBBER};
  return;

}

并且程序确实打印了 + 作为它的最后输出。

最终代码中没有条件,被淘汰


也许您希望 -fdump-tree-optimized 立即打印一些东西?它不会那样做,它会将优化后的代码写入文件。在我的例子中,它被命名为 dead_elim.f90.191t.optimized.