compiler.cfg.*: even more compiler docs
parent
997f95196c
commit
c3ca8bd859
|
@ -4,7 +4,7 @@ IN: compiler.cfg.def-use
|
||||||
|
|
||||||
HELP: compute-insns
|
HELP: compute-insns
|
||||||
{ $values { "cfg" cfg } }
|
{ $values { "cfg" cfg } }
|
||||||
{ $description "Computes a mapping from vregs to the instructions that define them and store the result in the " { $link insns } " variable." } ;
|
{ $description "Computes a mapping from vregs to the instructions that define them and store the result in the " { $link insns } " variable. The " { $link insn-of } " word can then be used to access the assoc." } ;
|
||||||
|
|
||||||
HELP: defs-vregs
|
HELP: defs-vregs
|
||||||
{ $values { "insn" insn } { "seq" sequence } }
|
{ $values { "insn" insn } { "seq" sequence } }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: alien arrays assocs classes compiler.cfg compiler.cfg.value-numbering
|
USING: alien arrays assocs classes compiler.cfg compiler.cfg.ssa.destruction
|
||||||
compiler.codegen.gc-maps cpu.architecture help.markup help.syntax kernel
|
compiler.cfg.value-numbering compiler.codegen.gc-maps cpu.architecture
|
||||||
layouts sequences slots.private system ;
|
help.markup help.syntax kernel layouts sequences slots.private system ;
|
||||||
IN: compiler.cfg.instructions
|
IN: compiler.cfg.instructions
|
||||||
|
|
||||||
HELP: ##alien-invoke
|
HELP: ##alien-invoke
|
||||||
|
@ -112,6 +112,13 @@ HELP: ##mul-vector
|
||||||
HELP: ##no-tco
|
HELP: ##no-tco
|
||||||
{ $class-description "A dummy instruction that simply inhibits TCO." } ;
|
{ $class-description "A dummy instruction that simply inhibits TCO." } ;
|
||||||
|
|
||||||
|
HELP: ##parallel-copy
|
||||||
|
{ $class-description "An instruction for performing multiple copies. It allows for optimizations or (or prunings) if more than one source or destination vreg is the same. They are transformed into " { $link ##copy } " instructions in " { $link destruct-ssa } ". It has the following slots:"
|
||||||
|
{ $table
|
||||||
|
{ { $slot "values" } { "An assoc mapping source vregs to destinations." } }
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
HELP: ##peek
|
HELP: ##peek
|
||||||
{ $class-description
|
{ $class-description
|
||||||
"Copies a value from a stack location to a machine register."
|
"Copies a value from a stack location to a machine register."
|
||||||
|
@ -192,7 +199,15 @@ HELP: ##store-memory-imm
|
||||||
{ $class-description "Instruction that copies an 8 byte value from a XMM register to a memory location addressed by a normal register. This instruction is often turned into a cheaper " { $link ##store-memory } " instruction in the " { $link value-numbering } " pass." } ;
|
{ $class-description "Instruction that copies an 8 byte value from a XMM register to a memory location addressed by a normal register. This instruction is often turned into a cheaper " { $link ##store-memory } " instruction in the " { $link value-numbering } " pass." } ;
|
||||||
|
|
||||||
HELP: ##vector>scalar
|
HELP: ##vector>scalar
|
||||||
{ $class-description "This instruction is very similar to " { $link ##copy } "." }
|
{ $class-description
|
||||||
|
"This instruction is very similar to " { $link ##copy } "."
|
||||||
|
{ $table
|
||||||
|
{ { $slot "dst" } { "destination vreg" } }
|
||||||
|
{ { $slot "src" } { "source vreg" } }
|
||||||
|
{ { $slot "rep" } { "representation for the source vreg" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ $notes "The two vregs must not necessarily share the same representation." }
|
||||||
{ $see-also %vector>scalar } ;
|
{ $see-also %vector>scalar } ;
|
||||||
|
|
||||||
HELP: ##write-barrier
|
HELP: ##write-barrier
|
||||||
|
@ -258,6 +273,7 @@ $nl
|
||||||
"Instruction classes for moving values around:"
|
"Instruction classes for moving values around:"
|
||||||
{ $subsections
|
{ $subsections
|
||||||
##copy
|
##copy
|
||||||
|
##parallel-copy
|
||||||
##peek
|
##peek
|
||||||
##reload
|
##reload
|
||||||
##replace
|
##replace
|
||||||
|
@ -316,7 +332,7 @@ $nl
|
||||||
##load-integer
|
##load-integer
|
||||||
##load-reference
|
##load-reference
|
||||||
}
|
}
|
||||||
"Floating point instructions:"
|
"Floating point SIMD instructions:"
|
||||||
{ $subsections
|
{ $subsections
|
||||||
##add-float
|
##add-float
|
||||||
##div-float
|
##div-float
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
USING: compiler.cfg.instructions compiler.tree help.markup help.syntax
|
||||||
|
math.vectors ;
|
||||||
|
IN: compiler.cfg.intrinsics.simd
|
||||||
|
|
||||||
|
HELP: emit-simd-v+
|
||||||
|
{ $values { "node" node } }
|
||||||
|
{ $description "Emits instructions for SIMD vector addition." }
|
||||||
|
{ $see-also ##add-vector v+ } ;
|
|
@ -1,6 +1,7 @@
|
||||||
USING: assocs compiler.cfg compiler.cfg.instructions
|
USING: assocs compiler.cfg compiler.cfg.instructions
|
||||||
compiler.cfg.linear-scan.live-intervals compiler.cfg.registers heaps help.markup
|
compiler.cfg.linear-scan.live-intervals
|
||||||
help.syntax math ;
|
compiler.cfg.linear-scan.allocation.state compiler.cfg.liveness
|
||||||
|
compiler.cfg.registers heaps help.markup help.syntax math ;
|
||||||
IN: compiler.cfg.linear-scan.assignment
|
IN: compiler.cfg.linear-scan.assignment
|
||||||
|
|
||||||
HELP: add-pending
|
HELP: add-pending
|
||||||
|
@ -16,6 +17,10 @@ HELP: assign-gc-roots
|
||||||
{ $values { "gc-map" gc-map } }
|
{ $values { "gc-map" gc-map } }
|
||||||
{ $description "Assigns spill slots for all gc roots in a gc map." } ;
|
{ $description "Assigns spill slots for all gc roots in a gc map." } ;
|
||||||
|
|
||||||
|
HELP: assign-registers-in-block
|
||||||
|
{ $values { "bb" basic-block } }
|
||||||
|
{ $description "Assigns registers and also inserts " { $link ##reload } " and " { $link ##spill } " instructions." } ;
|
||||||
|
|
||||||
HELP: assign-registers-in-insn
|
HELP: assign-registers-in-insn
|
||||||
{ $values { "insn" insn } }
|
{ $values { "insn" insn } }
|
||||||
{ $description "Assigns physical registers and spill slots for the virtual registers used by the instruction." } ;
|
{ $description "Assigns physical registers and spill slots for the virtual registers used by the instruction." } ;
|
||||||
|
@ -24,7 +29,7 @@ HELP: machine-edge-live-ins
|
||||||
{ $var-description "Mapping from basic blocks to predecessors to values which are live on a particular incoming edge." } ;
|
{ $var-description "Mapping from basic blocks to predecessors to values which are live on a particular incoming edge." } ;
|
||||||
|
|
||||||
HELP: machine-live-ins
|
HELP: machine-live-ins
|
||||||
{ $var-description "Mapping from basic blocks to values which are live at the start on all incoming CFG edges." } ;
|
{ $var-description "Mapping from basic blocks to values which are live at the start on all incoming CFG edges. It's like " { $link live-ins } " except the registers are physical instead of virtual." } ;
|
||||||
|
|
||||||
HELP: machine-live-outs
|
HELP: machine-live-outs
|
||||||
{ $var-description "Mapping from " { $link basic-block } " to an " { $link assoc } " of pairs which are the values that are live at the end. The keys of the pairs are virtual registers and the values are either real registers or spill slots." } ;
|
{ $var-description "Mapping from " { $link basic-block } " to an " { $link assoc } " of pairs which are the values that are live at the end. The keys of the pairs are virtual registers and the values are either real registers or spill slots." } ;
|
||||||
|
@ -37,10 +42,10 @@ HELP: unhandled-intervals
|
||||||
{ $var-description { $link min-heap } " of live intervals which still need a register allocation." } ;
|
{ $var-description { $link min-heap } " of live intervals which still need a register allocation." } ;
|
||||||
|
|
||||||
HELP: vreg>reg
|
HELP: vreg>reg
|
||||||
{ $values { "vreg" "virtual register" } { "reg" "register" } }
|
{ $values { "vreg" "virtual register" } { "reg/spill-slot" "a register or a spill slot" } }
|
||||||
{ $description "If a live vreg is not in the pending set, then it must have been spilled." }
|
{ $description "Translates a virtual register to a physical one. If the vreg is not in the pending set, then it must have been spilled and its spill slot is returned." }
|
||||||
{ $errors "Can throw a " { $link bad-vreg } " error." }
|
{ $errors "Can throw a " { $link bad-vreg } " error if the vreg is not in the " { $link pending-interval-assoc } " and also doesn't have a spill slot registered." }
|
||||||
{ $see-also pending-interval-assoc } ;
|
{ $see-also lookup-spill-slot pending-interval-assoc } ;
|
||||||
|
|
||||||
HELP: vregs>regs
|
HELP: vregs>regs
|
||||||
{ $values { "vregs" "a sequence of virtual registers" } { "assoc" assoc } }
|
{ $values { "vregs" "a sequence of virtual registers" } { "assoc" assoc } }
|
||||||
|
@ -53,7 +58,12 @@ HELP: vreg>spill-slot
|
||||||
ARTICLE: "compiler.cfg.linear-scan.assignment" "Assigning registers to live intervals"
|
ARTICLE: "compiler.cfg.linear-scan.assignment" "Assigning registers to live intervals"
|
||||||
"The " { $vocab-link "compiler.cfg.linear-scan.assignment" } " assigns registers to live intervals." $nl
|
"The " { $vocab-link "compiler.cfg.linear-scan.assignment" } " assigns registers to live intervals." $nl
|
||||||
"Pending intervals:"
|
"Pending intervals:"
|
||||||
{ $subsections add-pending pending-interval-assoc remove-pending }
|
{ $subsections
|
||||||
|
activate-interval
|
||||||
|
add-pending
|
||||||
|
pending-interval-assoc
|
||||||
|
remove-pending
|
||||||
|
}
|
||||||
"Vreg transformations:"
|
"Vreg transformations:"
|
||||||
{ $subsections vreg>reg vreg>spill-slot vregs>regs } ;
|
{ $subsections vreg>reg vreg>spill-slot vregs>regs } ;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ SYMBOL: pending-interval-assoc
|
||||||
: remove-pending ( live-interval -- )
|
: remove-pending ( live-interval -- )
|
||||||
vreg>> pending-interval-assoc get delete-at ;
|
vreg>> pending-interval-assoc get delete-at ;
|
||||||
|
|
||||||
:: vreg>reg ( vreg -- reg )
|
:: vreg>reg ( vreg -- reg/spill-slot )
|
||||||
vreg leader :> leader
|
vreg leader :> leader
|
||||||
leader pending-interval-assoc get at* [
|
leader pending-interval-assoc get at* [
|
||||||
drop leader vreg rep-of lookup-spill-slot
|
drop leader vreg rep-of lookup-spill-slot
|
||||||
|
@ -63,14 +63,6 @@ SYMBOL: machine-live-outs
|
||||||
: compute-live-out ( bb -- )
|
: compute-live-out ( bb -- )
|
||||||
[ live-out keys vregs>regs ] keep machine-live-outs get set-at ;
|
[ live-out keys vregs>regs ] keep machine-live-outs get set-at ;
|
||||||
|
|
||||||
: init-assignment ( live-intervals -- )
|
|
||||||
[ [ start>> ] map ] keep zip >min-heap unhandled-intervals set
|
|
||||||
<min-heap> pending-interval-heap set
|
|
||||||
H{ } clone pending-interval-assoc set
|
|
||||||
H{ } clone machine-live-ins set
|
|
||||||
H{ } clone machine-edge-live-ins set
|
|
||||||
H{ } clone machine-live-outs set ;
|
|
||||||
|
|
||||||
: heap-pop-while ( heap quot: ( key -- ? ) -- values )
|
: heap-pop-while ( heap quot: ( key -- ? ) -- values )
|
||||||
'[ dup heap-empty? [ f f ] [ dup heap-peek @ ] if ]
|
'[ dup heap-empty? [ f f ] [ dup heap-peek @ ] if ]
|
||||||
[ over heap-pop* ] produce 2nip ; inline
|
[ over heap-pop* ] produce 2nip ; inline
|
||||||
|
@ -146,8 +138,17 @@ M: insn assign-registers-in-insn drop ;
|
||||||
] each
|
] each
|
||||||
] V{ } make
|
] V{ } make
|
||||||
] change-instructions drop
|
] change-instructions drop
|
||||||
|
|
||||||
bb compute-live-out ;
|
bb compute-live-out ;
|
||||||
|
|
||||||
|
: init-assignment ( live-intervals -- )
|
||||||
|
[ [ start>> ] map ] keep zip >min-heap unhandled-intervals set
|
||||||
|
<min-heap> pending-interval-heap set
|
||||||
|
H{ } clone pending-interval-assoc set
|
||||||
|
H{ } clone machine-live-ins set
|
||||||
|
H{ } clone machine-edge-live-ins set
|
||||||
|
H{ } clone machine-live-outs set ;
|
||||||
|
|
||||||
: assign-registers ( cfg live-intervals -- )
|
: assign-registers ( cfg live-intervals -- )
|
||||||
init-assignment
|
init-assignment
|
||||||
linearization-order [ kill-block?>> not ] filter
|
linearization-order [ kill-block?>> not ] filter
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
USING: compiler.cfg.instructions help.markup help.syntax ;
|
USING: compiler.cfg compiler.cfg.instructions
|
||||||
|
compiler.cfg.linear-scan.allocation cpu.architecture help.markup help.syntax
|
||||||
|
math sequences ;
|
||||||
IN: compiler.cfg.linear-scan.live-intervals
|
IN: compiler.cfg.linear-scan.live-intervals
|
||||||
|
|
||||||
HELP: live-intervals
|
|
||||||
{ $var-description "Mapping from vreg to " { $link live-interval-state } "." } ;
|
|
||||||
|
|
||||||
HELP: sync-point
|
|
||||||
{ $class-description "A location where all registers have to be spilled. It has the following slots:"
|
|
||||||
{ $table
|
|
||||||
{ { $slot "n" } { "Set from an instructions sequence number." } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{ $see-also insn } ;
|
|
||||||
|
|
||||||
HELP: live-interval-state
|
|
||||||
{ $class-description "A class encoding the \"liveness\" of a virtual register." } ;
|
|
||||||
|
|
||||||
HELP: <live-interval>
|
HELP: <live-interval>
|
||||||
{ $values
|
{ $values
|
||||||
{ "vreg" "virtual register" }
|
{ "vreg" "virtual register" }
|
||||||
|
@ -22,3 +10,57 @@ HELP: <live-interval>
|
||||||
{ "live-interval" live-interval-state }
|
{ "live-interval" live-interval-state }
|
||||||
}
|
}
|
||||||
{ $description "Creates a new live interval for a virtual register. Initially the range is empty." } ;
|
{ $description "Creates a new live interval for a virtual register. Initially the range is empty." } ;
|
||||||
|
|
||||||
|
HELP: block-from
|
||||||
|
{ $values { "bb" basic-block } { "n" integer } }
|
||||||
|
{ $description "The instruction number immediately preceeding this block." } ;
|
||||||
|
|
||||||
|
HELP: finish-live-intervals
|
||||||
|
{ $values { "live-intervals" sequence } { "seq" sequence } }
|
||||||
|
{ $description "Since live intervals are computed in a backward order, we have to reverse some sequences, and compute the start and end." } ;
|
||||||
|
|
||||||
|
HELP: live-interval-state
|
||||||
|
{ $class-description "A class encoding the \"liveness\" of a virtual register. It has the following slots:"
|
||||||
|
{ $table
|
||||||
|
{ { $slot "vreg" } { "The vreg this live interval state is bound to." } }
|
||||||
|
{
|
||||||
|
{ $slot "reg" }
|
||||||
|
{ "The allocated register, set in the " { $link allocate-registers } " step." }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
{ $slot "spill-to" }
|
||||||
|
{ { $link spill-slot } " to use for spilling, if it needs to be spilled." }
|
||||||
|
}
|
||||||
|
{ { $slot "start" } { "Earliest insn# where the interval is live." } }
|
||||||
|
{ { $slot "end" } { "Latest insn# where the interval is live." } }
|
||||||
|
{
|
||||||
|
{ $slot "ranges" }
|
||||||
|
{ "Inclusive ranges where the live interval is live. This is because the [start,end] interval can have gaps." }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
{ $slot "uses" } { "sequence of references to instructions that use the register in the live interval." }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
{ $slot "reg-class" }
|
||||||
|
{ "Register class of the interval, either "
|
||||||
|
{ $link int-regs } " or " { $link float-regs } "." }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ $notes "The " { $slot "uses" } " and " { $slot "ranges" } " will never be empty because then the interval would be unused." } ;
|
||||||
|
|
||||||
|
|
||||||
|
HELP: live-intervals
|
||||||
|
{ $var-description "Mapping from vreg to " { $link live-interval-state } "." } ;
|
||||||
|
|
||||||
|
HELP: sync-point
|
||||||
|
{ $class-description "A location where all registers have to be spilled. For example when garbage collection is run or an alien ffi call is invoked. Figuring out where in the " { $link cfg } " the sync points are is done in the " { $link compute-live-intervals } " step. The tuple has the following slots:"
|
||||||
|
{ $table
|
||||||
|
{ { $slot "n" } { "Set from an instructions sequence number." } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ $see-also insn } ;
|
||||||
|
|
||||||
|
HELP: sync-points
|
||||||
|
{ $var-description "Sequence of sync points." } ;
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
USING: accessors assocs binary-search combinators
|
USING: accessors assocs binary-search combinators
|
||||||
compiler.cfg.def-use compiler.cfg.instructions
|
compiler.cfg.def-use compiler.cfg.instructions
|
||||||
compiler.cfg.linearization compiler.cfg.liveness
|
compiler.cfg.linearization compiler.cfg.liveness
|
||||||
compiler.cfg.registers compiler.cfg.ssa.destruction.leaders
|
compiler.cfg.registers compiler.cfg.ssa.destruction.leaders cpu.architecture
|
||||||
cpu.architecture fry kernel locals math math.order namespaces
|
fry kernel locals math math.intervals math.order namespaces sequences ;
|
||||||
sequences ;
|
|
||||||
IN: compiler.cfg.linear-scan.live-intervals
|
IN: compiler.cfg.linear-scan.live-intervals
|
||||||
|
|
||||||
TUPLE: live-range from to ;
|
TUPLE: live-range from to ;
|
||||||
|
@ -164,7 +163,6 @@ TUPLE: sync-point n keep-dst? ;
|
||||||
|
|
||||||
C: <sync-point> sync-point
|
C: <sync-point> sync-point
|
||||||
|
|
||||||
! Sequence of sync points
|
|
||||||
SYMBOL: sync-points
|
SYMBOL: sync-points
|
||||||
|
|
||||||
GENERIC: compute-sync-points* ( insn -- )
|
GENERIC: compute-sync-points* ( insn -- )
|
||||||
|
@ -178,7 +176,6 @@ M: clobber-insn compute-sync-points*
|
||||||
M: insn compute-sync-points* drop ;
|
M: insn compute-sync-points* drop ;
|
||||||
|
|
||||||
: compute-live-intervals-step ( bb -- )
|
: compute-live-intervals-step ( bb -- )
|
||||||
dup kill-block?>> [ drop ] [
|
|
||||||
{
|
{
|
||||||
[ block-from from set ]
|
[ block-from from set ]
|
||||||
[ block-to to set ]
|
[ block-to to set ]
|
||||||
|
@ -190,8 +187,7 @@ M: insn compute-sync-points* drop ;
|
||||||
bi
|
bi
|
||||||
] each
|
] each
|
||||||
]
|
]
|
||||||
} cleave
|
} cleave ;
|
||||||
] if ;
|
|
||||||
|
|
||||||
: init-live-intervals ( -- )
|
: init-live-intervals ( -- )
|
||||||
H{ } clone live-intervals set
|
H{ } clone live-intervals set
|
||||||
|
@ -207,8 +203,6 @@ ERROR: bad-live-interval live-interval ;
|
||||||
dup start>> -1 = [ bad-live-interval ] [ drop ] if ;
|
dup start>> -1 = [ bad-live-interval ] [ drop ] if ;
|
||||||
|
|
||||||
: finish-live-intervals ( live-intervals -- seq )
|
: finish-live-intervals ( live-intervals -- seq )
|
||||||
! Since live intervals are computed in a backward order, we have
|
|
||||||
! to reverse some sequences, and compute the start and end.
|
|
||||||
values dup [
|
values dup [
|
||||||
{
|
{
|
||||||
[ [ { } like reverse! ] change-ranges drop ]
|
[ [ { } like reverse! ] change-ranges drop ]
|
||||||
|
@ -220,7 +214,8 @@ ERROR: bad-live-interval live-interval ;
|
||||||
|
|
||||||
: compute-live-intervals ( cfg -- live-intervals sync-points )
|
: compute-live-intervals ( cfg -- live-intervals sync-points )
|
||||||
init-live-intervals
|
init-live-intervals
|
||||||
linearization-order <reversed> [ compute-live-intervals-step ] each
|
linearization-order <reversed> [ kill-block?>> not ] filter
|
||||||
|
[ compute-live-intervals-step ] each
|
||||||
live-intervals get finish-live-intervals
|
live-intervals get finish-live-intervals
|
||||||
sync-points get ;
|
sync-points get ;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,13 @@ HELP: base-pointers
|
||||||
{ $var-description "Mapping from vregs to base pointer vregs. If the vreg doesn't have a base pointer, then it will be mapped to " { $link f } "." }
|
{ $var-description "Mapping from vregs to base pointer vregs. If the vreg doesn't have a base pointer, then it will be mapped to " { $link f } "." }
|
||||||
{ $see-also lookup-base-pointer } ;
|
{ $see-also lookup-base-pointer } ;
|
||||||
|
|
||||||
|
HELP: compute-live-sets
|
||||||
|
{ $values { "cfg" cfg } }
|
||||||
|
{ $description "Main entry point for vocab. Pass must only be run after representation selection. In this pass " { $slot "gc-roots" } " are set." } ;
|
||||||
|
|
||||||
|
HELP: edge-live-ins
|
||||||
|
{ $var-description "Assoc mapping basic blocks to sequences of sets of vregs; each sequence is in correspondence with a predecessor." } ;
|
||||||
|
|
||||||
HELP: fill-gc-map
|
HELP: fill-gc-map
|
||||||
{ $values { "live-set" assoc } { "gc-map" gc-map } }
|
{ $values { "live-set" assoc } { "gc-map" gc-map } }
|
||||||
{ $description "Assigns values to the " { $slot "gc-roots" } " and " { $slot "derived-roots" } " slots of the " { $link gc-map } ". Does nothing if the " { $link select-representations } " pass hasn't ran." } ;
|
{ $description "Assigns values to the " { $slot "gc-roots" } " and " { $slot "derived-roots" } " slots of the " { $link gc-map } ". Does nothing if the " { $link select-representations } " pass hasn't ran." } ;
|
||||||
|
@ -32,9 +39,6 @@ HELP: lookup-base-pointer
|
||||||
{ $description "Tries to figure out what the base pointer for a vreg is. Can't use cache here because of infinite recursion inside the quotation passed to cache" }
|
{ $description "Tries to figure out what the base pointer for a vreg is. Can't use cache here because of infinite recursion inside the quotation passed to cache" }
|
||||||
{ $see-also base-pointers } ;
|
{ $see-also base-pointers } ;
|
||||||
|
|
||||||
HELP: edge-live-ins
|
|
||||||
{ $var-description "Assoc mapping basic blocks to sequences of sets of vregs; each sequence is in correspondence with a predecessor." } ;
|
|
||||||
|
|
||||||
ARTICLE: "compiler.cfg.liveness" "Liveness analysis"
|
ARTICLE: "compiler.cfg.liveness" "Liveness analysis"
|
||||||
"Similar to http://en.wikipedia.org/wiki/Liveness_analysis, with three additions:"
|
"Similar to http://en.wikipedia.org/wiki/Liveness_analysis, with three additions:"
|
||||||
$nl
|
$nl
|
||||||
|
@ -42,6 +46,9 @@ $nl
|
||||||
"With SSA, it is not sufficient to have a single live-in set per block. There is also an edge-live-in set per edge, consisting of phi inputs from each predecessor."
|
"With SSA, it is not sufficient to have a single live-in set per block. There is also an edge-live-in set per edge, consisting of phi inputs from each predecessor."
|
||||||
"Liveness analysis annotates call sites with GC maps indicating the spill slots in the stack frame that contain tagged pointers, and thus have to be visited if a GC occurs inside the call."
|
"Liveness analysis annotates call sites with GC maps indicating the spill slots in the stack frame that contain tagged pointers, and thus have to be visited if a GC occurs inside the call."
|
||||||
{ "GC maps can contain derived pointers. A derived pointer is a pointer into the middle of a data heap object. Each derived pointer has a base pointer, to keep it up to date when objects are moved by the garbage collector. This extends live intervals and inserts new " { $link ##phi } " instructions." }
|
{ "GC maps can contain derived pointers. A derived pointer is a pointer into the middle of a data heap object. Each derived pointer has a base pointer, to keep it up to date when objects are moved by the garbage collector. This extends live intervals and inserts new " { $link ##phi } " instructions." }
|
||||||
} ;
|
}
|
||||||
|
$nl
|
||||||
|
"Querying liveness data:"
|
||||||
|
{ $subsections live-in live-in? live-out live-out? } ;
|
||||||
|
|
||||||
ABOUT: "compiler.cfg.liveness"
|
ABOUT: "compiler.cfg.liveness"
|
||||||
|
|
|
@ -13,7 +13,7 @@ HELP: parallel-copy
|
||||||
|
|
||||||
HELP: parallel-copy-rep
|
HELP: parallel-copy-rep
|
||||||
{ $values { "mapping" { $link assoc } " of { dst src } virtual register pairs" } { "insns" array } }
|
{ $values { "mapping" { $link assoc } " of { dst src } virtual register pairs" } { "insns" array } }
|
||||||
{ $description "Creates " { $link ##copy } " instructions." } ;
|
{ $description "Creates " { $link ##copy } " instructions. Representation selection must have been run previously." } ;
|
||||||
|
|
||||||
ARTICLE: "compiler.cfg.parallel-copy" "Parallel copy"
|
ARTICLE: "compiler.cfg.parallel-copy" "Parallel copy"
|
||||||
"Revisiting Out-of-SSA Translation for Correctness, Code Quality, and Efficiency http://hal.archives-ouvertes.fr/docs/00/34/99/25/PDF/OutSSA-RR.pdf, Algorithm 1" ;
|
"Revisiting Out-of-SSA Translation for Correctness, Code Quality, and Efficiency http://hal.archives-ouvertes.fr/docs/00/34/99/25/PDF/OutSSA-RR.pdf, Algorithm 1" ;
|
||||||
|
|
|
@ -15,6 +15,9 @@ HELP: rep-of
|
||||||
{ $description "Gets the representation for a virtual register. This word cannot be called before representation selection has run; use any-rep for " { $link ##copy } " instructions and so on." }
|
{ $description "Gets the representation for a virtual register. This word cannot be called before representation selection has run; use any-rep for " { $link ##copy } " instructions and so on." }
|
||||||
{ $notes "Throws " { $link bad-vreg } " if the representation for the vreg isn't known." } ;
|
{ $notes "Throws " { $link bad-vreg } " if the representation for the vreg isn't known." } ;
|
||||||
|
|
||||||
|
HELP: representations
|
||||||
|
{ $var-description "Mapping from vregs to their representations." } ;
|
||||||
|
|
||||||
HELP: set-rep-of
|
HELP: set-rep-of
|
||||||
{ $values { "rep" representation } { "vreg" number } }
|
{ $values { "rep" representation } { "vreg" number } }
|
||||||
{ $description "Sets the representation for a virtual register." } ;
|
{ $description "Sets the representation for a virtual register." } ;
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
USING: help.markup help.syntax ;
|
||||||
|
IN: compiler.cfg.representations
|
||||||
|
|
||||||
|
ARTICLE: "compiler.cfg.representations" "Virtual register representation selection" "Virtual register representation selection. This is where decisions about integer tagging and float and vector boxing are made. The appropriate conversion operations inserted after a cost analysis." ;
|
||||||
|
|
||||||
|
ABOUT: "compiler.cfg.representations"
|
|
@ -12,11 +12,6 @@ compiler.cfg.representations.selection
|
||||||
compiler.cfg.utilities ;
|
compiler.cfg.utilities ;
|
||||||
IN: compiler.cfg.representations
|
IN: compiler.cfg.representations
|
||||||
|
|
||||||
! Virtual register representation selection. This is where
|
|
||||||
! decisions about integer tagging and float and vector boxing
|
|
||||||
! are made. The appropriate conversion operations inserted
|
|
||||||
! after a cost analysis.
|
|
||||||
|
|
||||||
: select-representations ( cfg -- )
|
: select-representations ( cfg -- )
|
||||||
{
|
{
|
||||||
needs-loops
|
needs-loops
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
USING: compiler.cfg.instructions help.markup help.syntax ;
|
USING: compiler.cfg compiler.cfg.instructions
|
||||||
|
compiler.cfg.ssa.destruction.private help.markup help.syntax ;
|
||||||
IN: compiler.cfg.ssa.destruction
|
IN: compiler.cfg.ssa.destruction
|
||||||
|
|
||||||
|
HELP: cleanup-cfg
|
||||||
|
{ $values { "cfg" cfg } }
|
||||||
|
{ $description "In this step, " { $link ##parallel-copy } " instructions are substituted with more concreete " { $link ##copy } " instructions. " { $link ##phi } " instructions are removed here." } ;
|
||||||
|
|
||||||
ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction"
|
ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction"
|
||||||
"Because of the design of the register allocator, this pass has three peculiar properties."
|
"Because of the design of the register allocator, this pass has three peculiar properties."
|
||||||
{ $list
|
{ $list
|
||||||
|
|
|
@ -2,12 +2,12 @@ USING: assocs compiler.cfg help.markup help.syntax ;
|
||||||
IN: compiler.cfg.stacks.finalize
|
IN: compiler.cfg.stacks.finalize
|
||||||
|
|
||||||
HELP: inserting-peeks
|
HELP: inserting-peeks
|
||||||
{ $values { "from" basic-block } { "to" basic-block } { "assoc" assoc } }
|
{ $values { "from" basic-block } { "to" basic-block } { "set" assoc } }
|
||||||
{ $description
|
{ $description
|
||||||
"A peek is inserted on an edge if the destination anticipates the stack location, the source does not anticipate it and it is not available from the source in a register." } ;
|
"A peek is inserted on an edge if the destination anticipates the stack location, the source does not anticipate it and it is not available from the source in a register." } ;
|
||||||
|
|
||||||
HELP: inserting-replaces
|
HELP: inserting-replaces
|
||||||
{ $values { "from" basic-block } { "to" basic-block } { "assoc" assoc } }
|
{ $values { "from" basic-block } { "to" basic-block } { "set" assoc } }
|
||||||
{ $description
|
{ $description
|
||||||
"A replace is inserted on an edge if two conditions hold:"
|
"A replace is inserted on an edge if two conditions hold:"
|
||||||
{ $list
|
{ $list
|
||||||
|
|
|
@ -28,7 +28,7 @@ HELP: translate-local-loc
|
||||||
{ $examples
|
{ $examples
|
||||||
{ $example
|
{ $example
|
||||||
"USING: compiler.cfg.stacks.local compiler.cfg.registers compiler.cfg.debugger namespaces prettyprint ;"
|
"USING: compiler.cfg.stacks.local compiler.cfg.registers compiler.cfg.debugger namespaces prettyprint ;"
|
||||||
"{ { 3 0 } { 0 0 } } D 7 translate-local-loc ."
|
"D 7 { { 3 0 } { 0 0 } } translate-local-loc ."
|
||||||
"D 4"
|
"D 4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ HELP: height-state>insns
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
HELP: emit-changes
|
HELP: emit-changes
|
||||||
|
{ $values { "replaces" sequence } { "state" sequence } }
|
||||||
{ $description "Insert height and stack changes prior to the last instruction." } ;
|
{ $description "Insert height and stack changes prior to the last instruction." } ;
|
||||||
|
|
||||||
HELP: inc-stack
|
HELP: inc-stack
|
||||||
|
|
|
@ -19,8 +19,8 @@ HELP: call-effect-slow>quot
|
||||||
{ $description "Creates a quotation which wraps " { $link call-effect-unsafe } "." } ;
|
{ $description "Creates a quotation which wraps " { $link call-effect-unsafe } "." } ;
|
||||||
|
|
||||||
HELP: call-effect-unsafe?
|
HELP: call-effect-unsafe?
|
||||||
{ $values { "cached-effect" "an effect or +unknown+" } { "effect" effect } { "?" "a boolean" } }
|
{ $values { "quot" quotation } { "effect" effect } { "?" "a boolean" } }
|
||||||
{ $description "Checks if the given effect is safe with regards to the cached one." } ;
|
{ $description "Checks if the given effect is safe with regards to the quotation." } ;
|
||||||
|
|
||||||
HELP: update-inline-cache
|
HELP: update-inline-cache
|
||||||
{ $values { "word/quot" "word or quotation" } { "ic" inline-cache } }
|
{ $values { "word/quot" "word or quotation" } { "ic" inline-cache } }
|
||||||
|
|
Loading…
Reference in New Issue