Pliant talk forum

Pliant talk forum

Discussion: Strange optimizer bug

How to find an optimizer bug?
Message posted by maybe Patrice Ossona de Mendez on 2002/03/23 11:55:56
I encountered a strange bug:
I use a local variable of type Str to initialize a pointer in an object.
I use the object as the only access to the variable in a loop.
If I do it this way, in my function, the local variable seems to be freed
prematuraly and I got an excpetion, that disappear if I add an access
to the local variable after the loop.

I tried to reproduce it with a smaller example, in vain.
Message posted by maybe Hubert Tonneau on 2002/03/23 13:12:42
> I use a local variable of type Str to initialize a pointer in an object.

How can a variable with type Str be a pointer ?

Could you publish not the all example since you specified that it is complex,
but only the fiew lines declaring and setting the variables, with some ...
in the middle.
Message posted by maybe  on 2002/03/24 10:09:37
type PatchCursor
  field Pointer:Str code # source patch string
  field Str reqs         # maped substring
  field PatchReq req     # current request
  field Int full         # remaining patch substring size
  field Bool atend       # end reached

method pc init c
  arg_w PatchCursor pc; arg Str c
  pc:code :> c
  pc:full := c:len
  pc:reqs set (pc:code:characters translate Char 0) pc:full false
  pc:req:op:=" "
  pc forward

function apply p f1 f2
  arg Data:FilePatch p; arg Array:Int f1; arg_w Array:Int f2
  var Str op := p:op
  var PatchCursor pc; pc init op
  while not pc:atend
    if pc:op="s"
    eif pc:op="d"
    eif pc:op="a"
    else # failure
      console "failure" eol
    pc forward_req
  op:=op 0 1 # Causes op not to be lost !

Remark: the same problem arises if, instead of "pc init op" (initialisation
with a local) I do "pc init p:op" (initialisation with a Data:Str)
Message posted by maybe Hubert Tonneau on 2002/03/24 10:26:24
This is the faulty section:

method pc init c
  arg_w PatchCursor pc; arg Str c
  pc:code :> c

It breaks the optimizer assertions because you have a function that will
map one of it's argument to another one, without telling the optimizer.

One way to solve it is to specify that 'PatchCursor' is a kind of pointer:

module "/pliant/language/compiler.pli"
(addressof:PatchCursor map Type) flags := PatchCursor:flags .or. type_flag_mapper

Message posted by maybe Patrice Ossona de Mendez on 2002/03/24 10:39:43
Works now. :-)
Message posted by maybe Hubert Tonneau on 2002/03/24 10:46:06
You could also teach Pliant optimizer at function level instead of type level.
Here is an example:

module "/pliant/language/compiler.pli"

function foo a b
  arg Int a b

((the_function foo Int Int) arg 0) maps := 2^1
# means that on return of 'foo', the first argument 'a' (it's index is 0)
# may be mapping the second one 'b' (it's index is 1)

Also, in your case, the 'PatchCursor' is truely a kind of pointer, so it's
better to declare at type level rather than the function.

The exact relation between type level and function level is that Pliant
optimizer is assuming than any argument which has 'mapper' flag set in it's
type may map any other argument passed to the function, so the 'maps' fields
in the functions prototypes are automatically silently set.