linearScanEnd pragma; string case statement optimization

This commit is contained in:
Araq 2011-03-14 23:57:41 +01:00
commit 8d734244b1
26 changed files with 537 additions and 252 deletions

View file

@ -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()