unused constants are optimized away

This commit is contained in:
Araq
2011-11-22 18:48:00 +01:00
parent c8dda8cc6f
commit fedc69f61a
4 changed files with 47 additions and 39 deletions

View File

@@ -1674,7 +1674,7 @@ proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
expr(p, n.sons[i], arr)
proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) =
genConstPrototype(p.module, sym)
requestConstImpl(p, sym)
assert((sym.loc.r != nil) and (sym.loc.t != nil))
putLocIntoDest(p, d, sym.loc)

View File

@@ -68,16 +68,18 @@ proc genConstStmt(p: BProc, t: PNode) =
if sfFakeConst in c.flags:
genSingleVar(p, it)
elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and
c.ast.len != 0:
# generate the data:
fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown)
if sfImportc in c.flags:
appf(p.module.s[cfsData], "extern NIM_CONST $1 $2;$n",
[getTypeDesc(p.module, c.typ), c.loc.r])
else:
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, c.typ), c.loc.r, genConstExpr(p, c.ast)])
c.ast.len != 0:
if not emitLazily(c): requestConstImpl(p, c)
when false:
# generate the data:
fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown)
if sfImportc in c.flags:
appf(p.module.s[cfsData], "extern NIM_CONST $1 $2;$n",
[getTypeDesc(p.module, c.typ), c.loc.r])
else:
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, c.typ), c.loc.r, genConstExpr(p, c.ast)])
proc genIfStmt(p: BProc, n: PNode) =
#
# if (!expr1) goto L1;

View File

@@ -53,6 +53,10 @@ proc findPendingModule(m: BModule, s: PSym): BModule =
result = nil
#InternalError(s.info, "no pending module found for: " & s.name.s)
proc emitLazily(s: PSym): bool {.inline.} =
result = optDeadCodeElim in gGlobalOptions or
sfDeadCodeElim in getModule(s).flags
proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) =
result.k = k
result.s = s
@@ -82,11 +86,10 @@ proc useHeader(m: BModule, sym: PSym) =
proc cgsym(m: BModule, name: string): PRope
proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
var i, j, length, start, num: int
i = 0
length = len(frmt)
var i = 0
var length = len(frmt)
result = nil
num = 0
var num = 0
while i < length:
if frmt[i] == '$':
inc(i) # skip '$'
@@ -99,17 +102,17 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
app(result, args[num])
inc(num)
of '0'..'9':
j = 0
var j = 0
while true:
j = (j * 10) + Ord(frmt[i]) - ord('0')
inc(i)
if i >= length or not (frmt[i] in {'0'..'9'}): break
num = j
if j > high(args) + 1:
internalError("ropes: invalid format string $" & $(j))
app(result, args[j - 1])
internalError("ropes: invalid format string $" & $j)
app(result, args[j-1])
of 'n':
if not (optLineDir in gOptions): app(result, tnl)
if optLineDir notin gOptions: app(result, tnl)
inc(i)
of 'N':
app(result, tnl)
@@ -129,7 +132,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
j = (j * 10) + Ord(frmt[i]) - ord('0')
inc(i)
app(result, cgsym(m, args[j-1].ropeToStr))
start = i
var start = i
while i < length:
if frmt[i] != '$' and frmt[i] != '#': inc(i)
else: break
@@ -382,7 +385,7 @@ proc fixLabel(p: BProc, labl: TLabel) =
appf(p.s[cpsStmts], "$1: ;$n", [labl])
proc genVarPrototype(m: BModule, sym: PSym)
proc genConstPrototype(m: BModule, sym: PSym)
proc requestConstImpl(p: BProc, sym: PSym)
proc genProc(m: BModule, prc: PSym)
proc genStmts(p: BProc, t: PNode)
proc genProcPrototype(m: BModule, sym: PSym)
@@ -619,7 +622,25 @@ proc genProcNoForward(m: BModule, prc: PSym) =
var q = findPendingModule(m, prc)
if q != nil and not ContainsOrIncl(q.declaredThings, prc.id):
genProcAux(q, prc)
proc requestConstImpl(p: BProc, sym: PSym) =
var m = p.module
useHeader(m, sym)
if sym.loc.k == locNone:
fillLoc(sym.loc, locData, sym.typ, mangleName(sym), OnUnknown)
if lfNoDecl in sym.loc.Flags: return
# declare implementation:
var q = findPendingModule(m, sym)
if q != nil and not ContainsOrIncl(q.declaredThings, sym.id):
assert q.initProc.module == q
appf(q.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(q, sym.typ), sym.loc.r, genConstExpr(q.initProc, sym.ast)])
# declare header:
if q != m and not ContainsOrIncl(m.declaredThings, sym.id):
assert(sym.loc.r != nil)
appf(m.s[cfsData], "extern NIM_CONST $1 $2;$n",
[getTypeDesc(m, sym.loc.t), sym.loc.r])
proc genProc(m: BModule, prc: PSym) =
if sfBorrow in prc.flags: return
fillProcLoc(prc)
@@ -644,20 +665,6 @@ proc genVarPrototype(m: BModule, sym: PSym) =
if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile")
appf(m.s[cfsVars], " $1;$n", [sym.loc.r])
proc genConstPrototype(m: BModule, sym: PSym) =
useHeader(m, sym)
if sym.loc.k == locNone:
fillLoc(sym.loc, locData, sym.typ, mangleName(sym), OnUnknown)
if (lfNoDecl in sym.loc.Flags) or
ContainsOrIncl(m.declaredThings, sym.id):
return
if sym.owner.id != m.module.id:
# else we already have the symbol generated!
assert(sym.loc.r != nil)
appff(m.s[cfsData], "extern NIM_CONST $1 $2;$n",
"$1 = linkonce constant $2 zeroinitializer",
[getTypeDesc(m, sym.loc.t), sym.loc.r])
proc getFileHeader(cfilenoext: string): PRope =
if optCompileOnly in gGlobalOptions:
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &

View File

@@ -1,7 +1,6 @@
Version 0.8.14
==============
- optimize unused constants away (affected by HLO)
- fix thread tests
version 0.9.0
@@ -116,7 +115,8 @@ Low priority
- compilation cache:
- adapt thread var emulation to care about the new merge operation
- check for interface changes; if only the implemenation changes, no
need to recompile clients
need to recompile clients; er ... what about templates, macros or anything
that has inlining semantics?
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
@@ -147,7 +147,6 @@ Version 2
var x = myProc() # checks myProc() initializes every pointer explicitely
- the two other parsers
- generalized case statement (requires better transf)
- rethink the syntax: distinction between expr and stmt is unfortunate;
indentation handling is quite complex too; problem with exception handling