lccrt/include/internal/lccrt_irv.h

479 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_irv.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_IRV_H
#define LCCRT_IRV_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "internal/lccrt_ctx.h"
/**
* Получить по битовому размеру целового типа его внутреннее название.
*/
#define lccrt_type_get_int_subtype_name( bs) \
( \
(bs) == 8 \
? LCCRT_INT_SUBTYPE_8 \
: ((bs) == 16 \
? LCCRT_INT_SUBTYPE_16 \
: ((bs) == 32 \
? LCCRT_INT_SUBTYPE_32 \
: ((bs) == 64 \
? LCCRT_INT_SUBTYPE_64 \
: ((bs) == 128 \
? LCCRT_INT_SUBTYPE_128 \
: LCCRT_INT_SUBTYPE_LAST)))) \
)
/**
* Получить по битовому размеру плавающего типа его внутреннее название.
*/
#define lccrt_type_get_float_subtype_name( bs) \
( \
(bs) == 32 \
? LCCRT_FLOAT_SUBTYPE_32 \
: ((bs) == 64 \
? LCCRT_FLOAT_SUBTYPE_64 \
: ((bs) == 80 \
? LCCRT_FLOAT_SUBTYPE_80 \
: ((bs) == 128 \
? LCCRT_FLOAT_SUBTYPE_128 \
: LCCRT_FLOAT_SUBTYPE_LAST))) \
)
/**
* Определение типов для списков.
*/
lccrt_ilist_head_typedef( lccrt_t_ptr);
lccrt_ilist_unit_typedef( lccrt_t_ptr);
lccrt_ilist_head_typedef( lccrt_f_ptr);
lccrt_ilist_unit_typedef( lccrt_f_ptr);
lccrt_ilist_head_typedef( lccrt_v_ptr);
lccrt_ilist_unit_typedef( lccrt_v_ptr);
lccrt_ilist_head_typedef( lccrt_vi_ptr);
lccrt_ilist_unit_typedef( lccrt_vi_ptr);
typedef struct lccrt_einfo_link_r *lccrt_einfo_link_ptr;
typedef struct lccrt_einfo_block_r *lccrt_einfo_block_ptr;
typedef lccrt_einfo_link_ptr lccrt_eil_ptr;
typedef lccrt_einfo_block_ptr lccrt_eib_ptr;
/**
* IR-тип данных.
*/
typedef struct lccrt_type_r
{
//lccrt_context_ptr ctx;
lccrt_module_ptr m;
lccrt_type_ptr parent; /* указуемый тип (для LCCRT_TYPE_PTR)
указуемый тип (для LCCRT_TYPE_NAME)
возвращаемый тип (для LCCRT_TYPE_FUNC)
элементарный тип (для LCCRT_TYPE_ARRAY)
элементарный тип (для LCCRT_TYPE_VLA_ARRAY)
элементарный тип (для LCCRT_TYPE_FIELD) */
lccrt_type_ptr *args; /* массив аргументов (для LCCRT_TYPE_FUNC)
массив элементов (для LCCRT_TYPE_STRUCT) */
uint64_t num_args; /* количество аргументов (для LCCRT_TYPE_FUNC)
количество элементов (для LCCRT_TYPE_ARRAY)
количество элементов (для LCCRT_TYPE_STRUCT) */
lccrt_var_ptr vnum; /* количество элементов (для LCCRT_TYPE_VLA_ARRAY) */
const char *sym_name; /* символьное имя (является ключем в ctx->types) */
const char *usr_name; /* пользовательское имя (является ключем в ctx->type_usr_names), может быть
пустым */
lccrt_ilist_unit( lccrt_t_ptr) types_unit; /* элемент списка типов */
uint64_t bytealign; /* байтовое выравнивание */
uint64_t bytesize; /* байтовый размер */
uint64_t byteshift; /* смещение от начала объемлющего типа (для LCCRT_TYPE_FIELD) */
uint64_t ident_num; /* уникальный номер типа */
lccrt_type_name_t type_name; /* идентификатор типа */
unsigned char bitsubshift; /* дополнительное битовое смещение (для LCCRT_TYPE_FIELD) */
unsigned char bitsubsize; /* количество хранимых бит (для LCCRT_TYPE_FIELD) */
unsigned char is_sign; /* знаковость (для LCCRT_TYPE_INT) */
unsigned char is_union; /* флаг совмещения полей (для LCCRT_TYPE_STRUCT) */
lccrt_check_type_t type_check;
} lccrt_type_t;
/**
* Основные IR-типы данных.
*/
typedef struct lccrt_types_std_r
{
int ptr_bytesize; /* байтовый размер указателей */
lccrt_type_ptr void_type; /* тип void */
lccrt_type_ptr bool_type; /* тип bool */
lccrt_type_ptr int_types[2][LCCRT_INT_SUBTYPE_LAST+1]; /* целые типы */
lccrt_type_ptr float_types[LCCRT_FLOAT_SUBTYPE_LAST+1]; /* плавающие типы */
lccrt_type_ptr ellipsis; /* тип для аргумента функции вида "..." */
lccrt_type_ptr intptr; /* целый тип по размеру эквивалентный указателю */
lccrt_type_ptr ptr_byte; /* указатель на uint8 */
lccrt_type_ptr ptr_char; /* указатель на sint8 */
lccrt_type_ptr ptr_intptr; /* указатель на intptr */
} lccrt_types_std_t;
/**
* Тип einfo-данных.
*/
typedef enum
{
LCCRT_EINFO_NULL = 0,
LCCRT_EINFO_INT64,
LCCRT_EINFO_STRUCT,
LCCRT_EINFO_UNION,
LCCRT_EINFO_ARRAY,
LCCRT_EINFO_RAW,
LCCRT_EINFO_LAST
} lccrt_einfo_type_t;
/**
* Указатель на einfo-данные.
*/
typedef struct
{
uint8_t type; /* тип einfo-данных */
union
{
uint64_t i64; // значение типа LCCRT_EINFO_INT64
lccrt_einfo_block_ptr ref; // указатель для типов LCCRT_EINFO_ARRAY, LCCRT_EINFO_STRUCT,
// LCCRT_EINFO_RAW, LCCRT_EINFO_UNION
} data;
} lccrt_einfo_handle_t;
/**
* Описание типа метаданных.
*/
typedef struct lccrt_einfo_tydescr_r
{
lccrt_einfo_tydescr_ptr next; /* общий список всех структур */
lccrt_einfo_type_t type; /* тип einfo-данных */
int num_flds; /* количество полей */
lccrt_module_ptr m; /* ссылка на модуль */
char *self_name; /* название структуры данных */
char **flds; /* массив с названиями полей */
lccrt_einfo_tydescr_ptr *types; /* массив с типами полей */
lccrt_check_type_t type_check;
} lccrt_einfo_tydescr_t;
/**
* Мета-данные.
*/
typedef struct lccrt_einfo_block_r
{
lccrt_einfo_block_ptr next; /* общий список всех данных */
uint8_t type; /* тип мета-данных */
int32_t num_args; /* количество полей для LCCRT_EINFO_STRUCT,
количество элементов для LCCRT_EINFO_ARRAY,
байтовый размер для LCCRT_EINFO_RAW */
int32_t max_args; /* длина выделения массива элементов для LCCRT_EINFO_ARRAY */
lccrt_einfo_tydescr_ptr tydescr; /* описание типов полей для LCCRT_EINFO_STRUCT, LCCRT_EINFO_UNION,
описание типа элемента для LCCRT_EINFO_ARRAY */
union
{
lccrt_einfo_handle_t *flds; /* значение полей для LCCRT_EINFO_STRUCT, LCCRT_EINFO_UNION */
lccrt_einfo_handle_t *elems; /* значение элементов LCCRT_EINFO_ARRAY */
uint8_t *rdata; /* данные для LCCRT_EINFO_RAW */
} data;
lccrt_check_type_t type_check;
} lccrt_einfo_block_t;
/**
* Элемент списка мета-данных.
*/
typedef struct lccrt_einfo_link_r
{
lccrt_einfo_link_ptr prev; /* ссылка на предыдущий элемент */
lccrt_einfo_link_ptr next; /* ссылка на следующий элемент */
lccrt_einfo_category_t ident; /* дескриптор свойства */
lccrt_einfo_handle_t value; /* значение свойства */
lccrt_check_type_t type_check;
} lccrt_einfo_link_t;
/**
* Размер диапазона кешируемых константных значений.
*/
#define LCCRT_MODULE_CARG_MIN (-32LL)
#define LCCRT_MODULE_CARG_MAX (+31LL)
#define LCCRT_MODULE_CARG_LEN (LCCRT_MODULE_CARG_MAX - LCCRT_MODULE_CARG_MIN + 1)
/**
* Модуль - аналог языковой единицы компиляции.
*/
typedef struct lccrt_module_r
{
lccrt_context_ptr ctx;
const char *name; /* название модуля */
const char *asm_text; /* asm-inline текст модуля */
uint64_t ident_num; /* уникальный идентификатор модуля */
lccrt_types_std_t types_std; /* основные типы данных */
lccrt_h_ptr types; /* хеш-таблица типов */
lccrt_h_ptr type_usr_names; /* хеш-таблица (пользовательскоеИмя -> тип) */
uint64_t type_max; /* счетчик типов */
lccrt_h_ptr gvars; /* соответствие имя->глобальнаяПеременная */
lccrt_h_ptr funcs; /* соответствие имя->функция */
uintptr_t einfo_ident; /* идентификатор для следующего класса метаданных */
lccrt_h_ptr einfo_cats; /* таблица названиеКатегории -> идентификаторКатегории */
lccrt_einfo_tydescr_ptr etydescrs_head; /* список всех блоков описания мета-данных */
lccrt_einfo_block_ptr eblocks_head; /* список всех блоков мета-данных */
lccrt_einfo_tydescr_ptr einfo_tyi64; /* описание типа для i64-einfo */
lccrt_einfo_tydescr_ptr einfo_tyraw; /* описание типа для raw-einfo */
lccrt_h_ptr einfo_tyarrs; /* таблица типЭлемента -> типМассив */
lccrt_h_ptr einfo_tysts; /* таблица тегНазвание -> типСтруктура */
lccrt_einfo_link_ptr einfo; /* собственные мета-данные модуля */
lccrt_ilist_head( lccrt_t_ptr) types_head; /* список всех типов */
lccrt_ilist_head( lccrt_v_ptr) gvars_head; /* список всех глобальных переменных */
lccrt_ilist_head( lccrt_f_ptr) funcs_head; /* список всех функций */
lccrt_ilist_head( lccrt_vi_ptr) varinits_head; /* список всех инициализаторов */
uint64_t funcs_num; /* нумерация функций */
uint64_t gvars_num; /* нумерация глобальных переменных */
uint64_t cargs_name_id; /* нумерация константных имен */
uint64_t global_name_id; /* нумерация глобальных имен */
lccrt_var_ptr carg_vars[2][LCCRT_MODULE_CARG_LEN]; /* переменные константные
аргументы [u32,u64][-32..+31] */
uint8_t is_ptr32; /* компиляция для 32-битной модели памяти */
uint8_t is_jit; /* компиляция в динамическом режиме */
lccrt_check_type_t type_check;
} lccrt_module_t;
/**
* Инициализатор переменной.
*/
typedef struct lccrt_varinit_r
{
lccrt_type_ptr type; /* ir-тип */
union lccrt_varinit_data_r
{
uint64_t ival; /* скалярное значение (для LCCRT_VARINIT_HEX) */
char *sval; /* массив байт (для LCCRT_VARINIT_STR) */
lccrt_varinit_ptr *vals; /* массив значений (для LCCRT_VARINIT_ARR) */
lccrt_var_ptr var; /* адрес переменной (для LCCRT_VARINIT_ADDR_VAR) */
struct lccrt_function_r *func; /* адрес функции (для LCCRT_VARINIT_ADDR_FUNC) */
} data;
lccrt_varinit_inittype_t init_type; /* разновидность инициализатора */
uint64_t num_elems; /* количество элементов (для LCCRT_VARINIT_ARR)
количество элементов (для LCCRT_VARINIT_STR)
смещение в байтах (для LCCRT_VARINIT_ADDR_VAR)
смещение в байтах (для LCCRT_VARINIT_ADDR_FUNC) */
lccrt_ilist_unit( lccrt_vi_ptr) varinits_unit; /* элемент списка инициализаторов */
lccrt_check_type_t type_check;
} lccrt_varinit_t;
/**
* Информация о способе линковке.
*/
typedef struct
{
lccrt_link_bind_t bnd; /* тип старшинства */
lccrt_link_visibility_t vis; /* тип видимости */
lccrt_link_tls_t tls; /* tls-тип */
uint8_t is_cnst; /* флаг неизменности значения ячейки памяти */
uint8_t is_alias; /* флаг алиаса */
} lccrt_asmlink_t;
/**
* Булевые атрибуты переменной (собираем вместе для экономии памяти).
*/
typedef enum
{
LCCRT_VAR_ATTR_USED, /* признак (скрытого) использования */
LCCRT_VAR_ATTR_COMMON, /* признак common-переменной */
LCCRT_VAR_ATTR_RESTRICT,
LCCRT_VAR_ATTR_LAST
} lccrt_var_attr_name_t;
/**
* Количество длинных слов (по 64 бита), которое необходимо для хранения значений
* всех атрибутов.
*/
#define LCCRT_VAR_ATTRS_LENGTH ((LCCRT_VAR_ATTR_LAST + 63) / 64)
/**
* Аналог языковой переменной.
*/
typedef struct lccrt_var_r
{
void *holder; /* полный контекст, модуль или функция (в зависимости от loc) */
const char *name; /* название переменной */
const char *asm_name; /* название в ассемблерном файле (для обычных переменных)
ассемблерный текст (для LCCRT_VAR_LOC_ASM) */
const char *section_name; /* название секции в ассемблерном файле */
const char *comdat; /* значение поля comdat (или 0) */
lccrt_varinit_ptr init_value; /* инициализатор переменной */
lccrt_type_ptr type; /* тип переменной */
lccrt_einfo_link_ptr einfo; /* мета-данные переменной */
lccrt_ilist_unit( lccrt_v_ptr) vars_unit; /* элемент списка переменных */
lccrt_var_loc_t loc; /* тип размещения переменной */
lccrt_asmlink_t link; /* тип связывания переменной */
uint64_t ident_num; /* идентификатор (внутри holder-контекста) */
unsigned align; /* минимальное выравнивание переменной */
int arg_num; /* номер аргумента среди аргументов функции (для LCCRT_VAR_LOC_ARG) */
int num_defs; /* количество использований переменной в качестве результата */
uint64_t attrs[LCCRT_VAR_ATTRS_LENGTH]; /* булевые атрибуты переменной */
lccrt_check_type_t type_check;
} lccrt_var_t;
/**
* Итератор для ссылки на операции.
*/
typedef struct lccrt_oper_iterator_r
{
lccrt_context_ptr ctx;
lccrt_oper_ptr prev;
lccrt_oper_ptr next;
lccrt_oper_ptr last; /* последняя, созданная с помощью итератора, операция */
int is_forward; /* флаг замены prev новой операцией, иначе - замена next */
lccrt_check_type_t type_check;
} lccrt_oper_iterator_t;
#define LCCRT_GET_BYTE( d, k) (((unsigned char *)(d))[k])
#define LCCRT_LINK_BYTE_BND( d) LCCRT_GET_BYTE( d, 0)
#define LCCRT_LINK_BYTE_VIS( d) LCCRT_GET_BYTE( d, 1)
#define LCCRT_LINK_BYTE_TLS( d) LCCRT_GET_BYTE( d, 2)
#define LCCRT_LINK_BYTE_CST( d) LCCRT_GET_BYTE( d, 3)
#define LCCRT_LINK_BYTE_ALS( d) LCCRT_GET_BYTE( d, 4)
/**
* Булевые атрибуты функции (собираем вместе для экономии памяти).
*/
typedef enum
{
LCCRT_FUNC_ATTR_DECLARATION, /* признак заголовочного объявления */
LCCRT_FUNC_ATTR_BUILTIN, /* признак встроенной функции */
LCCRT_FUNC_ATTR_USED, /* признак "used" */
LCCRT_FUNC_ATTR_EXTERN_INLINE, /* признак declare-функции, для которой доступно тело
функции, но только для оптимизаций типа inline */
LCCRT_FUNC_ATTR_DOES_NOT_THROW, /* признак "does not throw" */
LCCRT_FUNC_ATTR_JIT_PROFGEN, /* признак генерации профиля */
LCCRT_FUNC_ATTR_LAST
} lccrt_function_attr_name_t;
/**
* Количество длинных слов (по 64 бита), которое необходимо для хранения значений
* всех атрибутов.
*/
#define LCCRT_FUNC_ATTRS_LENGTH ((LCCRT_FUNC_ATTR_LAST + 63) / 64)
/**
* Функция.
*/
typedef struct lccrt_function_r
{
lccrt_context_ptr ctx;
lccrt_module_ptr module; /* охватывающий модуль */
const char *name; /* имя функции */
const char *asm_name; /* имя функции в ассемблерном файле */
const char *section; /* название секции в ассемблерном файле (или 0) */
const char *comdat; /* значение поля comdat (или 0) */
lccrt_hash_ptr lvars; /* локальные переменные функции */
lccrt_asmlink_t link; /* информация о линковке */
lccrt_type_ptr sig_type; /* сигнатура функции */
lccrt_var_ptr *args; /* аргументы функции */
lccrt_var_ptr *sysargs; /* (специальные) аргументы функции */
lccrt_function_jit_info_ptr jit_info; /* данные для динамической компиляции */
lccrt_einfo_link_ptr einfo; /* мета-данные функции */
uint64_t ident_num; /* уникальный идентификатор функции (внутри модуля) */
uint32_t sysargs_num; /* нумерация (специальных) аргументов функции */
uint32_t lvars_num; /* нумерация локальных переменных */
uint32_t opers_num; /* нумерация операций */
uint32_t local_name_id; /* нумерация локальных имен */
lccrt_ilist_unit( lccrt_f_ptr) funcs_unit; /* элемент списка функций */
lccrt_oper_ptr start; /* стартовая ir-операция */
lccrt_oper_iterator_t cur; /* ir-итератор */
lccrt_ilist_head( lccrt_v_ptr) lvars_head; /* список всех локальных переменных */
lccrt_function_init_type_t init_type; /* тип инициализации для функции */
int init_priority; /* порядок инициализации функции */
uint64_t attrs[LCCRT_FUNC_ATTRS_LENGTH]; /* булевые атрибуты функции */
lccrt_check_type_t type_check;
} lccrt_function_t;
/**
* IR-операция.
*/
typedef struct lccrt_oper_r
{
lccrt_function_ptr func;
uint64_t ident_num; /* идентификатор операции */
lccrt_oper_ptr prev; /* предыдущая операция */
lccrt_oper_ptr next; /* следующая операция */
lccrt_var_ptr res; /* результат операции */
lccrt_arg_t *args; /* аргументы операции */
const char *label; /* метка операции (для LCCRT_OPER_LABEL) */
lccrt_einfo_link_ptr einfo; /* мета-данные операции */
lccrt_oper_name_t name; /* название операции */
int32_t num_args; /* количество аргументов */
int32_t num_sysargs; /* количество (специальных) аргументов */
char is_volatile; /* флаг volatile-обращение */
char is_atomic; /* флаг atomic-обращение */
char is_cleanup; /* флаг cleanup-landingpad'а */
lccrt_check_type_t type_check;
} lccrt_oper_t;
extern lccrt_t_ptr lccrt_type_make_simple( lccrt_m_ptr m, lccrt_type_name_t name, const char *sym_name,
int is_sign, uint64_t bytealign, uint64_t bytesize);
extern void lccrt_type_delete( lccrt_t_ptr type);
extern void lccrt_type_set_parent( lccrt_type_ptr type, lccrt_type_ptr parent);
extern void lccrt_type_set_arg( lccrt_type_ptr type, int arg_num, lccrt_type_ptr arg);
extern lccrt_t_ptr lccrt_type_import( lccrt_m_ptr m, lccrt_t_ptr type, lccrt_h_ptr types);
extern lccrt_link_t lccrt_link_conv( lccrt_asmlink_t link);
extern lccrt_asmlink_t lccrt_link_unpack( lccrt_link_t link);
extern void lccrt_varinit_delete( lccrt_vi_ptr vi);
extern void lccrt_var_copy_attrs( lccrt_v_ptr dst, lccrt_v_ptr src);
extern void lccrt_module_delete_data( lccrt_m_ptr m);
extern char *lccrt_module_name_new_global( lccrt_m_ptr m, const char *name);
extern lccrt_hash_ptr lccrt_module_get_types( lccrt_m_ptr m);
extern lccrt_hash_ptr lccrt_module_get_gvars( lccrt_m_ptr m);
extern lccrt_hash_ptr lccrt_module_get_funcs( lccrt_m_ptr m);
extern uint64_t lccrt_module_get_type_max( lccrt_module_ptr m);
extern uint64_t lccrt_module_get_func_max( lccrt_module_ptr m);
extern void lccrt_function_delete( lccrt_f_ptr f);
extern int lccrt_function_get_attr_jit_profgen( lccrt_f_ptr func);
extern int lccrt_function_set_attr_jit_profgen( lccrt_f_ptr func, int value);
extern char *lccrt_function_name_new_local( lccrt_f_ptr f, const char *name);
extern void lccrt_function_clear( lccrt_function_ptr f);
extern lccrt_f_ptr lccrt_function_copy( lccrt_m_ptr m, lccrt_f_ptr f, const char *name,
const char *asm_name, lccrt_link_t ln, lccrt_h_ptr types);
extern lccrt_o_ptr lccrt_function_call_inline( lccrt_o_ptr call, lccrt_f_ptr call_func);
extern lccrt_var_ptr lccrt_function_var_import( lccrt_f_ptr dst_func, lccrt_f_ptr src_func,
lccrt_v_ptr v, lccrt_h_ptr vars, lccrt_h_ptr types,
int is_same_name);
extern void lccrt_function_init_jit_info( lccrt_f_ptr f, lccrt_f_ptr root,
lccrt_v_ptr func_entry, lccrt_v_ptr profgen_tls);
extern lccrt_einfo_handle_t lccrt_einfo_get_handle( lccrt_einfo_reference_t value);
extern int lccrt_einfo_is_scalar( lccrt_einfo_reference_t einfo);
extern lccrt_eir_t lccrt_einfo_get_block_reference( lccrt_eib_ptr eblock);
extern void lccrt_einfo_block_delete( lccrt_einfo_block_ptr eblock);
extern void lccrt_einfo_tydescr_delete( lccrt_einfo_tydescr_ptr etyde);
extern lccrt_einfo_link_ptr lccrt_einfo_link_new( lccrt_m_ptr m, lccrt_eil_ptr elink,
lccrt_eic_t ecat, lccrt_eir_t value);
extern lccrt_einfo_link_ptr lccrt_einfo_link_push_value( lccrt_m_ptr m, lccrt_eil_ptr elink0,
lccrt_eic_t ecat, lccrt_eir_t value);
extern lccrt_einfo_link_ptr lccrt_einfo_link_delete_chain( lccrt_einfo_link_ptr elink);
extern lccrt_einfo_link_ptr lccrt_einfo_link_find( lccrt_einfo_link_ptr elink, lccrt_eic_t ecat);
extern void lccrt_einfo_link_delete( lccrt_einfo_link_ptr elink);
extern lccrt_einfo_reference_t lccrt_einfo_link_get_value( lccrt_einfo_link_ptr elink);
extern void lccrt_module_einfo_number( lccrt_m_ptr m, lccrt_h_ptr btbl, lccrt_h_ptr ttbl);
extern int lccrt_var_get_num_defs( lccrt_v_ptr v);
extern int lccrt_var_set_num_defs( lccrt_v_ptr v, int num_defs);
extern const char *lccrt_oper_get_name_str( lccrt_oper_ptr op);
extern void lccrt_oper_print_opers( lccrt_o_ptr op1, lccrt_o_ptr op2);
extern int lccrt_oper_get_str_opername( const char *str);
#if defined(__cplusplus)
}
#endif
#endif /* LCCRT_IRV_H */