unused constants are optimized away

This commit is contained in:
Araq 2011-11-22 18:48:00 +01:00
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) expr(p, n.sons[i], arr)
proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) = 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)) assert((sym.loc.r != nil) and (sym.loc.t != nil))
putLocIntoDest(p, d, sym.loc) putLocIntoDest(p, d, sym.loc)

View file

@ -69,6 +69,8 @@ proc genConstStmt(p: BProc, t: PNode) =
genSingleVar(p, it) genSingleVar(p, it)
elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and
c.ast.len != 0: c.ast.len != 0:
if not emitLazily(c): requestConstImpl(p, c)
when false:
# generate the data: # generate the data:
fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown) fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown)
if sfImportc in c.flags: if sfImportc in c.flags:

View file

@ -53,6 +53,10 @@ proc findPendingModule(m: BModule, s: PSym): BModule =
result = nil result = nil
#InternalError(s.info, "no pending module found for: " & s.name.s) #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) = proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) =
result.k = k result.k = k
result.s = s result.s = s
@ -82,11 +86,10 @@ proc useHeader(m: BModule, sym: PSym) =
proc cgsym(m: BModule, name: string): PRope proc cgsym(m: BModule, name: string): PRope
proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope = proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
var i, j, length, start, num: int var i = 0
i = 0 var length = len(frmt)
length = len(frmt)
result = nil result = nil
num = 0 var num = 0
while i < length: while i < length:
if frmt[i] == '$': if frmt[i] == '$':
inc(i) # skip '$' inc(i) # skip '$'
@ -99,17 +102,17 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
app(result, args[num]) app(result, args[num])
inc(num) inc(num)
of '0'..'9': of '0'..'9':
j = 0 var j = 0
while true: while true:
j = (j * 10) + Ord(frmt[i]) - ord('0') j = (j * 10) + Ord(frmt[i]) - ord('0')
inc(i) inc(i)
if i >= length or not (frmt[i] in {'0'..'9'}): break if i >= length or not (frmt[i] in {'0'..'9'}): break
num = j num = j
if j > high(args) + 1: if j > high(args) + 1:
internalError("ropes: invalid format string $" & $(j)) internalError("ropes: invalid format string $" & $j)
app(result, args[j-1]) app(result, args[j-1])
of 'n': of 'n':
if not (optLineDir in gOptions): app(result, tnl) if optLineDir notin gOptions: app(result, tnl)
inc(i) inc(i)
of 'N': of 'N':
app(result, tnl) 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') j = (j * 10) + Ord(frmt[i]) - ord('0')
inc(i) inc(i)
app(result, cgsym(m, args[j-1].ropeToStr)) app(result, cgsym(m, args[j-1].ropeToStr))
start = i var start = i
while i < length: while i < length:
if frmt[i] != '$' and frmt[i] != '#': inc(i) if frmt[i] != '$' and frmt[i] != '#': inc(i)
else: break else: break
@ -382,7 +385,7 @@ proc fixLabel(p: BProc, labl: TLabel) =
appf(p.s[cpsStmts], "$1: ;$n", [labl]) appf(p.s[cpsStmts], "$1: ;$n", [labl])
proc genVarPrototype(m: BModule, sym: PSym) 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 genProc(m: BModule, prc: PSym)
proc genStmts(p: BProc, t: PNode) proc genStmts(p: BProc, t: PNode)
proc genProcPrototype(m: BModule, sym: PSym) proc genProcPrototype(m: BModule, sym: PSym)
@ -620,6 +623,24 @@ proc genProcNoForward(m: BModule, prc: PSym) =
if q != nil and not ContainsOrIncl(q.declaredThings, prc.id): if q != nil and not ContainsOrIncl(q.declaredThings, prc.id):
genProcAux(q, prc) 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) = proc genProc(m: BModule, prc: PSym) =
if sfBorrow in prc.flags: return if sfBorrow in prc.flags: return
fillProcLoc(prc) fillProcLoc(prc)
@ -644,20 +665,6 @@ proc genVarPrototype(m: BModule, sym: PSym) =
if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile") if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile")
appf(m.s[cfsVars], " $1;$n", [sym.loc.r]) 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 = proc getFileHeader(cfilenoext: string): PRope =
if optCompileOnly in gGlobalOptions: if optCompileOnly in gGlobalOptions:
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" & result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &

View file

@ -1,7 +1,6 @@
Version 0.8.14 Version 0.8.14
============== ==============
- optimize unused constants away (affected by HLO)
- fix thread tests - fix thread tests
version 0.9.0 version 0.9.0
@ -116,7 +115,8 @@ Low priority
- compilation cache: - compilation cache:
- adapt thread var emulation to care about the new merge operation - adapt thread var emulation to care about the new merge operation
- check for interface changes; if only the implemenation changes, no - 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 - 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 var x = myProc() # checks myProc() initializes every pointer explicitely
- the two other parsers
- generalized case statement (requires better transf) - generalized case statement (requires better transf)
- rethink the syntax: distinction between expr and stmt is unfortunate; - rethink the syntax: distinction between expr and stmt is unfortunate;
indentation handling is quite complex too; problem with exception handling indentation handling is quite complex too; problem with exception handling