51 for (
size_t i = 0; i < len; i++)
54 add_global(vm, global);
70 case eOperandEmpty:
return NULL;
71 case eOperandImm:
return operand.
value;
73 case eOperandGlobal: {
75 ssa_opt_global(vm->
vm, (
void*)global);
88 case eOperandGlobal: {
90 ssa_opt_global(vm->
vm, (
void*)global);
135 if (!check_init(vm, operand)) {
return operand; }
148 mpz_neg(result, literal->
digit);
153 mpz_abs(result, literal->
digit);
158 mpz_com(result, literal->
digit);
180 if (!check_init(vm, lhs)) {
return lhs; }
181 if (!check_init(vm, rhs)) {
return rhs; }
195 mpz_add(result, lhs_literal->
digit, rhs_literal->
digit);
198 mpz_sub(result, lhs_literal->
digit, rhs_literal->
digit);
201 mpz_mul(result, lhs_literal->
digit, rhs_literal->
digit);
204 if (mpz_cmp_ui(rhs_literal->
digit, 0) == 0)
209 mpz_divexact(result, lhs_literal->
digit, rhs_literal->
digit);
212 if (mpz_cmp_ui(rhs_literal->
digit, 0) == 0)
217 mpz_mod(result, lhs_literal->
digit, rhs_literal->
digit);
222 mpz_mul_2exp(result, lhs_literal->
digit, mpz_get_ui(rhs_literal->
digit));
225 mpz_fdiv_q_2exp(result, lhs_literal->
digit, mpz_get_ui(rhs_literal->
digit));
228 mpz_xor(result, lhs_literal->
digit, rhs_literal->
digit);
261 if (value->
value == eValueLiteral)
267 if (value->
value == eValueRelative)
295 return cast_to_opaque(type, value);
298 return cast_to_pointer(type, value);
301 return cast_to_digit(value);
312 case eOpLoad:
return ssa_opt_load(vm, step->
load);
313 case eOpReturn:
return ssa_opt_return(vm, step->
ret);
315 case eOpUnary:
return ssa_opt_unary(vm, step->
unary);
316 case eOpBinary:
return ssa_opt_binary(vm, step->
binary);
317 case eOpCast:
return ssa_opt_cast(vm, step->
cast);
326 for (
size_t i = 0; i < len; i++)
340 if (global->
value != NULL)
348 .return_value = NULL,
352 ssa_opt_block(&scope, global->
entry);
374 for (
size_t i = 0; i < len; i++)
377 add_globals(&vm, mod);
384 ssa_opt_global(&vm, global);
ssa_value_t * ssa_value_bool(const ssa_type_t *type, bool value)
ssa_value_t * ssa_value_relative(const ssa_type_t *type, ssa_relative_value_t value)
ssa_value_t * ssa_value_literal(const ssa_type_t *type, ssa_literal_value_t value)
ssa_value_t * ssa_value_digit(const ssa_type_t *type, const mpz_t value)
#define CT_PUREFN
mark a function as pure, always returns the same value for the same arguments
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
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_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_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_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_contains(const set_t *set, const void *key)
check if a set contains a key
CT_NODISCARD CT_PUREFN CT_STD_API bool set_has_next(set_iter_t *iter)
check if a set iterator has more items
CT_NODISCARD CT_SCAN_API node_t * node_builtin(const char *name, arena_t *arena)
get the builtin node node used for drivers that declare builtin symbols
CT_NOTIFY_API event_builder_t msg_notify(INOUT_NOTNULL logger_t *logs, const diagnostic_t *diagnostic, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
notify the logger of a new message
#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 void ssa_opt(logger_t *reports, ssa_result_t result, arena_t *arena)
Optimize a given module.
CT_CONSTFN CT_NODISCARD CT_SSA_API const char * ssa_type_name(STA_IN_RANGE(0, eTypeCount - 1) ssa_kind_t kind)
CT_TREE_API const char * binary_name(binary_t op)
get the pretty name of a binary operator
binary_t
all binary operators
unary_t
all unary operators
CT_TREE_API const char * unary_name(unary_t op)
get the pretty name of a unary operator
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_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_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
a position in a source file
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 * global
const ssa_value_t * return_value
const ssa_symbol_t * symbol
ssa_block_t * entry
entry block
const ssa_value_t * value
the value of this symbol, must always be set for globals
const char * name
internal name
ssa_literal_value_t literal
bool init
whether this value has been initialized
ssa_relative_value_t relative
A vector with a fixed type size.