113     symbol->
type = ssa_type;
 
  114     symbol->
value = NULL;
 
  115     symbol->
entry = NULL;
 
  127     return symbol_new(ssa, name, 
tree_get_type(tree), *attrib, storage);
 
  146     return create_new_storage(types, type, 
size, quals);
 
  153     ssa_symbol_t *
self = symbol_create_decl(ssa, tree, storage);
 
  157     for (
size_t i = 0; i < locals; i++)
 
  176     for (
size_t i = 0; i < params; i++)
 
  211         .visibility = eVisiblePrivate,
 
  218     ssa_symbol_t *it = symbol_new(ssa, NULL, type, attribs, storage);
 
  258         .
kind = eOperandEmpty
 
  266         .
kind = eOperandBlock,
 
  304             .then = operand_bb(then_block),
 
  305             .other = else_block ? operand_bb(else_block) : operand_bb(tail_block)
 
  310         .
kind = eOperandBlock,
 
  321     compile_tree(ssa, branch->
then);
 
  322     bb_add_step(then_block, jump_to_tail);
 
  324     if (branch->
other != NULL)
 
  327         compile_tree(ssa, branch->
other);
 
  328         bb_add_step(else_block, jump_to_tail);
 
  359         .exit_loop = tail_block,
 
  364         .
kind = eOperandBlock,
 
  369         .
kind = eOperandBlock,
 
  379     add_step(ssa, enter_loop);
 
  387             .then = operand_bb(body_block),
 
  394     compile_tree(ssa, tree->
then);
 
  402     add_step(ssa, repeat_loop);
 
  421         return add_step(ssa, step);
 
  423     case eJumpContinue: {
 
  430         return add_step(ssa, step);
 
  433     default: 
CT_NEVER(
"unhandled jump %d", jump);
 
  437 static size_t get_field_index(
const tree_t *ty, 
const tree_t *field)
 
  452     size_t index = get_field_index(ty->
ptr, tree->
field);
 
  461     return add_step(ssa, step);
 
  471     case eTreeExprEmpty: {
 
  473             .
kind = eOperandEmpty
 
  478     case eTreeDeclCase: {
 
  489     case eTreeExprUnit: {
 
  497     case eTreeExprString: {
 
  501             .
kind = eOperandGlobal,
 
  507     case eTreeExprCast: {
 
  516         return add_step(ssa, step);
 
  519     case eTreeExprOffset: {
 
  530         return add_step(ssa, step);
 
  533     case eTreeExprField: {
 
  534         return get_field(ssa, tree);
 
  537     case eTreeExprUnary: {
 
  546         return add_step(ssa, step);
 
  549     case eTreeExprBinary: {
 
  560         return add_step(ssa, step);
 
  563     case eTreeDeclGlobal: {
 
  570             .
kind = eOperandGlobal,
 
  577     case eTreeExprLoad: {
 
  585         return add_step(ssa, step);
 
  588     case eTreeStmtJump: {
 
  590         CTASSERTF(target != NULL, 
"loop not found");
 
  592         return add_jump(ssa, target, tree->
jump);
 
  595     case eTreeExprAddressOf: {
 
  603         return add_step(ssa, step);
 
  606     case eTreeStmtBlock: {
 
  608         for (
size_t i = 0; i < len; i++)
 
  611             compile_tree(ssa, stmt);
 
  614         return operand_empty();
 
  617     case eTreeStmtAssign: {
 
  628         return add_step(ssa, step);
 
  631     case eTreeDeclLocal: {
 
  636             .
kind = eOperandLocal,
 
  642     case eTreeDeclParam: {
 
  647             .
kind = eOperandParam,
 
  653     case eTreeStmtReturn: {
 
  661         return add_step(ssa, step);
 
  664     case eTreeExprCall: {
 
  668         for (
size_t i = 0; i < len; i++)
 
  683         return add_step(ssa, step);
 
  686     case eTreeDeclFunction: {
 
  692             .
kind = eOperandFunction,
 
  699     case eTreeStmtBranch:
 
  700         return compile_branch(ssa, tree);
 
  702     case eTreeExprCompare: {
 
  715         return add_step(ssa, step);
 
  719         return compile_loop(ssa, tree);
 
  721     case eTreeExprAlignOf: {
 
  729         return add_step(ssa, step);
 
  732     case eTreeExprSizeOf: {
 
  740         return add_step(ssa, step);
 
  743     case eTreeExprOffsetOf: {
 
  750                 .index = get_field_index(tree->
object, tree->
field)
 
  754         return add_step(ssa, step);
 
  771         ssa_symbol_t *global = symbol_create_decl(ssa, tree, create_storage_for_decl(ssa->
types, tree));
 
  827         forward_module(ssa, entry.
value);
 
  899     for (
size_t i = 0; i < len; i++)
 
  938     for (
size_t i = 0; i < len; i++)
 
  941         forward_module(&ssa, mod);
 
  955         begin_compile(&ssa, global);
 
  995         begin_compile(&ssa, symbol);
 
 1001             compile_tree(&ssa, body);
 
 1006                 "function `%s` has no implementation, but is not an imported symbol (linkage=%s)",
 
 1022 static const char *
const kTypeNameTable[
eTypeCount] = {
 
 1023 #define SSA_KIND(ID, NAME) [ID] = (NAME), 
 1027 static const char *
const kOperandNameTable[
eOperandCount] = {
 
 1028 #define SSA_OPERAND(ID, NAME) [ID] = (NAME), 
 1032 static const char *
const kOpCodeNameTable[
eOpCount] = {
 
 1033 #define SSA_OPCODE(ID, NAME) [ID] = (NAME), 
 1037 static const char *
const kValueNameTable[
eValueCount] = {
 
 1038 #define SSA_VALUE(ID, NAME) [ID] = (NAME), 
 1047     return kTypeNameTable[kind];
 
 1055     return kOperandNameTable[kind];
 
 1063     return kOpCodeNameTable[opcode];
 
 1071     return kValueNameTable[value];
 
CT_PUREFN CT_TREE_API const char * tree_get_name(const tree_t *tree)
CT_PUREFN CT_TREE_API const tree_t * tree_get_type(const tree_t *tree)
CT_PUREFN CT_TREE_API bool tree_is(const tree_t *self, tree_kind_t kind)
ssa_operand_t operand_value(ssa_value_t *value)
ssa_value_t * ssa_value_string(const ssa_type_t *type, text_view_t text)
ssa_type_t * ssa_type_create_cached(map_t *cache, const tree_t *type)
ssa_value_t * ssa_value_from(map_t *types, const tree_t *expr)
ssa_value_t * ssa_value_noinit(const ssa_type_t *type)
void count_modules(ssa_map_sizes_t *sizes, const tree_t *tree)
STA_DECL const char * ssa_value_name(ssa_value_state_t value)
STA_DECL const char * ssa_type_name(ssa_kind_t kind)
ssa_map_sizes_t predict_maps(vector_t *mods)
STA_DECL const char * ssa_opcode_name(ssa_opcode_t opcode)
STA_DECL const char * ssa_opkind_name(ssa_opkind_t kind)
CT_TREE_API tree_quals_t tree_get_storage_quals(const tree_t *self)
CT_PUREFN CT_TREE_API bool tree_ty_is_address(const tree_t *type)
CT_TREE_API const char * tree_to_string(const tree_t *self)
CT_TREE_API const tree_t * tree_get_storage_type(const tree_t *self)
CT_TREE_API const tree_attribs_t * tree_get_attrib(const tree_t *self)
CT_PUREFN CT_TREE_API const tree_t * tree_ty_load_type(const tree_t *self)
get the type of a type after it has been loaded
CT_TREE_API size_t tree_get_storage_size(const tree_t *self)
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
STA_RET_STRING colour_t idx
CT_NODISCARD CT_PUREFN CT_STD_API size_t map_count(const map_t *map)
get the number of key-value pairs in a map
CT_NODISCARD CT_PUREFN CT_STD_API void * map_get_default(const map_t *map, const void *key, void *other)
get a value from a map or a default value
CT_NODISCARD CT_STD_API map_t * map_optimal(size_t size, hash_info_t info, arena_t *arena)
create a new map with an optimal size
CT_NODISCARD CT_PUREFN CT_STD_API bool map_has_next(const map_iter_t *iter)
check if a map iterator has more elements
CT_STD_API void map_reset(map_t *map)
clear all key-value pairs from a map
CT_STD_API bool map_delete(map_t *map, const void *key)
delete a key-value pair from a map
CT_NODISCARD CT_PUREFN CT_STD_API map_iter_t map_iter(const map_t *map)
create a new map iterator
CT_STD_API void map_set(map_t *map, const void *key, void *value)
set a key-value pair in a map
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_NOALIAS CT_STD_API map_entry_t map_next(map_iter_t *iter)
get the next key-value pair from a map iterator
CT_NODISCARD CT_STD_API set_t * set_new(size_t size, hash_info_t info, arena_t *arena)
create a new set
CT_STD_API const void * set_add(set_t *set, const void *key)
add a key to a set
CT_NODISCARD CT_ARENA_API void * arena_memdup(STA_READS(size) const void *ptr, size_t size, arena_t *arena)
duplicate a memory region from a custom allocator duplicate a region of memory and return a pointer t...
#define ARENA_IDENTIFY(ptr, name, parent, arena)
rename and reparent a pointer in a custom allocator
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
#define CT_ASSERT_RANGE(value, min, max)
assert that a value is in a range inclusive bounds check
#define CT_NEVER(...)
assert that a code path is never reached
#define CTASSERT(expr)
assert a condition, prints the condition as a message
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
STA_DECL ssa_result_t ssa_compile(vector_t *mods, arena_t *arena)
compile a set of trees into their ssa form
tree_jump_t
the type of jump
CT_TREE_API const char * linkage_string(tree_linkage_t link)
get the name of a linkage
tree_quals_t
all type qualifiers
CT_TREE_API map_t * tree_module_tag(const tree_t *self, size_t tag)
CT_STD_API const hash_info_t kTypeInfoPtr
type information for a generic pointer this operates on the pointer itself and not the data it points...
CT_STD_API const hash_info_t kTypeInfoText
type information for a text_view_t
CT_STD_API void typevec_set(typevec_t *vec, size_t index, const void *src)
set an element in the vector
CT_NODISCARD CT_STD_API typevec_t * typevec_of(size_t width, size_t len, arena_t *arena)
create a new typed vector with an initial size and length
CT_STD_API void * typevec_push(typevec_t *vec, const void *src)
push a value onto the vector
CT_NODISCARD CT_PUREFN CT_STD_API size_t typevec_len(const typevec_t *vec)
get the length of a vector
CT_NODISCARD CT_STD_API typevec_t * typevec_new(size_t width, size_t len, arena_t *arena)
create a new typed vector on the heap
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_STD_API void vector_push(vector_t **vector, void *value)
push a value onto the end of a vector
CT_PUREFN CT_STD_API size_t vector_find(vector_t *vector, const void *element)
find an element in a vector searches via pointer equality
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
a key-value pair in a map
const void * key
the key of this entry
void * value
the value of this entry
the ssa compilation context
map_t * symbol_locals
all locals in the current symbol map<tree, size_t>
map_t * types
all types in the program map<tree, ssa_type>
map_t * symbol_deps
direct dependencies between symbols dependecies are a cyclic graph, this is a map of the edges map<ss...
size_t string_count
all strings in the program map_t<text_view_t*, ssa_symbol>
vector_t * modules
result data
map_t * globals
all globals in the program map<tree, ssa_symbol>
map_t * symbol_loops
all loops in the current symbol map<tree, ssa_loop>
ssa_module_t * current_module
the current module being compiled
ssa_symbol_t * current_symbol
the current symbol being compiled can be a function or a global
map_t * functions
all functions in the program map<tree, ssa_symbol>
map_t * module_lookup
map of symbol to its source module map<ssa_symbol, ssa_module> TODO: this is stupid
ssa_block_t * current_block
the current block being compiled
arena_t * arena
internal data
ssa_block_t * enter_loop
the block to jump to when continuing the loop
ssa_block_t * exit_loop
the block to jump to when exiting the loop
a prediction of how many items will be in each map this is not a hard limit, but a hint to the alloca...
size_t types
the number of types in the program
size_t deps
the number of dependencies between symbols
size_t modules
the number of modules in the program
size_t globals
the number of globals in the program
size_t functions
the number of functions in the program
vector_t * types
vector<ssa_type_t> all types used by this module
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
ssa underlying storage type
const ssa_type_t * type
the internal storage type
ssa_block_t * entry
entry block
const ssa_type_t * type
the public facing type of this symbol
vector_t * blocks
vector_t<ssa_block_t *>
ssa_storage_t storage
the backing storage for this symbol
tree_visibility_t visibility
typevec_t * params
typevec_t<ssa_type_t>
const char * linkage_string
external name
const ssa_value_t * value
the value of this symbol, must always be set for globals
typevec_t * locals
typevec_t<ssa_type_t>
const char * name
internal name
a non-owning view of text
size_t length
the number of characters in the text
tree_visibility_t visibility
the visibility of the declaration
const char * mangle
override the mangle of the declaration
tree_linkage_t link
the link type of the declaration
A vector with a fixed type size.
a generic vector of pointers