Clear[sum];
sum = Compile[{{n0, _Integer}, {s0, _Integer}},
Block[{n = n0, s = s0},
Label["t"];
If[n > 0, s += n; n--; Goto["t"]];
s
]
];
sum[10, 0]
It seems that the Label is not found. How to make it works?
Clear[sum];
sum = Compile[{{n0, _Integer}, {s0, _Integer}},
Block[{n = n0, s = s0},
Label["t"];
If[n > 0, s += n; n--; Goto["t"]];
s
]
];
sum[10, 0]
It seems that the Label is not found. How to make it works?
It looks like the compiler has troubles when Goto appears as a compound statement in If. It causes a call to MainEvaluate for this part of the code which, as shown here, means calling a labelled Goto where the compiler already removed the Label.
Needs["CompiledFunctionTools`"]
CompilePrint[sum]
2 arguments
1 Boolean register
9 Integer registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
I0 = A1
I1 = A2
I7 = 1
I5 = 0
Result = I4
1 I2 = I0
2 I4 = I1
3
4 B0 = I5 < I2
5 if[ !B0] goto 8
6 V17I2I4 = MainEvaluate[ Function[{n0, s0, nCompile$22, sCompile$23},
Block[{n = nCompile$22, s = sCompile$23},
{s += n; n--; Goto[t], n, s}]][ I0, I1, I2, I4]]
7 goto 8
8 Return
If you rewrite it to move the compound statement out of the If:
Clear[sum];
sum = Compile[{{n0, _Integer}, {s0, _Integer}},
Block[{n = n0, s = s0},
Label["t"];
If[n <= 0, Goto["end"]];
s += n; n--; Goto["t"];
Label["end"];
s]];
sum[10, 0]
55
it works as intended.
Goto to generate an MEvaluate call will fail. That could be a non-compilable Print as in the other question, but also apparently CompundExpression with Goto as is the case here.
– Sjoerd C. de Vries
Nov 03 '13 at 12:27
Sjoerd's answer already gives the solution. Let me try to dig a bit deeper. In the Details section of the Goto documentation one finds
Goto first scans any compound expression in which it appears directly, then scans compound expressions that enclose this one.
This suggests to me that Goto only works iff the Label is in the same CompoundExpression or in an enclosed one. If we look at a simplified version of the OP's code we see
Hold[(Label[t];
If[True,
Goto[t];
];
s)] // TreeForm

that CompoundExpression containing the Goto is not enclosed by another one. It is enclosed by an If expression. Sjoerds solution circumvents this by eliminating the CompoundExpression inside the If thus leaving outer CompoundExpression as first reachable one.
Hold[(
Label["t"];
If[True, Goto["end"]];
Goto["t"];
Label["end"])] // TreeForm

Unfortunately, this is not the end of the story. It seems that with Compile exactly this "scan for the next enclosed CompoundExpression" does not work correctly. Let's take one very simple example
Hold[(1; Goto["end"]; 2; Label["end"]; 3)] // TreeForm

If one compiles this code, it will work as expected: no MainEvaluate. Although, if you nest the CompoundExpression by simply using some parenthesis
Hold[((1; Goto["end"]); 2; Label["end"]; 3)] // TreeForm

The code will not compile. This leaves only one conclusion: Be careful when you work with Goto and Compile, it might not work as expected.
The last line yields 55
I look forward to clarification from the experts.
– ubpdqn Nov 03 '13 at 11:51