diff options
author | Mamy Ratsimbazafy <mratsim@users.noreply.github.com> | 2019-03-22 23:38:43 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-03-22 23:38:43 +0100 |
commit | 25649616ea5b6aba575149df3f9943f48a5ece31 (patch) | |
tree | 30da754b1ec901a7fe6f0b7894789ee61d9fc52e | |
parent | 04ad200b403f1c4908a1a043e1f27b111298e1f3 (diff) | |
download | Nim-25649616ea5b6aba575149df3f9943f48a5ece31.tar.gz |
Add OpenMP overload with stepping (#10891)
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 20 | ||||
-rw-r--r-- | lib/system.nim | 18 |
3 files changed, 35 insertions, 5 deletions
diff --git a/changelog.md b/changelog.md index 6e3872219..975c71ca2 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,8 @@ the change is transparent, if you used annotations you will have to prefix your previous annotations with `parallel for`. + Furthermore, an overload with positive stepping is available. + - The `unchecked` pragma was removed, instead use `system.UncheckedArray`. - The undocumented ``#? strongSpaces`` parsing mode has been removed. diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 1e6e04458..2b1cb404d 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -622,15 +622,25 @@ proc genParForStmt(p: BProc, t: PNode) = #initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack) #discard mangleName(forLoopVar) let call = t.sons[1] + assert(sonsLen(call) in {4, 5}) initLocExpr(p, call.sons[1], rangeA) initLocExpr(p, call.sons[2], rangeB) # $n at the beginning because of #9710 - lineF(p, cpsStmts, "$n#pragma omp $4$n" & - "for ($1 = $2; $1 <= $3; ++$1)", - [forLoopVar.loc.rdLoc, - rangeA.rdLoc, rangeB.rdLoc, - call.sons[3].getStr.rope]) + if call.sonsLen == 4: # `||`(a, b, annotation) + lineF(p, cpsStmts, "$n#pragma omp $4$n" & + "for ($1 = $2; $1 <= $3; ++$1)", + [forLoopVar.loc.rdLoc, + rangeA.rdLoc, rangeB.rdLoc, + call.sons[3].getStr.rope]) + else: # `||`(a, b, step, annotation) + var step: TLoc + initLocExpr(p, call.sons[3], step) + lineF(p, cpsStmts, "$n#pragma omp $5$n" & + "for ($1 = $2; $1 <= $3; $1 += $4)", + [forLoopVar.loc.rdLoc, + rangeA.rdLoc, rangeB.rdLoc, step.rdLoc, + call.sons[4].getStr.rope]) p.breakIdx = startBlock(p) p.blocks[p.breakIdx].isLoop = true diff --git a/lib/system.nim b/lib/system.nim index 090c6359c..016675d55 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2681,6 +2681,24 @@ iterator `||`*[S, T](a: S, b: T, annotation: static string = "parallel for"): T ## and GC. discard +iterator `||`*[S, T](a: S, b: T, step: Positive, annotation: static string = "parallel for"): T {. + inline, magic: "OmpParFor", sideEffect.} = + ## OpenMP parallel loop iterator with stepping. + ## Same as `countup` but the loop may run in parallel. + ## + ## `annotation` is an additional annotation for the code generator to use. + ## The default annotation is `parallel for`. + ## Please refer to the `OpenMP Syntax Reference + ## <https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf>`_ + ## for further information. + ## + ## Note that the compiler maps that to + ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as + ## such isn't aware of the parallelism in your code! Be careful! Later + ## versions of ``||`` will get proper support by Nim's code generator + ## and GC. + discard + {.push stackTrace:off.} proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} = if x <= y: x else: y |