bugfixes; field discriminant checks; linearScanEnd, unroll, shallow pragmas

This commit is contained in:
Araq
2011-03-23 01:09:52 +01:00
parent 8d734244b1
commit 5b789f2da8
45 changed files with 2342 additions and 243 deletions

View File

@@ -2614,6 +2614,26 @@ The `final`:idx: pragma can be used for an object type to specify that it
cannot be inherited from.
shallow pragma
--------------
The `shallow`:idx: pragma affects the semantics of a type: The compiler is
allowed to make a shallow copy. This can cause serious semantic issues and
break memory safety! However, it can speed up assignments considerably,
because the semantics of Nimrod require deep copying of sequences and strings.
This can be expensive, especially if sequences are used to build a tree
structure:
.. code-block:: nimrod
type
TNodeKind = enum nkLeaf, nkInner
TNode {.final, shallow.} = object
case kind: TNodeKind
of nkLeaf:
strVal: string
of nkInner:
children: seq[TNode]
Pure pragma
-----------
The `pure`:idx: pragma serves two completely different purposes:
@@ -2646,53 +2666,53 @@ hint pragma
-----------
The `hint`:idx: pragma is used to make the compiler output a hint message with
the given content. Compilation continues after the hint.
linearScanEnd pragma
--------------------
The `linearScanEnd`:idx: pragma can be used to tell the compiler how to
compile a Nimrod `case`:idx: statement. Syntactially it has to be used as a
statement:
.. code-block:: nimrod
case myInt
of 0:
echo "most common case"
of 1:
{.linearScanEnd.}
echo "second most common case"
of 2: echo "unlikely: use branch table"
else: echo "unlikely too: use branch table for ", myInt
In the example, the case branches ``0`` and ``1`` are much more common than
the other cases. Therefore the generated assembler code should test for these
values first, so that the CPU's branch predictor has a good chance to succeed
(avoiding an expensive CPU pipeline stall). The other cases might be put into a
jump table for O(1) overhead, but at the cost of a (very likely) pipeline
stall.
The ``linearScanEnd`` pragma should be put into the last branch that should be
tested against via linear scanning. If put into the last branch of the
whole ``case`` statement, the whole ``case`` statement uses linear scanning.
unroll pragma
-------------
The `unroll`:idx: pragma can be used to tell the compiler that it should unroll
a `for`:idx: or `while`:idx: loop for runtime efficiency:
.. code-block:: nimrod
proc searchChar(s: string, c: char): int =
for i in 0 .. s.high:
{.unroll: 4.}
if s[i] == c: return i
result = -1
In the above example, the search loop is unrolled by a factor 4. The unroll
factor can be left out too; the compiler then chooses an appropriate unroll
factor.
**Note**: Currently the compiler recognizes but ignores this pragma.
linearScanEnd pragma
--------------------
The `linearScanEnd`:idx: pragma can be used to tell the compiler how to
compile a Nimrod `case`:idx: statement. Syntactially it has to be used as a
statement:
.. code-block:: nimrod
case myInt
of 0:
echo "most common case"
of 1:
{.linearScanEnd.}
echo "second most common case"
of 2: echo "unlikely: use branch table"
else: echo "unlikely too: use branch table for ", myInt
In the example, the case branches ``0`` and ``1`` are much more common than
the other cases. Therefore the generated assembler code should test for these
values first, so that the CPU's branch predictor has a good chance to succeed
(avoiding an expensive CPU pipeline stall). The other cases might be put into a
jump table for O(1) overhead, but at the cost of a (very likely) pipeline
stall.
The ``linearScanEnd`` pragma should be put into the last branch that should be
tested against via linear scanning. If put into the last branch of the
whole ``case`` statement, the whole ``case`` statement uses linear scanning.
unroll pragma
-------------
The `unroll`:idx: pragma can be used to tell the compiler that it should unroll
a `for`:idx: or `while`:idx: loop for runtime efficiency:
.. code-block:: nimrod
proc searchChar(s: string, c: char): int =
for i in 0 .. s.high:
{.unroll: 4.}
if s[i] == c: return i
result = -1
In the above example, the search loop is unrolled by a factor 4. The unroll
factor can be left out too; the compiler then chooses an appropriate unroll
factor.
**Note**: Currently the compiler recognizes but ignores this pragma.
compilation option pragmas