added system.||; lacks runtime support

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

View file

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

View file

@ -258,6 +258,34 @@ proc genBlock(p: BProc, t: PNode, d: var TLoc) =
else: genStmts(p, t.sons[1]) else: genStmts(p, t.sons[1])
endBlock(p) 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) = proc genBreakStmt(p: BProc, t: PNode) =
var idx = p.breakIdx var idx = p.breakIdx
if t.sons[0].kind != nkEmpty: if t.sons[0].kind != nkEmpty:
@ -815,5 +843,6 @@ proc genStmts(p: BProc, t: PNode) =
# we have not only the header: # we have not only the header:
if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags: if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
genProc(p.module, prc) genProc(p.module, prc)
of nkParForStmt: genParForStmt(p, t)
else: internalError(t.info, "genStmts(" & $t.kind & ')') 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 nkWhileStmt: genWhileStmt(p, n, r)
of nkVarSection, nkLetSection: genVarStmt(p, n, r) of nkVarSection, nkLetSection: genVarStmt(p, n, r)
of nkConstSection: genConstStmt(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 nkCaseStmt: genCaseStmt(p, n, r)
of nkReturnStmt: genReturnStmt(p, n, r) of nkReturnStmt: genReturnStmt(p, n, r)
of nkBreakStmt: genBreakStmt(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: of nkPragmaBlock:
result = evalAux(c, n.sons[1], flags) result = evalAux(c, n.sons[1], flags)
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr, of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
nkLambdaKinds, nkContinueStmt, nkIdent: nkLambdaKinds, nkContinueStmt, nkIdent, nkParForStmt:
result = raiseCannotEval(c, n.info) result = raiseCannotEval(c, n.info)
of nkRefTy: of nkRefTy:
result = evalAux(c, n.sons[0], flags) 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 nkCaseStmt, nkRecCase: gcase(g, n)
of nkMacroStmt: gmacro(g, n) of nkMacroStmt: gmacro(g, n)
of nkTryStmt: gtry(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 nkBlockStmt, nkBlockExpr: gblock(g, n)
of nkStaticStmt: gstaticStmt(g, n) of nkStaticStmt: gstaticStmt(g, n)
of nkAsmStmt: gasm(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[j] = semGenericStmt(c, a.sons[j], flags, toBind)
a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind) a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind)
closeScope(c.tab) closeScope(c.tab)
of nkForStmt: of nkForStmt, nkParForStmt:
var L = sonsLen(n) var L = sonsLen(n)
openScope(c.tab) openScope(c.tab)
n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind) n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind)

View file

@ -465,6 +465,10 @@ proc semFor(c: PContext, n: PNode): PNode =
else: else:
GlobalError(n.sons[length - 2].info, errIteratorExpected) GlobalError(n.sons[length - 2].info, errIteratorExpected)
elif call.sons[0].sym.magic != mNone: elif call.sons[0].sym.magic != mNone:
if call.sons[0].sym.magic == mOmpParFor:
result = semForVars(c, n)
result.kind = nkParForStmt
else:
result = semForFields(c, n, call.sons[0].sym.magic) result = semForFields(c, n, call.sons[0].sym.magic)
else: else:
result = semForVars(c, n) result = semForVars(c, n)
@ -889,7 +893,7 @@ proc SemStmt(c: PContext, n: PNode): PNode =
of nkWhileStmt: result = semWhile(c, n) of nkWhileStmt: result = semWhile(c, n)
of nkTryStmt: result = semTry(c, n) of nkTryStmt: result = semTry(c, n)
of nkBreakStmt, nkContinueStmt: result = semBreakOrContinue(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 nkCaseStmt: result = semCase(c, n)
of nkReturnStmt: result = semReturn(c, n) of nkReturnStmt: result = semReturn(c, n)
of nkAsmStmt: result = semAsm(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 = proc hasContinue(n: PNode): bool =
case n.kind case n.kind
of nkEmpty..nkNilLit, nkForStmt, nkWhileStmt: nil of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: nil
of nkContinueStmt: result = true of nkContinueStmt: result = true
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
@ -659,6 +659,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
inc c.inLoop inc c.inLoop
result = transformFor(c, n) result = transformFor(c, n)
dec c.inLoop dec c.inLoop
of nkParForStmt:
inc c.inLoop
result = transformSons(c, n)
dec c.inLoop
of nkCaseStmt: result = transformCase(c, n) of nkCaseStmt: result = transformCase(c, n)
of nkContinueStmt: of nkContinueStmt:
result = PTransNode(newNode(nkBreakStmt)) result = PTransNode(newNode(nkBreakStmt))

View file

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

View file

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

View file

@ -1200,6 +1200,15 @@ iterator `..`*[S, T](a: S, b: T): T {.inline.} =
yield res yield res
inc 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: int): int {.magic: "MinI", noSideEffect.}
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.} proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
proc min*(x, y: int16): int16 {.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 ``system.clamp`` to limit a value within an interval ``[a, b]``.
- Added ``strutils.continuesWith``. - Added ``strutils.continuesWith``.
- Added ``system.getStackTrace``. - Added ``system.getStackTrace``.
- Added ``system.||`` for parallel for loop support.
- The GC supports (soft) realtime systems via ``GC_setMaxPause`` - The GC supports (soft) realtime systems via ``GC_setMaxPause``
and ``GC_step`` procs. and ``GC_step`` procs.
@ -84,6 +85,7 @@ Compiler Additions
option or pragma. option or pragma.
- The compiler now generates marker procs that the GC can use instead of RTTI. - The compiler now generates marker procs that the GC can use instead of RTTI.
This speeds up the GC quite a bit. This speeds up the GC quite a bit.
- The compiler now supports OpenMP's parallel for loop.
Language Additions Language Additions