[M3devel] subrange value not constant?

Mika Nystrom mika at async.caltech.edu
Thu May 21 09:34:48 CEST 2009


In general you're right but often, such expressions generate precisely
the same assembly on my machine, so I think it's mostly a clarity
issue.  I don't even have to use -O.

Hmm, it's possible this is only true if the compiler can statically
determine that the range checks are OK.  The range checks inserted
by cm3 seem to inhibit the optimization (i.e., the range checks are
carried out for every "evaluation").

     Mika

(226)rover:~/src>cat P.m3 
MODULE P EXPORTS Main;

VAR x : ARRAY [0..10] OF INTEGER;

PROCEDURE P() =
  BEGIN INC(x[5]) END P;

PROCEDURE Q() =
  BEGIN x[5] := x[5]+1 END Q;

BEGIN END P.

(227)rover:~/src>cm3
--- building in ../FreeBSD4 ---

new source -> compiling P.m3
"../src/P.m3", line 5: warning: not used (P)
"../src/P.m3", line 8: warning: not used (Q)
2 warnings encountered
new "P.mo" -> linking prog
(228)rover:~/src>objdump --disassemble ../FreeBSD4/P.mo

../FreeBSD4/P.mo:     file format elf32-i386-freebsd

Disassembly of section .text:

00000000 <P__P>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   a1 88 00 00 00          mov    0x88,%eax
   8:   8d 50 01                lea    0x1(%eax),%edx
   b:   a1 88 00 00 00          mov    0x88,%eax
  10:   83 e0 00                and    $0x0,%eax
  13:   09 d0                   or     %edx,%eax
  15:   a3 88 00 00 00          mov    %eax,0x88
  1a:   5d                      pop    %ebp
  1b:   c3                      ret    

0000001c <P__Q>:
  1c:   55                      push   %ebp
  1d:   89 e5                   mov    %esp,%ebp
  1f:   a1 88 00 00 00          mov    0x88,%eax
  24:   8d 50 01                lea    0x1(%eax),%edx
  27:   a1 88 00 00 00          mov    0x88,%eax
  2c:   83 e0 00                and    $0x0,%eax
  2f:   09 d0                   or     %edx,%eax
  31:   a3 88 00 00 00          mov    %eax,0x88
  36:   5d                      pop    %ebp
  37:   c3                      ret    

00000038 <P_M3>:
  38:   55                      push   %ebp
  39:   89 e5                   mov    %esp,%ebp
  3b:   83 ec 04                sub    $0x4,%esp
  3e:   8b 45 08                mov    0x8(%ebp),%eax
  41:   b8 40 00 00 00          mov    $0x40,%eax
  46:   c9                      leave  
  47:   c3                      ret    


Jay writes:
>
>INC and DEC?
>Oh for += and -=.
> 
>It's not just clarity though, it is also to avoid the cost of evaluating the expression twice.
> 
> - Jay
>
>
>----------------------------------------
>> To: martinbishop at bellsouth.net
>> Date: Wed, 20 May 2009 22:27:43 -0700
>> From: mika at async.caltech.edu
>> CC: m3devel at elegosoft.com
>> Subject: Re: [M3devel] subrange value not constant?
>>
>>
>> Martin, you have one bug: you don't initialize count. Per 2.6.9 in the
>> Green Book, NEW returns "an arbitrary value of its type"
>>
>> Also, for slightly more clarity, count can be a REF ARRAY OF CARDINAL.
>>
>> INC and DEC would make the code a bit easier to read, perhaps.
>>
>> Finally, you can dispense with min and max completely by just using
>> min, initialized to a[0], and re-allocating the array whenever the
>> new value is greater than min + NUMBER(count^) :-) But maybe you
>> already know what min and max are by some means that doesn't involve
>> scanning the array.
>>
>> Mika
>>
>>
>>
>>
>> Martin Bishop writes:
>>>By the way, in case anyone cares, here's the proper code:
>>>
>>>PROCEDURE Sort(VAR a: ARRAY OF INTEGER; min, max: INTEGER) =
>>> VAR range := max - min + 1;
>>> count := NEW(REF ARRAY OF INTEGER, range);
>>> z := 0;
>>> BEGIN
>>> FOR i := FIRST(a) TO LAST(a) DO
>>> count[a[i] - min] := count[a[i] - min] + 1;
>>> END;
>>> FOR i := min TO max DO
>>> WHILE (count[i - min]> 0) DO
>>> a[z] := i;
>>> INC(z);
>>> count[i - min] := count[i - min] - 1;
>>> END;
>>> END;
>>> END Sort;
>>>
>>>Martin Bishop wrote:
>>>> I've written this procedure (an implementation of counting sort):
>>>>
>>>> PROCEDURE Sort(VAR a: ARRAY OF INTEGER; min, max: INTEGER) =
>>>> VAR count := ARRAY [min..max] OF INTEGER {0, ..};
>>>> z := 0;
>>>> BEGIN
>>>> FOR i := FIRST(a) TO LAST(a) DO
>>>> count[i - min] := count[i - min] + 1;
>>>> END;
>>>> FOR i := min TO max DO
>>>> WHILE count[i - min]> 0 DO
>>>> a[z] := i;
>>>> INC(z);
>>>> count[i - min] := count[i - min] - 1;
>>>> END;
>>>> END;
>>>> END Sort;
>>>>
>>>> However, when I try to compile I get:
>>>>
>>>> "../Counting.m3", line 8: subrange lower bound is not constant
>>>> "../Counting.m3", line 8: subrange upper bound is not constant
>>>>
>>>> Line 8 is:
>>>>
>>>> VAR count := ARRAY [min..max] OF INTEGER {0, ..};
>>>>
>>>> I don't see what's wrong?
>>>>
>>>>



More information about the M3devel mailing list