LIR Reference
LIR is GDCC’s lower-level function IR. It is designed around explicit GDExtension-facing boundaries: types, variable slots, temporary values, control flow, object lifecycle, and Variant transitions are represented directly in the IR.
This reference describes the public LIR surface and the intent of each instruction. It does not document GDCC’s concrete backend implementation strategy.
LIR Architecture
Section titled “LIR Architecture”An LIR unit is organized around class definitions. A class contains signals, properties, and functions; functions contain the executable body.
- Module: contains one or more class definitions emitted by a compile unit.
- Class definition: contains the class name, superclass, annotations, signals, properties, and functions that make up the Godot-visible class surface.
- Signal: contains a name and parameter list for a typed signal declaration.
- Property: contains a name, type, static flag, initialization helper, and accessor helpers for field/property surface.
- Function: contains the signature, parameters, return type, variable table, and basic blocks for executable logic.
- Variables: record parameters, locals, constants, and stack slots addressed by
$id. - Basic block: contains one entry, ordinary instructions, and one terminator instruction.
- Instruction: contains an opcode, optional result, and operands for a computation, call, read/write, or jump.
LIR is not SSA. Values flow through explicit variable slots, assignments, loads, stores, and returns. That shape keeps the IR close to GDExtension C generation without making the generated C details part of this reference.
The text form is:
($<result_id> = )?<opcode> <operand>...Variable operands use $id, strings and operator names use quotes, and block labels are written as bare labels.
Common Conventions
Section titled “Common Conventions”Instructions can require a result, allow an optional result, or produce no result.
- Required result: the instruction produces a new value, written as
$result = opcode .... - Optional result: call instructions may keep the return value or omit it when only side effects matter.
- No result: the instruction only produces side effects, control flow, or debug metadata.
Common operand forms:
- Variable:
$value, referring to a variable id or temporary id. - String:
"name", used for class names, function names, property names, and string literals. - Number or bool:
1,1.5,true, used for immediate literal operands. - Label:
entry, used for basic block ids. - Operator:
"ADD", used for Godot operator enum names.
Data Literals and Assignment
Section titled “Data Literals and Assignment”These instructions turn constants or existing variables into LIR values. They are usually expression-lowering leaves.
literal_bool
Section titled “literal_bool”Creates a bool constant.
$flag = literal_bool trueliteral_int
Section titled “literal_int”Creates an integer constant.
$count = literal_int 42literal_float
Section titled “literal_float”Creates a floating-point constant.
$ratio = literal_float 0.5literal_string
Section titled “literal_string”Creates a UTF-8 String constant.
$text = literal_string "hello"literal_string_name
Section titled “literal_string_name”Creates a StringName constant for identity-like names such as methods, properties, and signals.
$name = literal_string_name "position"literal_nil
Section titled “literal_nil”Creates a Variant Nil value.
$v = literal_nilliteral_null
Section titled “literal_null”Creates a null object reference.
$obj = literal_nullassign
Section titled “assign”Moves a source value into a target-typed result slot.
$target = assign $sourceassign represents a typed boundary. The source must be assignable to the result variable’s type, such as same-type assignment, object upcast, Variant boundary, supported container covariance, or a value already materialized by a supported implicit conversion rule.
Construction, Lifecycle, and Operators
Section titled “Construction, Lifecycle, and Operators”These instructions create complex values, maintain lifecycle boundaries, and execute Godot operators.
construct_builtin
Section titled “construct_builtin”Constructs a builtin value using the result variable’s type.
$vec = construct_builtin $x $y $zconstruct_array
Section titled “construct_array”Constructs Array or Packed*Array. A normal Array may carry an element type hint; a packed array is selected from the result variable type.
$items = construct_array "Node"$packed = construct_arrayconstruct_dictionary
Section titled “construct_dictionary”Constructs a typed or generic Dictionary.
$map = construct_dictionary "StringName" "Node"construct_object
Section titled “construct_object”Constructs an object of a named class.
$node = construct_object "Node"construct_callable
Section titled “construct_callable”Creates a Callable from a function in the compile unit.
$cb = construct_callable "do_work"construct_lambda
Section titled “construct_lambda”Creates a Callable from a lambda and capture variables. The first operand is the lambda function name; the remaining operands are captures.
$cb = construct_lambda "lambda_1" $self $valuedestruct
Section titled “destruct”Destroys or releases a resource held by a variable, with provenance.
destruct $value "AUTO_GENERATED"try_own_object
Section titled “try_own_object”Tries to take ownership of an object reference. For non-reference-counted objects, this may be a semantic no-op.
try_own_object $obj "INTERNAL"try_release_object
Section titled “try_release_object”Tries to release ownership of an object reference. For non-reference-counted objects, this may be a semantic no-op.
try_release_object $obj "USER_EXPLICIT"Lifecycle provenance may be AUTO_GENERATED, INTERNAL, USER_EXPLICIT, or UNKNOWN. New LIR should prefer explicit provenance.
unary_op
Section titled “unary_op”Executes a unary Godot operator.
$out = unary_op "NEGATE" $valueAvailable unary operators:
| Operator | Common source spelling |
|---|---|
NEGATE | unary - |
POSITIVE | unary + |
BIT_NOT | ~ |
NOT | not, ! |
binary_op
Section titled “binary_op”Executes a binary Godot operator.
$sum = binary_op "ADD" $left $rightAvailable binary operators:
| Operator | Common source spelling |
|---|---|
EQUAL | == |
NOT_EQUAL | != |
LESS | < |
LESS_EQUAL | <= |
GREATER | > |
GREATER_EQUAL | >= |
ADD | binary + |
SUBTRACT | binary - |
MULTIPLY | * |
DIVIDE | / |
MODULE | % |
POWER | ** |
SHIFT_LEFT | << |
SHIFT_RIGHT | >> |
BIT_AND | & |
BIT_OR | | |
BIT_XOR | ^ |
AND | and, && |
OR | or, || |
XOR | xor |
IN | in |
The LIR text operand uses the enum name, such as "ADD" or "NEGATE", not the source symbol + or -.
Indexing and Dynamic Access
Section titled “Indexing and Dynamic Access”These instructions are the dynamic access surface for Variant, dictionary-like, array-like, object-like, keyed, named, and indexed access.
variant_get
Section titled “variant_get”Reads from a Variant with a Variant key.
$out = variant_get $variant $keyvariant_get_keyed
Section titled “variant_get_keyed”Reads from a keyed Variant, usually dictionary-like.
$out = variant_get_keyed $dict_like $keyvariant_get_named
Section titled “variant_get_named”Reads from a named Variant using StringName.
$out = variant_get_named $object_like $namevariant_get_indexed
Section titled “variant_get_indexed”Reads from a Variant using an integer index.
$out = variant_get_indexed $array_like $indexvariant_set
Section titled “variant_set”Writes to a Variant with a Variant key.
variant_set $variant $key $valuevariant_set_keyed
Section titled “variant_set_keyed”Writes to a keyed Variant.
variant_set_keyed $dict_like $key $valuevariant_set_named
Section titled “variant_set_named”Writes to a named Variant.
variant_set_named $object_like $name $valuevariant_set_indexed
Section titled “variant_set_indexed”Writes to a Variant using an integer index.
variant_set_indexed $array_like $index $valueResults often remain Variant until a later unpack_variant, assign, or explicit typed boundary.
Type and Variant Boundaries
Section titled “Type and Variant Boundaries”Type instructions handle runtime type queries, object tests, object casts, and stable-type to Variant transitions.
get_variant_type
Section titled “get_variant_type”Reads the Godot type id held by a Variant.
$type_id = get_variant_type $variantget_class_name
Section titled “get_class_name”Gets a static type name or runtime object class name as String.
$name = get_class_name $valueobject_cast
Section titled “object_cast”Casts an object to a named class, returning null on mismatch.
$node = object_cast "Node" $objis_instance_of
Section titled “is_instance_of”Tests whether an object is an instance of a named class.
$ok = is_instance_of "Node" $objpack_variant
Section titled “pack_variant”Packs a stable value into Variant.
$variant = pack_variant $valueunpack_variant
Section titled “unpack_variant”Unpacks a Variant into the result variable’s type.
$value = unpack_variant $variantpack_variant and unpack_variant are the explicit markers for entering and leaving dynamic value space.
variant_is_nil
Section titled “variant_is_nil”Tests whether a Variant is Nil.
$is_nil = variant_is_nil $variantobject_is_null
Section titled “object_is_null”Tests whether an object reference is null.
$is_null = object_is_null $objControl Flow
Section titled “Control Flow”Control-flow instructions terminate basic blocks.
Unconditionally branches to a basic block.
goto exitBranches to true/false blocks based on a bool.
go_if $cond then_block else_blockgo_if expects a boolean condition. Dynamic or non-boolean source conditions should be normalized before the branch.
return
Section titled “return”Returns from the current function, with or without a value.
returnreturn $valueCall instructions allow optional results. Keep the result when the surrounding expression needs it; omit it for side-effect-only calls.
call_global
Section titled “call_global”Calls a global function.
$out = call_global "print" $messagecall_method
Section titled “call_method”Calls an instance method. The first variable operand is the receiver.
$out = call_method "get_child" $node $indexcall_super_method
Section titled “call_super_method”Calls a superclass method.
call_super_method "_ready" $selfcall_static_method
Section titled “call_static_method”Calls a static method on a class.
$out = call_static_method "MathUtil" "clamp_i" $value $min $maxcall_intrinsic
Section titled “call_intrinsic”Calls a backend-owned intrinsic registered by name. Implicit conversions that need materialization use this shape, such as c_int_to_float and c_vector3i_to_vector3.
$out = call_intrinsic "intrinsic_name" $argCall arguments are listed in source order. Retain the result only when the surrounding expression needs it.
Property and Static Access
Section titled “Property and Static Access”These instructions represent stable property/static paths, unlike variant_get_named and variant_set_named, which operate through dynamic Variant access.
load_property
Section titled “load_property”Reads a named property from an object.
$value = load_property "position" $nodestore_property
Section titled “store_property”Writes a named property on an object.
store_property "position" $node $valueload_static
Section titled “load_static”Reads a static variable or property.
$value = load_static "GameState" "score"store_static
Section titled “store_static”Writes a static variable or property.
store_static "GameState" "score" $valueMiscellaneous
Section titled “Miscellaneous”Does nothing; useful as a placeholder or test instruction.
nopline_number
Section titled “line_number”Marks the current source line for diagnostics or debug data.
line_number 27Instruction Index
Section titled “Instruction Index”- Data:
literal_bool,literal_int,literal_float,literal_string,literal_string_name,literal_nil,literal_null,assign. - Construction, lifecycle, and operators:
construct_builtin,construct_array,construct_dictionary,construct_object,construct_callable,construct_lambda,destruct,try_own_object,try_release_object,unary_op,binary_op. - Indexing and dynamic access:
variant_get,variant_get_keyed,variant_get_named,variant_get_indexed,variant_set,variant_set_keyed,variant_set_named,variant_set_indexed. - Type:
get_variant_type,get_class_name,object_cast,is_instance_of,pack_variant,unpack_variant,variant_is_nil,object_is_null. - Control flow:
goto,go_if,return. - Calls:
call_global,call_method,call_super_method,call_static_method,call_intrinsic. - Access:
load_property,store_property,load_static,store_static. - Misc:
nop,line_number.