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
.
让我们考虑一下 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
.