Skip to content

v2.ssa #

fn Builder.new #

fn Builder.new(mod &Module) &Builder

fn Builder.new_with_env #

fn Builder.new_with_env(mod &Module, env &types.Environment) &Builder

fn Module.new #

fn Module.new(name string) &Module

fn TypeStore.new #

fn TypeStore.new() &TypeStore

type BlockID #

type BlockID = int

type TypeID #

type TypeID = int

type ValueID #

type ValueID = int

enum AtomicOrdering #

enum AtomicOrdering {
	not_atomic
	unordered
	monotonic
	acquire
	release
	acq_rel
	seq_cst
}

enum CallConv #

enum CallConv {
	c_decl
	fast_call
	wasm_std
}

enum InlineHint #

enum InlineHint {
	none   // No hint, let optimizer decide
	always // Always inline (e.g., V's [inline] attribute)
	never  // Never inline (e.g., V's [noinline] attribute)
	hint   // Suggest inlining (optimizer may ignore)
}

enum Linkage #

enum Linkage {
	external
	private
	internal
}

enum OpCode #

enum OpCode {
	// Terminators
	ret
	br
	jmp
	switch_
	unreachable

	// Binary (integer)
	add
	sub
	mul
	sdiv
	udiv
	srem
	urem

	// Binary (float)
	fadd
	fsub
	fmul
	fdiv
	frem

	// Bitwise
	shl
	lshr
	ashr
	and_
	or_
	xor

	// Memory
	alloca
	heap_alloc // Heap allocate memory for a type (malloc+zero): returns ptr
	load
	store
	get_element_ptr
	fence
	cmpxchg
	atomicrmw

	// Conversion
	trunc
	zext
	sext
	fptoui
	fptosi
	uitofp
	sitofp
	bitcast

	// Comparisons (signed)
	lt
	gt
	le
	ge
	eq
	ne
	// Comparisons (unsigned)
	ult
	ugt
	ule
	uge

	// Other
	phi
	call
	call_indirect // Indirect call through function pointer
	call_sret     // Call with struct return (x8 indirect return on ARM64)
	select
	assign             // copy for phi elimination
	inline_string_init // Create string struct by value: (string){str, len, is_lit}

	// Aggregate (struct/tuple) operations
	extractvalue // Extract element from struct/tuple: extractvalue %tuple, index
	insertvalue  // Insert element into struct/tuple: insertvalue %tuple, %val, index
	struct_init  // Create struct: operands are field values in order
}

enum TypeKind #

enum TypeKind {
	void_t
	int_t
	float_t
	ptr_t
	array_t
	struct_t
	func_t
	label_t
	metadata_t
}

enum ValueKind #

enum ValueKind {
	unknown
	constant
	argument
	global
	instruction
	basic_block
	string_literal   // V string struct literal (by value)
	c_string_literal // C string literal (raw char pointer)
	func_ref         // Function pointer reference (for map hash/eq/clone/free functions)
}

struct BasicBlock #

struct BasicBlock {
pub:
	id     BlockID
	val_id ValueID
	name   string
	parent int // Function ID
pub mut:
	instrs []ValueID

	// Control Flow Graph
	preds []BlockID
	succs []BlockID

	// Dominators
	idom     BlockID
	dom_tree []BlockID
}

struct Builder #

struct Builder {
mut:
	mod        &Module
	env        &types.Environment = unsafe { nil }
	cur_func   int                = -1
	cur_block  BlockID            = -1
	cur_module string             = 'main'
	// Variable name -> SSA ValueID (alloca pointer)
	vars map[string]ValueID
	// Loop break/continue targets
	loop_stack []LoopInfo
	// Struct name -> SSA TypeID
	struct_types map[string]TypeID
	// Enum name -> field values
	enum_values map[string]int
	// Function name -> SSA function index
	fn_index map[string]int
	// Constant name -> evaluated integer value (for inlining)
	const_values map[string]i64
	// String constant name -> string literal value (for inlining)
	string_const_values map[string]string
	// Float constant name -> float literal string (for inlining as f64)
	float_const_values map[string]string
	// Label name -> SSA BlockID (for goto/label support)
	label_blocks map[string]BlockID
	// Track mut pointer params (e.g., mut buf &u8) that need extra dereference
	// when used in expressions (buf is ptr(ptr(i8)), but user sees buf as &u8)
	mut_ptr_params map[string]bool
	// Set during sum type init _data field building to trigger heap allocation
	// for &struct_local (prevents dangling stack pointers in returned sum types)
	in_sumtype_data bool
	// Constant array globals: names of globals that store raw element data
	// (not V array structs). build_ident returns the pointer directly.
	const_array_globals    map[string]bool
	const_array_elem_count map[string]int
	// Dynamic const arrays: array struct globals that need _vinit initialization.
	// Key: array struct global name, Value: data global name + metadata.
	dyn_const_arrays []DynConstArray
	// Counter for generating unique anonymous function names
	anon_fn_counter int
}

fn (Builder) build_all #

fn (mut b Builder) build_all(files []ast.File)

struct ConstantData #

struct ConstantData {
pub:
	int_val   i64
	float_val f64
	str_val   string
}

struct Function #

struct Function {
pub:
	id   int
	name string
	typ  TypeID
pub mut:
	blocks      []BlockID
	params      []ValueID
	is_c_extern bool // C-language extern function (no V body, provided by C headers/libraries)

	linkage   Linkage
	call_conv CallConv
}

struct GlobalVar #

struct GlobalVar {
pub:
	name          string
	typ           TypeID
	linkage       Linkage
	alignment     int
	is_constant   bool
	initial_value i64  // For constants/enums, the initial integer value
	initial_data  []u8 // For constant arrays: serialized element data
}

struct Instruction #

struct Instruction {
pub mut:
	op OpCode
	// Operands are IDs of other Values
	operands []ValueID
pub:
	block BlockID
	typ   TypeID // Result type

	pos        token.Pos
	atomic_ord AtomicOrdering
	inline     InlineHint // Inline hint for call instructions
}

struct Module #

@[heap]
struct Module {
pub mut:
	name       string
	target     TargetData
	type_store TypeStore

	// Type checker environment (optional, for backends that need rich type info)
	env &types.Environment = unsafe { nil }

	// Arenas
	values  []Value
	instrs  []Instruction
	blocks  []BasicBlock
	funcs   []Function
	globals []GlobalVar

	// C struct names: TypeID -> C struct name (e.g., 114 -> "stat" for struct stat)
	// Used by the C gen to emit `typedef struct  Struct_N;` instead of
	// generating a custom struct definition that would have the wrong memory layout.
	c_struct_names map[int]string
	// C structs marked with @[typedef] – already a C typedef, not a struct tag.
	c_typedef_structs map[int]bool

	// Constant cache: (type, name) -> ValueID for deduplication
	const_cache map[string]ValueID
}

fn (Module) new_function #

fn (mut m Module) new_function(name string, ret TypeID, params []TypeID) int

fn (Module) add_block #

fn (mut m Module) add_block(func_id int, name string) BlockID

fn (Module) add_value_node #

fn (mut m Module) add_value_node(kind ValueKind, typ TypeID, name string, index int) ValueID

Updated to accept 'index'

fn (Module) get_or_add_const #

fn (mut m Module) get_or_add_const(typ TypeID, name string) ValueID

Get or create a constant value, reusing existing ones when possible. This maintains SSA's immutability principle by avoiding duplicate constants.

fn (Module) get_block_from_val #

fn (m Module) get_block_from_val(val_id int) int

fn (Module) add_instr #

fn (mut m Module) add_instr(op OpCode, block BlockID, typ TypeID, operands []ValueID) ValueID

fn (Module) add_global #

fn (mut m Module) add_global(name string, typ TypeID, is_const bool) int

fn (Module) add_global_with_value #

fn (mut m Module) add_global_with_value(name string, typ TypeID, is_const bool, initial_value i64) int

fn (Module) add_global_with_data #

fn (mut m Module) add_global_with_data(name string, elem_type TypeID, is_const bool, data []u8) int

fn (Module) add_external_global #

fn (mut m Module) add_external_global(name string, typ TypeID) ValueID

add_external_global adds an external global variable (defined outside this module) Returns the ValueID for the global pointer

fn (Module) add_instr_front #

fn (mut m Module) add_instr_front(op OpCode, block BlockID, typ TypeID, operands []ValueID) ValueID

fn (Module) replace_uses #

fn (mut m Module) replace_uses(old_val int, new_val int)

struct TargetData #

struct TargetData {
pub:
	ptr_size      int
	endian_little bool
}

struct Type #

struct Type {
pub:
	kind        TypeKind
	width       int      // Bit width
	elem_type   TypeID   // For Ptr, Array
	len         int      // For Array
	fields      []TypeID // For Structs
	field_names []string // Field names for Structs
	params      []TypeID // For Funcs
	ret_type    TypeID
	is_c_struct bool // True for C interop structs (use raw field names, typedef to C struct)
	is_union    bool // True for union types (all fields overlap at offset 0)
	is_unsigned bool // True for unsigned integer types (u8, u16, u32, u64)
}

struct TypeStore #

struct TypeStore {
pub mut:
	types []Type
	cache map[string]TypeID
}

fn (TypeStore) get_int #

fn (mut ts TypeStore) get_int(width int) TypeID

fn (TypeStore) get_uint #

fn (mut ts TypeStore) get_uint(width int) TypeID

fn (TypeStore) get_float #

fn (mut ts TypeStore) get_float(width int) TypeID

fn (TypeStore) get_ptr #

fn (mut ts TypeStore) get_ptr(elem TypeID) TypeID

fn (TypeStore) get_array #

fn (mut ts TypeStore) get_array(elem TypeID, length int) TypeID

fn (TypeStore) get_tuple #

fn (mut ts TypeStore) get_tuple(elem_types []TypeID) TypeID

fn (TypeStore) register #

fn (mut ts TypeStore) register(t Type) TypeID

struct Value #

struct Value {
pub:
	id  ValueID
	typ TypeID
	// Index into the specific arena (instrs, blocks, globals)
	index int
pub mut:
	kind ValueKind
	name string
	uses []ValueID
}