linearScanEnd pragma; string case statement optimization
This commit is contained in:
parent
6850fb73c1
commit
8d734244b1
26 changed files with 537 additions and 252 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2009 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -10,21 +10,58 @@
|
|||
# This module declares some helpers for the C code generator.
|
||||
|
||||
import
|
||||
ast, astalgo, ropes, lists, nhashes, strutils, types, msgs
|
||||
ast, astalgo, ropes, lists, nhashes, strutils, types, msgs, wordrecg,
|
||||
platform
|
||||
|
||||
proc toCChar*(c: Char): string
|
||||
proc makeCString*(s: string): PRope
|
||||
proc makeLLVMString*(s: string): PRope
|
||||
proc TableGetType*(tab: TIdTable, key: PType): PObject
|
||||
proc GetUniqueType*(key: PType): PType
|
||||
# implementation
|
||||
proc whichPragma*(n: PNode): TSpecialWord =
|
||||
var key = if n.kind == nkExprColonExpr: n.sons[0] else: n
|
||||
if key.kind == nkIdent: result = whichKeyword(key.ident)
|
||||
|
||||
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
||||
case n.kind
|
||||
of nkStmtList:
|
||||
for i in 0 .. < n.len:
|
||||
result = getPragmaStmt(n[i], w)
|
||||
if result != nil: break
|
||||
of nkPragma:
|
||||
for i in 0 .. < n.len:
|
||||
if whichPragma(n[i]) == w: return n[i]
|
||||
else: nil
|
||||
|
||||
proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool =
|
||||
result = getPragmaStmt(n, w) != nil
|
||||
|
||||
proc hashString*(s: string): biggestInt =
|
||||
# has to be the same algorithm as system.hashString!
|
||||
if CPU[targetCPU].bit == 64:
|
||||
# we have to use the same bitwidth
|
||||
# as the target CPU
|
||||
var b = 0'i64
|
||||
for i in countup(0, len(s) - 1):
|
||||
b = b +% Ord(s[i])
|
||||
b = b +% `shl`(b, 10)
|
||||
b = b xor `shr`(b, 6)
|
||||
b = b +% `shl`(b, 3)
|
||||
b = b xor `shr`(b, 11)
|
||||
b = b +% `shl`(b, 15)
|
||||
result = b
|
||||
else:
|
||||
var a = 0'i32
|
||||
for i in countup(0, len(s) - 1):
|
||||
a = a +% Ord(s[i]).int32
|
||||
a = a +% `shl`(a, 10'i32)
|
||||
a = a xor `shr`(a, 6'i32)
|
||||
a = a +% `shl`(a, 3'i32)
|
||||
a = a xor `shr`(a, 11'i32)
|
||||
a = a +% `shl`(a, 15'i32)
|
||||
result = a
|
||||
|
||||
var gTypeTable: array[TTypeKind, TIdTable]
|
||||
|
||||
proc initTypeTables() =
|
||||
for i in countup(low(TTypeKind), high(TTypeKind)): InitIdTable(gTypeTable[i])
|
||||
|
||||
proc GetUniqueType(key: PType): PType =
|
||||
proc GetUniqueType*(key: PType): PType =
|
||||
var
|
||||
t: PType
|
||||
k: TTypeKind
|
||||
|
|
@ -32,33 +69,7 @@ proc GetUniqueType(key: PType): PType =
|
|||
result = key
|
||||
if key == nil: return
|
||||
k = key.kind
|
||||
case k #
|
||||
# case key.Kind of
|
||||
# tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||
# tyInt..tyFloat128, tyProc, tyAnyEnum: begin end;
|
||||
# tyNone, tyForward:
|
||||
# InternalError('GetUniqueType: ' + typeToString(key));
|
||||
# tyGenericParam, tyGeneric, tyAbstract, tySequence,
|
||||
# tyOpenArray, tySet, tyVar, tyRef, tyPtr, tyArrayConstr,
|
||||
# tyArray, tyTuple, tyRange: begin
|
||||
# // we have to do a slow linear search because types may need
|
||||
# // to be compared by their structure:
|
||||
# if IdTableHasObjectAsKey(gTypeTable, key) then exit;
|
||||
# for h := 0 to high(gTypeTable.data) do begin
|
||||
# t := PType(gTypeTable.data[h].key);
|
||||
# if (t <> nil) and sameType(t, key) then begin result := t; exit end
|
||||
# end;
|
||||
# IdTablePut(gTypeTable, key, key);
|
||||
# end;
|
||||
# tyObject, tyEnum: begin
|
||||
# result := PType(IdTableGet(gTypeTable, key));
|
||||
# if result = nil then begin
|
||||
# IdTablePut(gTypeTable, key, key);
|
||||
# result := key;
|
||||
# end
|
||||
# end;
|
||||
# tyGenericInst, tyAbstract: result := GetUniqueType(lastSon(key));
|
||||
# end;
|
||||
case k
|
||||
of tyObject, tyEnum:
|
||||
result = PType(IdTableGet(gTypeTable[k], key))
|
||||
if result == nil:
|
||||
|
|
@ -78,7 +89,7 @@ proc GetUniqueType(key: PType): PType =
|
|||
return t
|
||||
IdTablePut(gTypeTable[k], key, key)
|
||||
|
||||
proc TableGetType(tab: TIdTable, key: PType): PObject =
|
||||
proc TableGetType*(tab: TIdTable, key: PType): PObject =
|
||||
var t: PType
|
||||
# returns nil if we need to declare this type
|
||||
result = IdTableGet(tab, key)
|
||||
|
|
@ -91,13 +102,13 @@ proc TableGetType(tab: TIdTable, key: PType): PObject =
|
|||
if sameType(t, key):
|
||||
return tab.data[h].val
|
||||
|
||||
proc toCChar(c: Char): string =
|
||||
proc toCChar*(c: Char): string =
|
||||
case c
|
||||
of '\0'..'\x1F', '\x80'..'\xFF': result = '\\' & toOctal(c)
|
||||
of '\'', '\"', '\\': result = '\\' & c
|
||||
else: result = $(c)
|
||||
|
||||
proc makeCString(s: string): PRope =
|
||||
proc makeCString*(s: string): PRope =
|
||||
# BUGFIX: We have to split long strings into many ropes. Otherwise
|
||||
# this could trigger an InternalError(). See the ropes module for
|
||||
# further information.
|
||||
|
|
@ -117,9 +128,8 @@ proc makeCString(s: string): PRope =
|
|||
add(res, '\"')
|
||||
app(result, toRope(res))
|
||||
|
||||
proc makeLLVMString(s: string): PRope =
|
||||
const
|
||||
MaxLineLength = 64
|
||||
proc makeLLVMString*(s: string): PRope =
|
||||
const MaxLineLength = 64
|
||||
var res: string
|
||||
result = nil
|
||||
res = "c\""
|
||||
|
|
@ -135,4 +145,4 @@ proc makeLLVMString(s: string): PRope =
|
|||
add(res, "\\00\"")
|
||||
app(result, toRope(res))
|
||||
|
||||
InitTypeTables()
|
||||
InitTypeTables()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue