mie: ir: implement deferred resolution of op arguments
This commit is contained in:
@@ -327,7 +327,10 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
|
||||
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
{
|
||||
if (op->op_flags & MIE_OP_F_RESOLVED) {
|
||||
bool fully_resolved = MIE_TEST_FLAGS(
|
||||
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARGS_RESOLVED);
|
||||
|
||||
if (fully_resolved) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -367,7 +370,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
free(op->op_name);
|
||||
op->op_name = NULL;
|
||||
|
||||
op->op_flags |= MIE_OP_F_RESOLVED;
|
||||
op->op_flags |= MIE_OP_F_OP_RESOLVED;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -421,7 +424,7 @@ struct mie_type *mie_ctx_get_type(
|
||||
|
||||
struct mie_dialect_type *type_info
|
||||
= mie_ctx_get_dialect_type(ctx, dialect_name, type_name);
|
||||
if (!type_info || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED)) {
|
||||
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
|
||||
/* cannot initialise unknown or parametised types */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,12 @@ struct mie_ctx {
|
||||
b_hashmap *ctx_sel_cache;
|
||||
b_hashmap *ctx_string_cache;
|
||||
#endif
|
||||
/* map of struct mie_dialect */
|
||||
struct mie_id_map ctx_dialects;
|
||||
/* map of struct mie_type */
|
||||
struct mie_id_map ctx_types;
|
||||
/* map of struct mie_trait */
|
||||
struct mie_id_map ctx_traits;
|
||||
|
||||
struct mie_int_cache *ctx_ints;
|
||||
struct mie_index_cache *ctx_indices;
|
||||
@@ -38,6 +42,8 @@ MIE_API struct mie_dialect_type *mie_ctx_get_dialect_type(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_trait(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_storage_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
|
||||
MIE_API struct mie_type *mie_ctx_get_function_type(
|
||||
|
||||
@@ -11,13 +11,18 @@ struct mie_ctx;
|
||||
|
||||
struct mie_dialect_op;
|
||||
struct mie_dialect_type;
|
||||
struct mie_trait_definition;
|
||||
|
||||
struct mie_dialect {
|
||||
mie_id d_id;
|
||||
char *d_name;
|
||||
|
||||
/* map of struct mie_dialect_op */
|
||||
struct mie_id_map d_ops;
|
||||
/* map of struct mie_dialect_type */
|
||||
struct mie_id_map d_types;
|
||||
/* map of struct mie_trait_definition */
|
||||
struct mie_id_map d_traits;
|
||||
};
|
||||
|
||||
MIE_API struct mie_dialect *mie_dialect_create(
|
||||
@@ -27,5 +32,7 @@ MIE_API const struct mie_dialect_op *mie_dialect_get_op(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_dialect_type *mie_dialect_get_type(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,16 +5,98 @@
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/id.h>
|
||||
#include <mie/status.h>
|
||||
#include <mie/trait/trait-table.h>
|
||||
|
||||
#define MIE_OP_MAX_PARAMS 8
|
||||
#define MIE_OP_MAX_RESULTS 8
|
||||
|
||||
struct mie_op;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
|
||||
enum mie_op_trait {
|
||||
MIE_OP_TRAIT_NONE = 0x00u,
|
||||
|
||||
/* this is a graph op. references to it by name must be prefixed with +
|
||||
* and the op can only be used within graph regions.
|
||||
* a graph op can have the same name as a regular or non-graph op. */
|
||||
MIE_OP_TRAIT_GRAPH_ONLY = 0x01u,
|
||||
|
||||
/* this is a non-graph op. this op cannot be used within graph regions */
|
||||
MIE_OP_TRAIT_NO_GRAPH = 0x02u,
|
||||
|
||||
/* regions of an op that has this trait are graph regions. graph regions
|
||||
* cannot have more than one block, and the entry block must be unnamed
|
||||
* with no parameters. However, graph ops can be used. */
|
||||
MIE_OP_TRAIT_GRAPH_SCOPE = 0x04u,
|
||||
|
||||
/* regions of an op that has this trait cannot capture or reference
|
||||
* values defined in the enclosing scope. */
|
||||
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
|
||||
};
|
||||
|
||||
enum mie_op_param_type {
|
||||
/* op has no parameter */
|
||||
MIE_OP_PARTYPE_NONE = 0,
|
||||
/* op has a parameter of any type. */
|
||||
MIE_OP_PARTYPE_ANY,
|
||||
/* op has a parameter of a fixed, named type. */
|
||||
MIE_OP_PARTYPE_TYPE_NAME,
|
||||
/* op has a parameter whose type matches the type of an attribute value */
|
||||
MIE_OP_PARTYPE_ATTRIB_VAL,
|
||||
};
|
||||
|
||||
enum mie_op_result_type {
|
||||
/* op has no result */
|
||||
MIE_OP_RESTYPE_NONE = 0,
|
||||
/* op has a result of any type. */
|
||||
MIE_OP_RESTYPE_ANY,
|
||||
/* op has a result of a fixed, named type. */
|
||||
MIE_OP_RESTYPE_TYPE_NAME,
|
||||
/* op has a result whose type matches the type of an input parameter */
|
||||
MIE_OP_RESTYPE_IN_VAL,
|
||||
/* op has a result whose type matches the type of an attribute value */
|
||||
MIE_OP_RESTYPE_ATTRIB_VAL,
|
||||
};
|
||||
|
||||
struct mie_op_param {
|
||||
enum mie_op_param_type param_type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *t_dialect;
|
||||
/* this can be NULL, in which case any type from the
|
||||
* dialect named in t_dialect will be accepted. */
|
||||
const char *t_name;
|
||||
} param_type_name;
|
||||
|
||||
const char *param_attrib;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op_result {
|
||||
enum mie_op_result_type r_type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *t_dialect;
|
||||
const char *t_name;
|
||||
} r_type_name;
|
||||
|
||||
unsigned int r_in_index;
|
||||
const char *r_attrib;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_dialect_op {
|
||||
mie_id op_id;
|
||||
struct mie_dialect *op_parent;
|
||||
char *op_name;
|
||||
|
||||
struct mie_trait_table op_traits;
|
||||
const struct mie_op_param op_params[MIE_OP_MAX_PARAMS];
|
||||
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
|
||||
|
||||
enum mie_status (*op_print)(const struct mie_op *, b_stream *);
|
||||
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
|
||||
};
|
||||
|
||||
@@ -5,19 +5,28 @@
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/id.h>
|
||||
#include <mie/status.h>
|
||||
#include <mie/trait/trait-table.h>
|
||||
|
||||
struct mie_type;
|
||||
struct mie_value;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
|
||||
enum mie_dialect_type_flags {
|
||||
MIE_DIALECT_TYPE_PARAMETISED = 0x01u,
|
||||
enum mie_type_trait {
|
||||
/* this type is parametised. one or more arguments are required to create
|
||||
* a corresponding mie_type instance. in textual IR, references to this
|
||||
* type will be followed by a set of arguments surrounded
|
||||
* by <angle brackets>. */
|
||||
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
|
||||
|
||||
/* this type can only be used within graph regions. unlike graph ops,
|
||||
* no special prefix is required */
|
||||
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_dialect_type {
|
||||
mie_id ty_id;
|
||||
enum mie_dialect_type_flags ty_flags;
|
||||
struct mie_trait_table ty_traits;
|
||||
struct mie_dialect *ty_parent;
|
||||
char *ty_name;
|
||||
|
||||
|
||||
@@ -3,21 +3,23 @@
|
||||
|
||||
#include "mie/vector.h"
|
||||
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
struct mie_type;
|
||||
|
||||
struct mie_value;
|
||||
struct mie_block;
|
||||
struct mie_region;
|
||||
struct mie_register;
|
||||
|
||||
struct mie_dialect;
|
||||
struct mie_dialect_op;
|
||||
|
||||
enum mie_op_flags {
|
||||
MIE_OP_F_RESOLVED = 0x01u,
|
||||
MIE_OP_F_OP_RESOLVED = 0x01u,
|
||||
MIE_OP_F_ARGS_RESOLVED = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_op_successor {
|
||||
@@ -30,6 +32,16 @@ struct mie_op_attribute {
|
||||
struct mie_value *attrib_value;
|
||||
};
|
||||
|
||||
struct mie_op_arg {
|
||||
struct mie_file_span arg_span;
|
||||
union {
|
||||
/* only valid if the parent op's F_ARGS_RESOLVED flag is set */
|
||||
struct mie_register *arg_value;
|
||||
/* only valid if the parent op's F_ARGS_RESOLVED flag is NOT set */
|
||||
struct mie_register_ref arg_unresolved;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op {
|
||||
enum mie_op_flags op_flags;
|
||||
|
||||
@@ -37,13 +49,14 @@ struct mie_op {
|
||||
const struct mie_dialect *op_dialect;
|
||||
const struct mie_dialect_op *op_info;
|
||||
|
||||
/* this pointer is only valid if the F_RESOLVED flag is NOT set */
|
||||
struct mie_file_span op_name_span;
|
||||
/* only valid if the F_RESOLVED flag is NOT set */
|
||||
char *op_name;
|
||||
|
||||
MIE_VECTOR_DECLARE(struct mie_region, op_regions);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib);
|
||||
MIE_VECTOR_DECLARE(struct mie_register *, op_args);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
|
||||
MIE_VECTOR_DECLARE(struct mie_register, op_result);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,16 +11,29 @@ enum mie_register_flags {
|
||||
MIE_REGISTER_F_OP_PARAM = 0x02u,
|
||||
MIE_REGISTER_F_BLOCK_PARAM = 0x04u,
|
||||
|
||||
/* only ONE of these two flags can be set at a time */
|
||||
MIE_REGISTER_F_VIRTUAL = 0x10u,
|
||||
MIE_REGISTER_F_MACHINE = 0x20u,
|
||||
};
|
||||
|
||||
/* represents a yet-to-be-resolved reference to a mie_register */
|
||||
struct mie_register_ref {
|
||||
enum mie_register_flags reg_flags;
|
||||
char *reg_name;
|
||||
/* what we THINK the type of the register is.
|
||||
* if this is set, it gets checked during the register resolution process. */
|
||||
const struct mie_type *reg_type;
|
||||
};
|
||||
|
||||
struct mie_register {
|
||||
enum mie_register_flags reg_flags;
|
||||
struct mie_name reg_name;
|
||||
/* only valid if F_MACHINE is set. */
|
||||
struct mie_target_register *reg_mach;
|
||||
struct mie_type *reg_value_type;
|
||||
union {
|
||||
/* only valid if F_VIRTUAL is set. */
|
||||
struct mie_name reg_name;
|
||||
/* only valid if F_MACHINE is set. */
|
||||
struct mie_target_register *reg_mach;
|
||||
};
|
||||
const struct mie_type *reg_type;
|
||||
/* if this is an OP_RESULT register, this points to the block within
|
||||
* which this register is defined.
|
||||
* if this is an OP_PARAM register, this pointer is NULL.
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \
|
||||
struct mie_dialect_op *func_prefix##_op_create(struct mie_dialect *d) \
|
||||
struct mie_dialect_op *func_prefix##_op_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect_op *op = mie_dialect_op_create(d, op_name); \
|
||||
if (!op) { \
|
||||
@@ -27,13 +28,14 @@
|
||||
return op; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \
|
||||
struct mie_dialect_type *func_prefix##_type_create(struct mie_dialect *d) \
|
||||
{ \
|
||||
struct mie_dialect_type *type \
|
||||
= mie_dialect_type_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \
|
||||
struct mie_dialect_type *func_prefix##_type_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect_type *type \
|
||||
= mie_dialect_type_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_TYPE_END() \
|
||||
@@ -41,12 +43,13 @@
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_ADD_OP(op_id) \
|
||||
extern struct mie_dialect_op *op_id##_op_create(struct mie_dialect *); \
|
||||
op = op_id##_op_create(self)
|
||||
extern struct mie_dialect_op *op_id##_op_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
op = op_id##_op_create(self, ctx)
|
||||
#define __MIE_DIALECT_ADD_TYPE(type_id) \
|
||||
extern struct mie_dialect_type *type_id##_type_create( \
|
||||
struct mie_dialect *); \
|
||||
type = type_id##_type_create(self)
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
type = type_id##_type_create(self, ctx)
|
||||
|
||||
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
||||
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
||||
@@ -60,13 +63,21 @@
|
||||
|
||||
#define MIE_DIALECT_TYPE_BEGIN(c_sym, type) \
|
||||
__MIE_DIALECT_TYPE_BEGIN(c_sym, type)
|
||||
#define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END()
|
||||
#define MIE_DIALECT_TYPE_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END()
|
||||
#define MIE_DIALECT_TYPE_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_DIALECT_TYPE_VALUE_PRINT(func) type->ty_value_print = (func)
|
||||
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_DIALECT_TYPE_BUILD_ID(func) type->ty_build_id = (func)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func)
|
||||
|
||||
#define MIE_DIALECT_TRAIT_BEGIN(c_sym, trait)
|
||||
#define MIE_DIALECT_TRAIT_END()
|
||||
#define MIE_DIALECT_TRAIT_STRUCT(name)
|
||||
#define MIE_DIALECT_TRAIT_PRINT(func)
|
||||
#define MIE_DIALECT_TRAIT_CLEANUP(func)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#define MIE_API extern
|
||||
#endif
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define MIE_TEST_FLAGS(value, flags) (((value) & (flags)) == (flags))
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user