ASSUME 指令向编译器提供有关程序中某些点的条件的提示。这些断言可以帮助编译器设定其优化策略。程序员也可以在执行过程中使用这些指令检查程序的有效性。ASSUME 有两种格式。
“点断言”ASSUME 的语法是:
!$PRAGMA ASSUME (expression [,probability]) |
另外,“范围断言”ASSUME 的语法是:
!$PRAGMA BEGIN ASSUME [expression [, probability) block of statements !$PRAGMA END ASSUME |
请使用点断言格式来声明编译器可在程序中的该点采用的条件。而使用范围断言格式来声明在语句封闭范围内有效的条件。范围断言中的 BEGIN 和 END 对必须正确嵌套。
必需的 expression 是一个布尔表达式,该表达式可在程序中的该点求值,并且其中不包含用户定义的运算符或函数调用(下面列出的除外)。
可选的 probability 值是一个介于 0.0 和 1.0 之间的实数或者是整数 0 或 1,它给出表达式为真的可能性。probability 的值为 0.0(或 0)意味着永远不会为真;值为 1.0(或 1)则意味着始终为真。如果没有指定,则认为表达式很有可能为真,但并不一定为真。probability 为 0 或 1 以外其他值的断言是非必然断言。类似地,probability 正好为 0 或 1 的断言是必然断言。
例如,如果程序员知道 DO 循环的长度始终大于 10,000,则为编译器提供该提示可使之生成更好的代码。通常,以下循环在使用 ASSUME pragma 时比不使用时运行得要快。
!$PRAGMA BEGIN ASSUME(__tripcount().GE.10000,1) !! a big loop do i = j, n a(i) = a(j) + 1 end do !$PRAGMA END ASSUME |
有两个内部函数专用于 ASSUME 指令的表达式子句。(请注意,它们的名称前面有两个下划线。)
__branchexp() |
用于紧挨在分支转移语句(带有布尔控制表达式)前面的点断言。它与控制分支转移语句的布尔表达式生成相同的结果。 |
__tripcount() |
生成紧跟在指令后面的或指令所包含的循环的行程计数。在用于点断言时,指令后面的语句必须位于 DO 的第一行。在用于范围断言时,它应用于最外层的封闭循环。 |
在将来的版本中,特殊内部函数的列表可能会扩展。
可与 -xassume_control 编译器选项结合使用。(请参见3.4.111 –xassume_control[ =keywords])例如,在使用 -xassume_control=check 进行编译时,如果行程计数变为小于 10,000,则上述示例将生成一条警告。
如果使用 -xassume_control=retrospective 进行编译,则在程序终止时会生成一个摘要报告,指出所有断言是真还是假。有关 -xassume_control 的详细信息,请参见 f95 手册页。
另一个示例:
!$PRAGMA ASSUME(__tripcount.GT.0,1) do i=n0, nx |
如果使用 -xassume_control=check 编译上述示例,则在由于行程计数为零或负数而没有执行循环时,将会发出一条运行时警告。