This commit is contained in:
Andreas Rumpf 2016-05-28 17:43:47 +02:00
commit 426306eeb4
2 changed files with 59 additions and 31 deletions

View file

@ -1818,7 +1818,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
result = nil result = nil
template setResult(e: expr) = template setResult(e: expr) =
if semCheck: result = semStmt(c, e) # do not open a new scope! if semCheck: result = semExpr(c, e) # do not open a new scope!
else: result = e else: result = e
# Check if the node is "when nimvm" # Check if the node is "when nimvm"
@ -1827,6 +1827,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
# else: # else:
# ... # ...
var whenNimvm = false var whenNimvm = false
var typ = commonTypeBegin
if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and
n.sons[1].kind == nkElse: n.sons[1].kind == nkElse:
let exprNode = n.sons[0].sons[0] let exprNode = n.sons[0].sons[0]
@ -1843,7 +1844,8 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
checkSonsLen(it, 2) checkSonsLen(it, 2)
if whenNimvm: if whenNimvm:
if semCheck: if semCheck:
it.sons[1] = semStmt(c, it.sons[1]) it.sons[1] = semExpr(c, it.sons[1])
typ = commonType(typ, it.sons[1].typ)
result = n # when nimvm is not elimited until codegen result = n # when nimvm is not elimited until codegen
else: else:
var e = semConstExpr(c, it.sons[0]) var e = semConstExpr(c, it.sons[0])
@ -1857,12 +1859,14 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
checkSonsLen(it, 1) checkSonsLen(it, 1)
if result == nil or whenNimvm: if result == nil or whenNimvm:
if semCheck: if semCheck:
it.sons[0] = semStmt(c, it.sons[0]) it.sons[0] = semExpr(c, it.sons[0])
typ = commonType(typ, it.sons[0].typ)
if result == nil: if result == nil:
result = it.sons[0] result = it.sons[0]
else: illFormedAst(n) else: illFormedAst(n)
if result == nil: if result == nil:
result = newNodeI(nkEmpty, n.info) result = newNodeI(nkEmpty, n.info)
if whenNimvm: result.typ = typ
# The ``when`` statement implements the mechanism for platform dependent # The ``when`` statement implements the mechanism for platform dependent
# code. Thus we try to ensure here consistent ID allocation after the # code. Thus we try to ensure here consistent ID allocation after the
# ``when`` statement. # ``when`` statement.

View file

@ -3042,34 +3042,6 @@ when not defined(JS): #and not defined(nimscript):
{.pop.} # stacktrace {.pop.} # stacktrace
when not defined(nimscript): when not defined(nimscript):
proc likely*(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}
## Hints the optimizer that `val` is likely going to be true.
##
## You can use this proc to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nim
## for value in inputValues:
## if likely(value <= 100):
## process(value)
## else:
## echo "Value too big!"
proc unlikely*(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}
## Hints the optimizer that `val` is likely going to be false.
##
## You can use this proc to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nim
## for value in inputValues:
## if unlikely(value > 100):
## echo "Value too big!"
## else:
## process(value)
proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} = proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
## retrieves the raw proc pointer of the closure `x`. This is ## retrieves the raw proc pointer of the closure `x`. This is
## useful for interfacing closures with C. ## useful for interfacing closures with C.
@ -3137,6 +3109,58 @@ proc quit*(errormsg: string, errorcode = QuitFailure) {.noReturn.} =
{.pop.} # checks {.pop.} # checks
{.pop.} # hints {.pop.} # hints
when not defined(JS):
proc likely_proc(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}
proc unlikely_proc(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}
template likely*(val: bool): bool =
## Hints the optimizer that `val` is likely going to be true.
##
## You can use this template to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nim
## for value in inputValues:
## if likely(value <= 100):
## process(value)
## else:
## echo "Value too big!"
##
## On backends without branch prediction (JS and the nimscript VM), this
## template will not affect code execution.
when nimvm:
val
else:
when defined(JS):
val
else:
likely_proc(val)
template unlikely*(val: bool): bool =
## Hints the optimizer that `val` is likely going to be false.
##
## You can use this proc to decorate a branch condition. On certain
## platforms this can help the processor predict better which branch is
## going to be run. Example:
##
## .. code-block:: nim
## for value in inputValues:
## if unlikely(value > 100):
## echo "Value too big!"
## else:
## process(value)
##
## On backends without branch prediction (JS and the nimscript VM), this
## template will not affect code execution.
when nimvm:
val
else:
when defined(JS):
val
else:
unlikely_proc(val)
proc `/`*(x, y: int): float {.inline, noSideEffect.} = proc `/`*(x, y: int): float {.inline, noSideEffect.} =
## integer division that results in a float. ## integer division that results in a float.
result = toFloat(x) / toFloat(y) result = toFloat(x) / toFloat(y)