added system.||; lacks runtime support

This commit is contained in:
Araq
2012-05-23 02:05:28 +02:00
parent 1c01c78be5
commit 848c1b297f
12 changed files with 60 additions and 9 deletions

View File

@@ -145,6 +145,7 @@ type
nkIfStmt, # an if statement
nkWhenStmt, # a when expression or statement
nkForStmt, # a for statement
nkParForStmt, # a parallel for statement
nkWhileStmt, # a while statement
nkCaseStmt, # a case statement
nkTypeSection, # a type section (consists of type definitions)
@@ -396,7 +397,7 @@ type
mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet,
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
mConTArr, mConTT, mSlice,
mFields, mFieldPairs,
mFields, mFieldPairs, mOmpParFor,
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq,
mIsPartOf, mAstToStr, mRand,

View File

@@ -258,6 +258,34 @@ proc genBlock(p: BProc, t: PNode, d: var TLoc) =
else: genStmts(p, t.sons[1])
endBlock(p)
proc genParForStmt(p: BProc, t: PNode) =
assert(sonsLen(t) == 3)
inc(p.withinLoop)
genLineDir(p, t)
preserveBreakIdx:
let forLoopVar = t.sons[0].sym
var rangeA, rangeB: TLoc
assignLocalVar(P, forLoopVar)
#initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack)
#discard mangleName(forLoopVar)
let call = t.sons[1]
initLocExpr(p, call.sons[1], rangeA)
initLocExpr(p, call.sons[2], rangeB)
appf(p.s(cpsStmts), "#pragma omp parallel for $4$n" &
"for ($1 = $2; $1 <= $3; ++$1)",
forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc,
call.sons[3].getStr.toRope)
p.breakIdx = startBlock(p)
p.blocks[p.breakIdx].isLoop = true
genStmts(p, t.sons[2])
endBlock(p)
dec(p.withinLoop)
proc genBreakStmt(p: BProc, t: PNode) =
var idx = p.breakIdx
if t.sons[0].kind != nkEmpty:
@@ -815,5 +843,6 @@ proc genStmts(p: BProc, t: PNode) =
# we have not only the header:
if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
genProc(p.module, prc)
of nkParForStmt: genParForStmt(p, t)
else: internalError(t.info, "genStmts(" & $t.kind & ')')

View File

@@ -1341,7 +1341,8 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
of nkWhileStmt: genWhileStmt(p, n, r)
of nkVarSection, nkLetSection: genVarStmt(p, n, r)
of nkConstSection: genConstStmt(p, n, r)
of nkForStmt: internalError(n.info, "for statement not eliminated")
of nkForStmt, nkParForStmt:
internalError(n.info, "for statement not eliminated")
of nkCaseStmt: genCaseStmt(p, n, r)
of nkReturnStmt: genReturnStmt(p, n, r)
of nkBreakStmt: genBreakStmt(p, n, r)

View File

@@ -1289,7 +1289,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkPragmaBlock:
result = evalAux(c, n.sons[1], flags)
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
nkLambdaKinds, nkContinueStmt, nkIdent:
nkLambdaKinds, nkContinueStmt, nkIdent, nkParForStmt:
result = raiseCannotEval(c, n.info)
of nkRefTy:
result = evalAux(c, n.sons[0], flags)

View File

@@ -984,7 +984,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkCaseStmt, nkRecCase: gcase(g, n)
of nkMacroStmt: gmacro(g, n)
of nkTryStmt: gtry(g, n)
of nkForStmt: gfor(g, n)
of nkForStmt, nkParForStmt: gfor(g, n)
of nkBlockStmt, nkBlockExpr: gblock(g, n)
of nkStaticStmt: gstaticStmt(g, n)
of nkAsmStmt: gasm(g, n)

View File

@@ -142,7 +142,7 @@ proc semGenericStmt(c: PContext, n: PNode,
a.sons[j] = semGenericStmt(c, a.sons[j], flags, toBind)
a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind)
closeScope(c.tab)
of nkForStmt:
of nkForStmt, nkParForStmt:
var L = sonsLen(n)
openScope(c.tab)
n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind)

View File

@@ -465,7 +465,11 @@ proc semFor(c: PContext, n: PNode): PNode =
else:
GlobalError(n.sons[length - 2].info, errIteratorExpected)
elif call.sons[0].sym.magic != mNone:
result = semForFields(c, n, call.sons[0].sym.magic)
if call.sons[0].sym.magic == mOmpParFor:
result = semForVars(c, n)
result.kind = nkParForStmt
else:
result = semForFields(c, n, call.sons[0].sym.magic)
else:
result = semForVars(c, n)
closeScope(c.tab)
@@ -889,7 +893,7 @@ proc SemStmt(c: PContext, n: PNode): PNode =
of nkWhileStmt: result = semWhile(c, n)
of nkTryStmt: result = semTry(c, n)
of nkBreakStmt, nkContinueStmt: result = semBreakOrContinue(c, n)
of nkForStmt: result = semFor(c, n)
of nkForStmt, nkParForStmt: result = semFor(c, n)
of nkCaseStmt: result = semCase(c, n)
of nkReturnStmt: result = semReturn(c, n)
of nkAsmStmt: result = semAsm(c, n)

View File

@@ -247,7 +247,7 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode =
proc hasContinue(n: PNode): bool =
case n.kind
of nkEmpty..nkNilLit, nkForStmt, nkWhileStmt: nil
of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: nil
of nkContinueStmt: result = true
else:
for i in countup(0, sonsLen(n) - 1):
@@ -659,6 +659,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
inc c.inLoop
result = transformFor(c, n)
dec c.inLoop
of nkParForStmt:
inc c.inLoop
result = transformSons(c, n)
dec c.inLoop
of nkCaseStmt: result = transformCase(c, n)
of nkContinueStmt:
result = PTransNode(newNode(nkBreakStmt))

View File

@@ -60,6 +60,7 @@ hint[LineTooLong]=off
@if unix:
@if not bsd:
# -fopenmp
gcc.options.linker = "-ldl"
clang.options.linker = "-ldl"
tcc.options.linker = "-ldl"

View File

@@ -36,7 +36,7 @@ type
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt,
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
nnkForStmt, nnkWhileStmt, nnkCaseStmt,
nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
nnkConstDef, nnkTypeDef,
nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,

View File

@@ -1200,6 +1200,15 @@ iterator `..`*[S, T](a: S, b: T): T {.inline.} =
yield res
inc res
iterator `||`*[S, T](a: S, b: T, annotation=""): T {.
inline, magic: "OmpParFor", sideEffect.} =
## parallel loop iterator. Same as `..` but the loop may run in parallel.
## `annotation` is an additional annotation for the code generator to use.
## 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.
nil
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}

View File

@@ -46,6 +46,7 @@ Library Additions
- Added ``system.clamp`` to limit a value within an interval ``[a, b]``.
- Added ``strutils.continuesWith``.
- Added ``system.getStackTrace``.
- Added ``system.||`` for parallel for loop support.
- The GC supports (soft) realtime systems via ``GC_setMaxPause``
and ``GC_step`` procs.
@@ -84,6 +85,7 @@ Compiler Additions
option or pragma.
- The compiler now generates marker procs that the GC can use instead of RTTI.
This speeds up the GC quite a bit.
- The compiler now supports OpenMP's parallel for loop.
Language Additions