diff --git a/compiler/stz-compiler-main.stanza b/compiler/stz-compiler-main.stanza index 773a56178..29e592887 100644 --- a/compiler/stz-compiler-main.stanza +++ b/compiler/stz-compiler-main.stanza @@ -341,4 +341,4 @@ public defstruct CompilationResult : compiled-packages: Tuple binding-packages: Tuple package-stamps: Tuple - output-pkgs: Tuple \ No newline at end of file + output-pkgs: Tuple diff --git a/compiler/stz-config.stanza b/compiler/stz-config.stanza index 701f78b63..0acf1b578 100644 --- a/compiler/stz-config.stanza +++ b/compiler/stz-config.stanza @@ -69,6 +69,8 @@ defsyntax stanza-config : STANZA-MAX-COMPILER-HEAP-SIZE = sz defrule entry = (experimental = ?b:#bool!) : EXPERIMENTAL = b + defrule entry = (strip-stack-checks? = ?b:#bool!) : + STRIP-STACK-CHECKS? = b fail-if entry = () : PE(closest-info(), "Invalid configuration rule.") diff --git a/compiler/stz-params.stanza b/compiler/stz-params.stanza index d6ecb2d75..57955febb 100644 --- a/compiler/stz-params.stanza +++ b/compiler/stz-params.stanza @@ -20,6 +20,7 @@ public var OUTPUT-PLATFORM:Symbol = `platform public var STANZA-PKG-DIRS:List = List() public val STANZA-PROJ-FILES = Vector() public var EXPERIMENTAL:True|False = false +public var STRIP-STACK-CHECKS?:True|False = false ;====== Compiler Configuration ===== public var STANZA-MAX-COMPILER-HEAP-SIZE = 4L * 1024L * 1024L * 1024L diff --git a/compiler/stz-reg-alloc.stanza b/compiler/stz-reg-alloc.stanza index 96df04b2a..5a9149a05 100644 --- a/compiler/stz-reg-alloc.stanza +++ b/compiler/stz-reg-alloc.stanza @@ -200,6 +200,13 @@ defpackage stz/reg-alloc : import stz/basic-blocks with : prefix(Block) => Basic +;============================================================ +;=================== Parameters ============================= +;============================================================ + +;Size of smap which can be called without checking stack-size. +val SMALL-SMAP-SIZE = 16 + ;============================================================ ;===================== Driver =============================== ;============================================================ @@ -249,10 +256,10 @@ public defn allocate-registers (ins:VMFunction, emitter:CodeEmitter, backend:Bac print-prog() val smap = stack-map() - ;if print? : - ; println("==== Stack Map ====") - ; println(smap) - + ;; if print? : + ;; println("==== Stack Map ====") + ;; println(smap) + collapse-blocks() if print? : println("==== Collapse Blocks ====") @@ -356,6 +363,10 @@ public defstruct MethodDispatch <: Ins : amb?: Int|False with: (default => false) killed?: False|List with: (default => false, as-method => true) +public defstruct SectionMarker <: Ins : + marker: Symbol + killed?: False|List with: (default => false, as-method => true) + public defstruct Save <: Ins : x: Var @@ -616,6 +627,7 @@ defmethod print (o:OutputStream, i:Ins) : (i:Label) : "label %_" % [n(i)] (i:Goto) : "goto %_" % [n(i)] (i:Break) : "break %_ when %_(%,)" % [n(i), op(i), xs(i)] + (i:SectionMarker) : "section: %~" % [marker(i)] defmethod print (o:OutputStream, c:FnContext) : print{o, _} $ match(c) : @@ -655,6 +667,7 @@ defn do-defined (f: Var -> ?, e:Ins) : (e:Load) : f(x(e)) (e:Match) : false (e:MethodDispatch) : false + (e:SectionMarker) : false false defn do-used (gv: Var -> ?, e:Ins) : @@ -671,6 +684,7 @@ defn do-used (gv: Var -> ?, e:Ins) : (e:Load) : false (e:Match) : do(g, xs(e)) (e:MethodDispatch) : false + (e:SectionMarker) : false false defn used-vars (e:Ins) : @@ -716,6 +730,8 @@ defn reverse-sweep (e:Ins, define:Var -> ?, emit:Ins -> ?, use-var:Var -> ?) : do(use, xs(e)) (e:MethodDispatch) : emit(e) + (e:SectionMarker) : + emit(e) defn attach-killed (e:Ins, ks:List) : match(e) : @@ -728,6 +744,7 @@ defn attach-killed (e:Ins, ks:List) : (e:Branch) : Branch(op(e), xs(e), ks) (e:Match) : Match(dispatch?(e), type-lists(e), xs(e), ks, ns?(e)) (e:MethodDispatch) : MethodDispatch(multi(e), num-header-args(e), default?(e), amb?(e), ks) + (e:SectionMarker) : SectionMarker(marker(e), ks) ;============================================================ ;=================== Unique Labels ========================== @@ -942,6 +959,8 @@ defn load-instructions (function:VMFunc, backend:Backend) : push(Op(SaveCContextOp(), List(), List())) (e:CommentIns) : false + (e:SectionMarkerIns) : + push(SectionMarker(marker(e))) (e:UnreachableIns) : false val next = to-list $ @@ -1805,6 +1824,8 @@ defn register-assignment (blk:Block, b:Int, backend:Backend) : do(free-var, killed(e)) (e:MethodDispatch) : emit(e) + (e:SectionMarker) : + emit(e) (e:Op) : defn assign-prefs (pref:List -> Loc|List) : val ys* = map(annotate, ys(e)) @@ -2391,8 +2412,8 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : ;============== ;==== Body ==== ;============== - for e in ins(BLOCKS[0]) do : - ;println("//Assembling: %_" % [e]) + + defn emit (e:Ins) : match(e) : (e:Set) : match(y(e)) : @@ -2436,7 +2457,7 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : (t:ExtendStack) : val return-lbl = unique-id(stubs) E $ SetL(R0, LM(return-lbl)) - E $ SetL(R1, INT(size(stackmap) + 8)) + E $ SetL(R1, INT(size(stackmap) + (8 + SMALL-SMAP-SIZE))) E $ asm-Goto(M(extend-stack(stubs))) E $ asm-Label(return-lbl) (t:CollectGarbage) : @@ -2459,10 +2480,10 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : ;Save RSP E $ StoreL(M(stack-pointer(stubs)), RSP) - + ;Restore the C context: E $ LoadL(RSP, M(saved-c-rsp(stubs))) - + ;Call C function with right convention val num-float-args = for y in ys(e) count : reg?(y as Var) is FReg E $ SubL(RSP, RSP, INT(frame-size(num-mem-args(t), backend(stubs)))) @@ -2498,7 +2519,7 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : E $ LoadL(TMP2, F, size-offset) E $ AddL(TMP, TMP, TMP2) E $ StoreL(M(stack-limit(stubs)), TMP) - + E $ LoadL(TMP, F, pc-offset) E $ asm-Goto(TMP) E $ asm-Label(lbl, info(t)) @@ -2629,7 +2650,7 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : defn cmp-stack-limit (le-op:asm-Op) : val TMP = R0 val TMP2 = R1 - E $ AddL(TMP, RSP, INT(size(stackmap) + 8)) + E $ AddL(TMP, RSP, INT(size(stackmap) + (8 + SMALL-SMAP-SIZE))) E $ LoadL(TMP2, M(stack-limit(stubs))) E $ BreakL(label-table[n(e)], le-op, TMP, TMP2) defn cmp-heap-limit (le-op:asm-Op) : @@ -2681,6 +2702,22 @@ defn assemble (emitter:CodeEmitter, stackmap:StackMap, stubs:AsmStubs) : val amb-branch = label-table[amb(e)] E $ asm-MethodDispatch(multi(e), num-header-args(e), no-branch, amb-branch) (e) : fatal("Not yet implemented: %_" % [e]) + + ;When size(stackmap) <= SMALL-SMAP-SIZE and no non-tail-calls in body: + val stripping-preamble?:True|False = if size(stackmap) <= SMALL-SMAP-SIZE and STRIP-STACK-CHECKS? : + for e in ins(BLOCKS[0]) any? : + match(e:Call) : type(e) is-not StanzaTCall + ;Strip ins between preamble SectionMarkerIns'. + var stripping?:True|False = false + for e in ins(BLOCKS[0]) do : + if stripping? : + match(e:SectionMarker) : + if marker(e) == `preamble: stripping? = false + else : + match(e:SectionMarker) : + stripping? = stripping-preamble? and (marker(e) == `preamble) + else : + emit(e) defn asm-type (x:Imm) : to-asm-type(type(x)) @@ -2757,4 +2794,4 @@ defn to-asm-op (op:VMOp) -> asm-Op : ;============================================================ defn keys (xs:Vector>) : to-list(seq(key,xs)) -defn values (xs:Vector>) : to-list(seq(value,xs)) \ No newline at end of file +defn values (xs:Vector>) : to-list(seq(value,xs)) diff --git a/compiler/stz-vm-ir.stanza b/compiler/stz-vm-ir.stanza index ea7ab4aa9..3bd09c0f4 100644 --- a/compiler/stz-vm-ir.stanza +++ b/compiler/stz-vm-ir.stanza @@ -260,7 +260,10 @@ public defstruct LiveIns <: VMIns : xs: Tuple public defstruct CommentIns <: VMIns : message: String +public defstruct SectionMarkerIns <: VMIns : + marker: Symbol public defstruct UnreachableIns <: VMIns + public deftype VMValue : Char <: VMValue @@ -676,6 +679,7 @@ defmethod print (o:OutputStream, i:VMIns) : (i:RecordLiveIns) : P $ "live (%,)" % [live(i)] (i:LiveIns) : P $ "mark-live (%,)" % [xs(i)] (i:CommentIns) : P $ "comment: %~" % [message(i)] + (i:SectionMarkerIns) : P $ "section: %~" % [marker(i)] (i:MatchIns) : print(o, "match(%,) :" % [ys(i)]) val o2 = IndentedStream(o) @@ -828,6 +832,7 @@ defsyntax vmcode : defrule ins = (live (?xs:#local ...)) : RecordLiveIns(to-tuple(xs)) defrule ins = (mark-live (?xs:#imm! ...)) : LiveIns(to-tuple(xs)) defrule ins = (comment: ?x:#string!) : CommentIns(x) + defrule ins = (section: ?x:#symbol!) : SectionMarkerIns(x) defrule ins = (match(?ys:#imm! ...) : (?bs:#vmbranch ... ?d:#defaultbranch)) : MatchIns(to-tuple(ys), to-tuple(bs), d) defrule ins = (dispatch(?ys:#imm! ...) : (?bs:#vmbranch ... ?d:#defaultbranch ?a:#ambbranch)) : DispatchIns(to-tuple(ys), to-tuple(bs), d, a) @@ -1057,4 +1062,4 @@ public defn dump (p:VMPackage, suffix:String|False) : dump(p, ".", suffix) public defn dump (p:VMPackage) : - dump(p, false) \ No newline at end of file + dump(p, false) diff --git a/compiler/stz-vm-normalize.stanza b/compiler/stz-vm-normalize.stanza index 86736db51..8c55d9118 100644 --- a/compiler/stz-vm-normalize.stanza +++ b/compiler/stz-vm-normalize.stanza @@ -70,11 +70,13 @@ defn normalize (f0:VMFunction, databuffer:DataBuffer, backend:Backend, iotable:I ;Check stack extension val has-stack-lbl = make-label(buffer) val no-stack-lbl = make-label(buffer) + load-instruction(SectionMarkerIns(`preamble)) load-instruction(Branch0Ins(has-stack-lbl, no-stack-lbl, HasStackOp())) load-instruction(LabelIns(no-stack-lbl)) load-instruction(ExtendStackIns()) load-instruction(GotoIns(has-stack-lbl)) load-instruction(LabelIns(has-stack-lbl)) + load-instruction(SectionMarkerIns(`preamble)) ;Get arguments val arg-rec = arg-extern-records(buffer, args(f), c-rsp-arg, backend) @@ -133,11 +135,13 @@ defn normalize (f0:VMFunction, databuffer:DataBuffer, backend:Backend, iotable:I ;Check stack extension val has-stack-lbl = make-label(buffer) val no-stack-lbl = make-label(buffer) + load-instruction(SectionMarkerIns(`preamble)) load-instruction(Branch0Ins(has-stack-lbl, no-stack-lbl, HasStackOp())) load-instruction(LabelIns(no-stack-lbl)) load-instruction(ExtendStackIns()) load-instruction(GotoIns(has-stack-lbl)) load-instruction(LabelIns(has-stack-lbl)) + load-instruction(SectionMarkerIns(`preamble)) ;Get arguments within ret = normalize(ret-records(buffer, args(f), backend)) : @@ -1438,4 +1442,4 @@ defn InsBuffer (function:VMFunction) : else : i def-table[n] = VMDef(n, t) Local(n) - \ No newline at end of file +