Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29383 Discussions

One stupid question concerning IFs and GOTOs.

atru
Beginner
5,117 Views

I wonder if exists any way to translate this assembler similar fortran code into the modern code without IF-THEN-ELSE? How to minimize the interminable conditional constructs? If my question is very stupid, forgive me. Just too many IFs and GOTOs spoil the soup.

0 Kudos
21 Replies
jimdempseyatthecove
Honored Contributor III
4,550 Views

The top line of your code snip was clipped. Also it is unclear as to if some or all of the tested variables can only have 0 or 1.

For the binary variables (possbly A:F) consider compositing them into an integer, use the integer as an index into a (parameter) table, then use the contents of the table either in your IF test or in a computed GOTO.

Jim Dempsey

0 Kudos
atru
Beginner
4,550 Views

Hmm… There is not a full stroke in the top line … The following line shows the full stroke:

 IF(A.EQ.0.AND.B.EQ.0.AND.C.EQ.0.AND.D.EQ.0.AND.E.EQ.0.AND.F.EQ.1) GO TO 9

0 Kudos
Steven_L_Intel1
Employee
4,550 Views

Are the values only 0 or 1? Could you use LOGICAL instead?

0 Kudos
atru
Beginner
4,550 Views
I am thinking about LOGICAL… In theory – only 0 and 1, in practice – nobody knows.
0 Kudos
atru
Beginner
4,550 Views

In other words a program has to use only 0 and 1. No other numbers are expected.

0 Kudos
TimP
Honored Contributor III
4,550 Views

If efficiency is the goal, it's not a foregone conclusion that streamlining the source code will make it run faster than a good compiler can do.

It looks like some kind of automatically generated code.  If the goal is to change this code into something more human readable, both open source and commercial tools exist (e.g. http://www.polyhedron.com/spag0html )  It's likely to require iterations between manual improvement, testing, and automated beautifier.

0 Kudos
Steven_L_Intel1
Employee
4,550 Views

I like Jim's idea of a table. It would be useful to draw up a table of all the combinations (there will be 256 of them for A through H) and determine where you want each one to go.

0 Kudos
andrew_4619
Honored Contributor III
4,550 Views

There 1 test to start for goto 9 and then 6 test for goto 6 follow. You need to negate them eg. if(h.lt.0 .or. h.gt.1 ) goto 6  or if( .not. (h.eq.o or. h.eq.1))  goto 6 and then it all look much clearer with no cascading jumps (if clarity is the objective).

0 Kudos
atru
Beginner
4,550 Views
Holy Mackerel! 256! Steve! Could you show it by example? I think you can not. I like Tim’s idea about changing this code into something more human readable by means of special tools. Without doubt the efficiency is of importance for my tasks, but from time to time somebody should read the code, it will not be a good thing to see many GOTOs that jump like fleas. The reasonable balance is wanted.
0 Kudos
atru
Beginner
4,550 Views
4 app4619 Thank you! Your notice is very useful.
0 Kudos
Steven_L_Intel1
Employee
4,550 Views

Sorry, it's 512 possible combinations. You have nine variables, 2**9 is 512.

0 Kudos
atru
Beginner
4,550 Views

Of course, I should express my grateful to Jim. Otherwise nobody could have read Steve’s comments. His remarks were dripping with mild sarcasm. Jim’s idea, gently ridiculed by Steve, was yet believed by some.

0 Kudos
atru
Beginner
4,550 Views
4 Steve. It’s a part of code. In fact a number of variables are more than 90. But it’s a top secret. Nobody should know about it. Only you and me.
0 Kudos
Steven_L_Intel1
Employee
4,550 Views

Um, I did not mean to ridicule Jim at all, and no sarcasm was intended. If the only values allowed were truly 0 and 1, and if the number of variables was limited to what you showed, then a table was a fine and efficient idea. But now you tell us that the real code is quite different, so our advice is no longer relevant.

At this point, my advice would be to leave it alone. Add some comments if you wish, but if you try to simplify it you'll probably end up breaking it.

0 Kudos
mecej4
Honored Contributor III
4,550 Views

The code originally shown includes lines such as [fortran]IF(N.EQ.0.OR.N.EQ.1)GOTO xxx[/fortran]If N were truly a boolean variable, this test would not make sense -- why test if a boolean variable has one of the only two possible values that it can have? Steve's advice to leave things alone is sound, given that the "atru" may not know the range of allowable values of M, N, etc.

0 Kudos
andrew_4619
Honored Contributor III
4,550 Views

The not broken don't fix principal is a good one most of the time with software. If you make a change to improve the readability the principal of 'assume nothing' is a good one unless you really understand everything the code does. As per my suggestion a few posts back you can improve the readability enormousy without changing the sequence or underlying logic by taking the negative (.not.) case of many of the checks to remove much uncessessary bunny hopping with goto's. 

0 Kudos
rwg
Novice
4,550 Views
atru are you looking for something like this? IF (.NOT.(A.EQ.0.AND....)) THEN IF(.NOT.(H.EQ.0.OR.H.EQ.1).OR. .NOT.(N.EQ.0.OR.N.EQ.1).OR. .NOT.(M.EQ.0.OR.M.EQ.1).OR. .NOT.(F.EQ.0).OR. ! Same as F.NE.0 (.NOT.(B.EQ.1.AND.A.EQ.0).AND. .NOT.(B.EQ.0.AND.A.EQ.1)).OR. (.NOT.(E.EQ.1.AND.D.EQ.0.AND.C.EQ.0).AND. .NOT.(E.EQ.0.AND.D.EQ.1.AND.C.EQ.0).AND. .NOT.(E.EQ.0.AND.D.EQ.0.AND.C.EQ.1))) THEN WRITE (*,*) ... ENDIF 8 .... ENDIF 9 .... If all values can only be positive you can use to the following IF (A+B+C+D+E.NE.0.OR.F.NE.1) THEN IF(H.GT.1.OR. N.GT.1.OR. M.GT.1.OR. F.NE.0.OR. A+B.NE.1).OR. C+D+E.NE.1) THEN WRITE (*,*) ... ENDIF 8 ... ENDIF 9 ... Sorry, I tried to enable syntax highlighting, but I'm to stupid to paste and handle rich-text.
0 Kudos
Anthony_Richards
New Contributor I
4,550 Views

Are the variables integers?
Are they definitely initialised to some value somewhere?

Are they restricted to values of 0 or 1?

If the latter, then statements 4 and 5 can be replaced with

IF(A+B.EQ.1) go to 5

IF(C+D+E.EQ.1) go to 8

If values other than 0 and 1 are permitted, leave it alone and don't break the code!
Suppose the variables are initialised to = -1, then the additions above will not duplicate the code you show.
And anyway, someone has pointed out that testing a variable for equality to 0 OR 1 indicates other values are possible, otherwise
the test is pointless.

0 Kudos
jimdempseyatthecove
Honored Contributor III
4,550 Views

H, M, N appear to have more than two values. These appear to have at least three states: 0, 1, anything else. For this section of code, 0 or 1 are valid, anything else is invalid (goto 6).

This would work, but it isn't any clearer:

[fortran]
  IOR_BITS = IOR(A,IOR(B,IOR(C,IOR(D,E))))
  IF(IOR_BITS.EQ.0.AND.F.EQ.1) GO TO 9 ! All 0, F==1
  IF(F.EQ.1) GO TO 6
  IF(IAND(IOR_BITS,-2) .NE. 0) GO TO 6 ! Any not 0 nor 1
  IF(IAND(IOR(N,M),-2) .NE. 0) GO TO 6 ! Any not 0 nor 1
  IF(IXOR(A,B).EQ.0) GO TO 6 ! Both 0 or both 1
  IF(C+D+E.EQ.1) GO TO 8
6 WRITE(*,*)
[/fortran]

Jim Dempsey

0 Kudos
atru
Beginner
4,361 Views
Steve! Please forgive me. I did not want to offend anybody. Having thought over all comments I decided that Jim’s idea was very interesting. But your support of it - was not properly understood. Nevertheless your advice is still relevant because all code will be probably transformed into the blocks. So, Jim’s idea is still alive. 2**9 + 2**9 + 2**9… mecej4 Thank you! 0 and 1. The other numbers can appear as a result of human factor or improper calculation. app4619 Your idea to make “negative” is very good. Thank you again! rwg Yes. I am looking for something like that. All values are both positive and integers. Your idea of summation is brilliant. Thank you! Anthony Richards All variables are integers. Answer to second question – yes. Only 0 or 1. I like idea of summation. The values other than 0 and 1 are not expected but they can appear as a result of improper calculation.
0 Kudos
Reply