dmd.toir
Convert to Intermediate Representation (IR) for the back-end.
License
Source: toir.d
Documentation: https://dlang.org/phobos/dmd_toir.html
-
Declaration
struct
Label
;Our label symbol
-
Declaration
struct
IRState
;Collect state variables needed by the intermediate representation (IR)
-
Declaration
bool
arrayBoundsCheck
();Return Value
true
if do array bounds checking for the current function -
Declaration
bool
isNothrow
();Return Value
true
if in a nothrow section of code
-
-
Declaration
elem*
incUsageElem
(IRState*irs
, const ref Locloc
);Produce elem which increments the usage count for a particular line. Sets corresponding bit in bitmap
m.covb[linnum]
. Used to implement -cov switch (coverage analysis).Parameters
IRState*
irs
context
Loc
loc
line and file of what line to show usage for
Return Value
elem that increments the line count
References: https://dlang.org/dmd-windows.html#switch-cov
-
Declaration
elem*
getEthis
(const ref Locloc
, IRState*irs
, Dsymbolfd
, Dsymbolfdp
= null, DsymbolorigSc
= null);Return elem that evaluates to the static frame pointer for function
fd
. Iffd
is a member function, the returned expression will compute the value offd
's 'this' variable. 'fdp
' is the parent of 'fd
' if the frame pointer is being used to call 'fd
'. 'origSc
' is the original scope we inlined from. This routine is critical for implementing nested functions. -
Declaration
elem*
fixEthis2
(elem*ethis
, FuncDeclarationfd
, boolctxt2
= false);Select one context pointer from a dual-context array
Return Value
*(
ethis
+ offset); -
Declaration
elem*
setEthis
(const ref Locloc
, IRState*irs
, elem*ey
, AggregateDeclarationad
, boolsetthis2
= false);Initialize the hidden aggregate member, vthis, with the context pointer.
Return Value
*(
ey
+ (ethis2 ?ad
.vthis2 :ad
.vthis).offset) = this; -
Declaration
int
intrinsic_op
(FuncDeclarationfd
);Convert intrinsic function to operator.
Return Value
the operator as backend OPER, NotIntrinsic if not an intrinsic function, OPtoPrec if frontend-only intrinsic
-
Declaration
elem*
resolveLengthVar
(VarDeclarationlengthVar
, elem**pe
, Typet1
);Given an expression e that is an array, determine and set the 'length' variable.
Input:
lengthVar
Symbol of 'length' variable &e expression that is the arrayt1
Type of the arrayOutput: e is rewritten to avoid side effects
Return Value
expression that initializes 'length'
-
Declaration
TYPE*
getParentClosureType
(Symbol*sthis
, FuncDeclarationfd
);for a nested function '
fd
' return the type of the closure of an outer function or aggregate. If the function is a member function the 'this' type is expected to be stored in 'sthis
.Sthis'. It is always returned if it is not a void pointer. buildClosure() must have been called on the outer function before.Parameters
Symbol*
sthis
the symbol of the current 'this' derived from
fd
.vthisFuncDeclaration
fd
the nested function
-
Declaration
uint
setClosureVarOffset
(FuncDeclarationfd
);Go through the variables in function
fd
that are to be allocated in a closure, and set the .offset fields for those variables to their positions relative to the start of the closure instance. Also turns off nrvo for closure variables.Parameters
FuncDeclaration
fd
function
Return Value
overall alignment of the closure
-
Declaration
void
buildClosure
(FuncDeclarationfd
, IRState*irs
);Closures are implemented by taking the local variables that need to survive the scope of the function, and copying them into a gc allocated chuck of memory. That chunk, called the closure here, is inserted into the linked list of stack frames instead of the usual stack frame.
Discussion
buildClosure
() inserts code just after the function prolog is complete. It allocates memory for the closure, allocates a local variable (sclosure) to point to it, inserts into it the link to the enclosing frame, and copies into it the parameters that are referred to in nested functions. In VarExp::toElem and SymOffExp::toElem, when referring to a variable that is in a closure, takes the offset from sclosure rather than from the frame pointer.
getEthis() and NewExp::toElem need to use sclosure, if set, rather than the current frame pointer. -
Declaration
uint
setAlignSectionVarOffset
(FuncDeclarationfd
);Go through the variables in function
fd
that are to be allocated in an aligned section, and set the .offset fields for those variables to their positions relative to the start of the aligned section instance.Parameters
FuncDeclaration
fd
function
Return Value
overall alignment of the align section
Reference: setClosureVarOffset
-
Declaration
void
buildAlignSection
(FuncDeclarationfd
, ref IRStateirs
);Aligned sections are implemented by taking the local variables that need alignment that is larger than the stack alignment. They are allocated into a separate chunk of memory on the stack called an align section, which is aligned on function entry.
Discussion
buildAlignSection
() inserts code just after the function prolog is complete. It allocates memory for the align closure by making a local stack variable to contain that memory, allocates a local variable (salignSection) to point to it. In VarExp::toElem and SymOffExp::toElem, when referring to a variable that is in an align closure, take the offset from salignSection rather than from the frame pointer. A variable cannot be in both a closure and an align section. They go in the closure and then that closure is aligned.
getEthis() and NewExp::toElem need to use sclosure, if set, rather than the current frame pointer??
Run after buildClosure, as buildClosure gets first dibs on inAlignSection variablesParameters
FuncDeclaration
fd
function in which all this occurs
IRState
irs
state of the intermediate code generation
Reference: buildClosure() is very similar.
https://github.com/dlang/dmd/pull/9143 was an incomplete attempt to solve this problem that was merged. It should probably be removed. -
Declaration
void
buildCapture
(FuncDeclarationfd
);build a debug info struct for variables captured by nested functions, but not in a closure. must be called after generating the function to fill stack offsets
Parameters
FuncDeclaration
fd
function
-
Declaration
RET
retStyle
(TypeFunctiontf
, boolneedsThis
);Determine return style of function - whether in registers or through a hidden pointer to the caller's stack.
Parameters
TypeFunction
tf
function type to check
bool
needsThis
true
if the function type is for a non-static member functionReturn Value
RET.stack if return value from function is on the stack, RET.regs otherwise