34 for (
size_t i = 0; i < len; i++)
71 for (
size_t i = 0; i <
CT_MIN(len, 16); i++)
74 const char *it = value_to_string(elem, arena);
80 char *joined =
str_join(
", ", parts, arena);
86 if (!value->
init) {
return "noinit"; }
93 case eTypeUnit:
return "unit";
94 case eTypeEmpty:
return "empty";
95 case eTypePointer:
return pointer_value_to_string(value, arena);
105 switch (operand.
kind)
107 case eOperandEmpty:
return "empty";
111 return str_format(arena,
"$%s", value_to_string(operand.
value, arena));
114 case eOperandGlobal: {
118 case eOperandFunction: {
122 case eOperandLocal: {
123 size_t index = operand.
local;
124 return str_format(arena,
"local(%zu)", index);
126 case eOperandParam: {
127 size_t index = operand.
param;
128 return str_format(arena,
"param(%zu)", index);
130 default:
CT_NEVER(
"unknown operand kind %d", operand.
kind);
139 for (
size_t i = 0; i < len; i++)
158 operand_to_string(emit, unary.
operand)
164 io_printf(io,
"\t%%%s = binary %s %s %s\n",
167 operand_to_string(emit, binary.
lhs),
168 operand_to_string(emit, binary.
rhs)
177 operand_to_string(emit, cast.
operand)
185 operand_to_string(emit, load.
src)
193 operand_to_string(emit, offset.
array),
194 operand_to_string(emit, offset.
offset)
200 io_printf(io,
"\t%%%s = member %s.%zu\n",
202 operand_to_string(emit, member.
object),
211 operand_to_string(emit, addr.
symbol)
228 operand_to_string(emit, store.
dst),
229 operand_to_string(emit, store.
src)
237 for (
size_t arg_idx = 0; arg_idx < args_len; arg_idx++)
240 vector_set(args, arg_idx, (
char*)operand_to_string(emit, *arg));
244 operand_to_string(emit, call.
function),
252 operand_to_string(emit, branch.
cond),
253 operand_to_string(emit, branch.
then),
254 operand_to_string(emit, branch.
other)
260 io_printf(io,
"\t%%%s = compare %s %s %s\n",
263 operand_to_string(emit, compare.
lhs),
264 operand_to_string(emit, compare.
rhs)
286 io_printf(io,
"\t%%%s = offsetof %s %zu\n",
303 for (
size_t i = 0; i < len; i++)
306 emit_ssa_block(emit, io, bb);
315 return str_format(arena,
"{type = %s, quals = %s, size = %zu}", ty, quals, storage.
size);
322 for (
size_t i = 0; i < len; i++)
357 io_t *io =
fs_open(fs, file, eOsAccessWrite | eOsAccessTruncate);
365 for (
size_t i = 0; i < len; i++)
368 emit_symbol_deps(io, global, emit->
deps);
371 emit_ssa_attribs(io, global, base->
arena);
373 emit_ssa_blocks(emit, io, global->
blocks);
379 for (
size_t i = 0; i < fns; i++)
382 emit_symbol_deps(io, fn, emit->
deps);
388 io_printf(io,
"fn %s(%s) -> %s [variadic: %s]\n",
393 emit_ssa_attribs(io, fn, base->
arena);
395 if (fn->
linkage != eLinkImport)
397 emit_ssa_locals(emit, io, fn->
locals);
398 emit_ssa_blocks(emit, io, fn->
blocks);
411 .reports = runtime->
logger,
421 for (
size_t i = 0; i < len; i++)
424 debug_emit_module(&emit, mod);
CT_NODISCARD CT_PUREFN CT_BASE_API size_t ctu_strlen(const char *str)
get the length of a string not including the null terminator equivalent to strlen but with safety che...
CT_NODISCARD CT_FS_API io_t * fs_open(fs_t *fs, const char *path, os_access_t flags)
open a file at a given location in the filesystem
CT_FS_API void fs_file_create(fs_t *fs, const char *path)
create a file
CT_NODISCARD CT_PUREFN CT_STD_API void * map_get(const map_t *map, const void *key)
get a value from a map
CT_NODISCARD CT_PUREFN CT_STD_API set_iter_t set_iter(set_t *set)
acquire a set iterator for a set
CT_NODISCARD CT_STD_API const void * set_next(set_iter_t *iter)
get the next item from a set iterator
CT_NODISCARD CT_PUREFN CT_STD_API bool set_has_next(set_iter_t *iter)
check if a set iterator has more items
CT_IO_API size_t io_printf(io_t *io, STA_FORMAT_STRING const char *fmt,...)
printf to an io object
#define CT_NEVER(...)
assert that a code path is never reached
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
CT_SSA_API bool ssa_value_get_bool(const ssa_value_t *value)
CT_SSA_API ssa_literal_value_t ssa_value_get_literal(const ssa_value_t *value)
CT_NODISCARD CT_STD_API char * str_join(const char *sep, const vector_t *parts, arena_t *arena)
join strings
CT_TREE_API const char * binary_name(binary_t op)
get the pretty name of a binary operator
CT_TREE_API const char * linkage_string(tree_linkage_t link)
get the name of a linkage
CT_TREE_API const char * quals_string(tree_quals_t quals)
get the name of a set of qualifiers
CT_TREE_API const char * visibility_string(tree_visibility_t vis)
get the name of visibility
CT_TREE_API const char * compare_name(compare_t op)
get the pretty name of a comparison operator
CT_TREE_API const char * unary_name(unary_t op)
get the pretty name of a unary operator
CT_NODISCARD CT_PUREFN CT_STD_API size_t typevec_len(const typevec_t *vec)
get the length of a vector
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_offset(const typevec_t *vec, size_t index)
get a pointer to the value at the given index
CT_NODISCARD CT_PUREFN CT_STD_API void * vector_get(const vector_t *vector, size_t index)
get a value from a vector
CT_NODISCARD CT_STD_API vector_t * vector_new(size_t size, arena_t *arena)
create a new vector with an initial capacity
CT_NODISCARD CT_STD_API vector_t * vector_of(size_t len, arena_t *arena)
create a new vector with a specified length
CT_STD_API void vector_push(vector_t **vector, void *value)
push a value onto the end of a vector
CT_STD_API void vector_set(vector_t *vector, size_t index, void *value)
set a value in a vector
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
STA_DECL char * str_format(arena_t *arena, const char *fmt,...)
target code emitter options
arena_t * arena
arena to use
vector_t * functions
vector<ssa_symbol_t> all functions declared/imported/exported by this module
vector_t * globals
vector<ssa_symbol_t> all globals declared/imported/exported by this module
const ssa_value_t * value
const ssa_block_t * vreg_context
const ssa_symbol_t * function
const ssa_symbol_t * global
const ssa_value_t * value
ssa underlying storage type
size_t size
the number of elements in the storage
tree_quals_t quals
the qualifiers of the storage
const ssa_type_t * type
the internal storage type
const ssa_type_t * type
the public facing type of this symbol
vector_t * blocks
vector_t<ssa_block_t *>
tree_visibility_t visibility
const char * linkage_string
external name
typevec_t * locals
typevec_t<ssa_type_t>
const char * name
internal name
const ssa_type_t * result
ssa_type_closure_t closure
bool init
whether this value has been initialized
A vector with a fixed type size.
a generic vector of pointers
names_t names_new(size_t size, arena_t *arena)
char * begin_module(emit_t *emit, fs_t *fs, const ssa_module_t *mod)
char * get_step_name(emit_t *emit, const ssa_step_t *step)
char * get_block_name(emit_t *emit, const ssa_block_t *block)
char * get_step_from_block(emit_t *emit, const ssa_block_t *block, size_t index)
const char * type_to_string(const ssa_type_t *type, arena_t *arena)
emit_result_t debug_ssa(target_runtime_t *runtime, const ssa_result_t *ssa, target_emit_t *target)