improving the compiler code

This commit is contained in:
hyung-hwan 2021-11-21 16:02:39 +00:00
parent b78513ad0a
commit 4a0ecfa0f1
3 changed files with 138 additions and 38 deletions

View File

@ -455,24 +455,28 @@ static int handle_logopt (hcl_t* hcl, const hcl_bch_t* logstr)
{ "ic", 0, HCL_LOG_IC }, { "ic", 0, HCL_LOG_IC },
{ "primitive", 0, HCL_LOG_PRIMITIVE }, { "primitive", 0, HCL_LOG_PRIMITIVE },
/* select a specific level */
{ "fatal", 0, HCL_LOG_FATAL }, { "fatal", 0, HCL_LOG_FATAL },
{ "error", 0, HCL_LOG_ERROR }, { "error", 0, HCL_LOG_ERROR },
{ "warn", 0, HCL_LOG_WARN }, { "warn", 0, HCL_LOG_WARN },
{ "info", 0, HCL_LOG_INFO }, { "info", 0, HCL_LOG_INFO },
{ "debug", 0, HCL_LOG_DEBUG }, { "debug", 0, HCL_LOG_DEBUG },
/* select a specific level or higher */
{ "fatal+", 0, HCL_LOG_FATAL }, { "fatal+", 0, HCL_LOG_FATAL },
{ "error+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR }, { "error+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR },
{ "warn+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN }, { "warn+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN },
{ "info+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO }, { "info+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO },
{ "debug+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG }, { "debug+", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG },
/* select a specific level or lower */
{ "fatal-", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG }, { "fatal-", 0, HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG },
{ "error-", 0, HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG }, { "error-", 0, HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG },
{ "warn-", 0, HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG }, { "warn-", 0, HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG },
{ "info-", 0, HCL_LOG_INFO | HCL_LOG_DEBUG }, { "info-", 0, HCL_LOG_INFO | HCL_LOG_DEBUG },
{ "debug-", 0, HCL_LOG_DEBUG }, { "debug-", 0, HCL_LOG_DEBUG },
/* exclude a specific level */
{ "-fatal", 1, ~HCL_LOG_FATAL }, { "-fatal", 1, ~HCL_LOG_FATAL },
{ "-error", 1, ~HCL_LOG_ERROR }, { "-error", 1, ~HCL_LOG_ERROR },
{ "-warn", 1, ~HCL_LOG_WARN }, { "-warn", 1, ~HCL_LOG_WARN },

View File

@ -35,6 +35,23 @@ enum
#define TV_BUFFER_ALIGN 256 #define TV_BUFFER_ALIGN 256
#define BLK_INFO_BUFFER_ALIGN 128 #define BLK_INFO_BUFFER_ALIGN 128
struct var_info_t
{
int type;
/* ctx_offset 0 means the current context.
* 1 means current->home.
* 2 means current->home->home.
* index_in_ctx is a relative index within the context found.
*/
hcl_oow_t ctx_offset; /* context offset */
hcl_oow_t index_in_ctx; /* index in the current scope */
};
typedef struct var_info_t var_info_t;
/* -------------------------------------------- /* --------------------------------------------
@ -133,6 +150,7 @@ static int __find_word_in_string (const hcl_oocs_t* haystack, const hcl_oocs_t*
{ {
if (last) if (last)
{ {
/* if last is true, find the last matching entry */
found = index; found = index;
} }
else else
@ -165,7 +183,6 @@ static int __find_word_in_string (const hcl_oocs_t* haystack, const hcl_oocs_t*
return -1; /* not found */ return -1; /* not found */
} }
static int add_temporary_variable (hcl_t* hcl, const hcl_oocs_t* name, hcl_oow_t dup_check_start) static int add_temporary_variable (hcl_t* hcl, const hcl_oocs_t* name, hcl_oow_t dup_check_start)
{ {
hcl_oocs_t s; hcl_oocs_t s;
@ -198,7 +215,6 @@ static void kill_temporary_variable_at_offset (hcl_t* hcl, hcl_oow_t offset)
/* this is a hacky function. it's better to implement kill_temporary_variables() which uses word positions */ /* this is a hacky function. it's better to implement kill_temporary_variables() which uses word positions */
HCL_ASSERT (hcl, offset < hcl->c->tv.s.len); HCL_ASSERT (hcl, offset < hcl->c->tv.s.len);
HCL_ASSERT (hcl, hcl->c->tv.s.ptr[offset] != ' '); HCL_ASSERT (hcl, hcl->c->tv.s.ptr[offset] != ' ');
hcl->c->tv.s.ptr[offset] = '('; /* put a special character which can't form a variable name */ hcl->c->tv.s.ptr[offset] = '('; /* put a special character which can't form a variable name */
} }
@ -208,6 +224,86 @@ static int find_temporary_variable_backward (hcl_t* hcl, const hcl_oocs_t* name,
return __find_word_in_string(&hcl->c->tv.s, name, 1, index); return __find_word_in_string(&hcl->c->tv.s, name, 1, index);
} }
#if 0
HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0);
fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth];
/* if a temporary variable is accessed inside a block,
* use a special instruction to indicate it */
HCL_ASSERT (hcl, index < fbi->tmprcnt);
for (i = hcl->c->fnblk.depth; i >= 0; i--)
{
hcl_oow_t parent_tmprcnt;
parent_tmprcnt = (i > 0)? hcl->c->fnblk.info[i - 1].tmprcnt: 0;
if (index >= parent_tmprcnt)
{
hcl_oow_t ctx_offset, index_in_ctx;
ctx_offset = hcl->c->fnblk.depth - i;
index_in_ctx = index - parent_tmprcnt;
/* ctx_offset 0 means the current context.
* 1 means current->home.
* 2 means current->home->home.
* index_in_ctx is a relative index within the context found.
*/
if (emit_double_param_instruction(hcl, baseinst1, ctx_offset, index_in_ctx, srcloc) <= -1) return -1;
if (ctx_offset > 0)
{
fbi->access_outer = 1; /* the current function block accesses temporaries in an outer function block */
hcl->c->fnblk.info[i].accessed_by_inner = 1; /* temporaries in an outer function block is accessed by the current function block */
}
return 0;
}
}
#endif
static int find_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, var_info_t* vi)
{
hcl_fnblk_info_t* fbi;
hcl_oow_t parent_tmprcnt, parent_tmprlen;
hcl_oow_t i, index;
hcl_oocs_t haystack;
HCL_ASSERT (hcl, hcl->c->fnblk.info[hcl->c->fnblk.depth].tmprlen = hcl->c->tv.s.len);
/* depth begins at -1. so it is the actual index. let the looping begin at depth + 1
* to avoid an extra exit check without it */
for (i = hcl->c->fnblk.depth + 1; i > 0; )
{
fbi = &hcl->c->fnblk.info[--i];
if (i > 0)
{
parent_tmprlen = hcl->c->fnblk.info[i - 1].tmprlen;
parent_tmprcnt = hcl->c->fnblk.info[i - 1].tmprcnt;
}
else
{
parent_tmprlen = 0;
parent_tmprcnt = 0;
}
/* narrow the search scope to the current block */
haystack.ptr = &hcl->c->tv.s.ptr[parent_tmprlen];
haystack.len = fbi->tmprlen - parent_tmprlen;
if (__find_word_in_string(&haystack, name, 1, &index) >= 0)
{
/* temporary variables or arguments */
vi->type = VAR_INDEXED;
vi->ctx_offset = hcl->c->fnblk.depth - i; /* context offset */
vi->index_in_ctx = index;
HCL_INFO4 (hcl, "FOUND ...[%.*js]................ ===> ctx_offset %d index %d\n", name->len, name->ptr, (int)(vi->ctx_offset), (int)vi->index_in_ctx);
return 0;
}
}
HCL_INFO2 (hcl, "NOT FOUND => %.*js\n", name->len, name->ptr);
return -1;
}
/* ========================================================================= */ /* ========================================================================= */
static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index) static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index)
@ -1918,17 +2014,19 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
hcl_cframe_t* cf; hcl_cframe_t* cf;
hcl_cnode_t* obj; hcl_cnode_t* obj;
hcl_oop_t tmp; hcl_oop_t tmp;
hcl_oow_t nivars, ncvars, saved_tv_wcount, tv_dup_start; hcl_oow_t nivars, ncvars, saved_tv_wcount, tv_dup_check_start;
cf = GET_TOP_CFRAME(hcl); cf = GET_TOP_CFRAME(hcl);
obj = cf->operand; obj = cf->operand;
saved_tv_wcount = hcl->c->tv.wcount; saved_tv_wcount = hcl->c->tv.wcount;
tv_dup_start = hcl->c->tv.s.len; tv_dup_check_start = hcl->c->tv.s.len;
/* TODO: class variables */ /* TODO: class variables */
nivars = ncvars = 0; nivars = ncvars = 0;
if (collect_vardcl(hcl, obj, &obj, tv_dup_start, &nivars, "instance") <= -1) goto oops; /* use the temporary variable collection buffer for convenience when scanning
* instance variables and class variables */
if (collect_vardcl(hcl, obj, &obj, tv_dup_check_start, &nivars, "instance") <= -1) goto oops;
if (nivars > 0) if (nivars > 0)
{ {
@ -1938,7 +2036,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
goto oops; goto oops;
} }
/* set starting point past the added space (+1 to index, -1 to length) */ /* set starting point past the added space (+1 to index, -1 to length) */
tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[tv_dup_start + 1], hcl->c->tv.s.len - tv_dup_start - 1, 0); tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[tv_dup_check_start + 1], hcl->c->tv.s.len - tv_dup_check_start - 1, 0);
if (HCL_UNLIKELY(!tmp)) goto oops; if (HCL_UNLIKELY(!tmp)) goto oops;
if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops; if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops;
} }
@ -1957,7 +2055,12 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops; if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops;
} }
if (push_clsblk(hcl, &cf->u._class.start_loc, nivars, ncvars, &hcl->c->tv.s.ptr[tv_dup_start + 1], HCL_NULL) <= -1) goto oops; if (push_clsblk(hcl, &cf->u._class.start_loc, nivars, ncvars, &hcl->c->tv.s.ptr[tv_dup_check_start + 1], HCL_NULL) <= -1) goto oops;
/* discard the instance variables and class variables in the temporary variable collection buffe
* because they have been pushed to the class block structure */
hcl->c->tv.s.len = tv_dup_check_start;
hcl->c->tv.wcount = saved_tv_wcount;
/* class_enter nsuperclasses, nivars, ncvars */ /* class_enter nsuperclasses, nivars, ncvars */
if (emit_byte_instruction(hcl, HCL_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops; if (emit_byte_instruction(hcl, HCL_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops;
@ -1970,7 +2073,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
return 0; return 0;
oops: oops:
hcl->c->tv.s.len = tv_dup_start; hcl->c->tv.s.len = tv_dup_check_start;
hcl->c->tv.wcount = saved_tv_wcount; hcl->c->tv.wcount = saved_tv_wcount;
return -1; return -1;
} }
@ -3150,7 +3253,10 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_cnode_t* obj)
hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNEDVARNAME, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "special symbol not to be used as a variable name"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNEDVARNAME, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "special symbol not to be used as a variable name");
return -1; return -1;
} }
{
var_info_t vi;
find_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &vi);
}
/* check if a symbol is a local variable */ /* check if a symbol is a local variable */
if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &index) <= -1) if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &index) <= -1)
{ {

View File

@ -28,17 +28,6 @@
#define DECODE_LOG_MASK (HCL_LOG_MNEMONIC | HCL_LOG_INFO) #define DECODE_LOG_MASK (HCL_LOG_MNEMONIC | HCL_LOG_INFO)
#if defined(HCL_BUILD_RELEASE)
/* get rid of instruction logging regardless of the log mask
* in the release build */
# define LOG_INST_0(hcl,fmt)
# define LOG_INST_1(hcl,fmt,a1)
# define LOG_INST_2(hcl,fmt,a1,a2)
# define LOG_INST_3(hcl,fmt,a1,a2,a3)
# define LOG_INST_4(hcl,fmt,a1,a2,a3,a4)
# define LOG_INST_5(hcl,fmt,a1,a2,a3,a4,a5)
# define LOG_INST_6(hcl,fmt,a1,a2,a3,a4,a5,a6)
#else
#define LOG_INST_0(hcl,fmt) HCL_LOG1(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer) #define LOG_INST_0(hcl,fmt) HCL_LOG1(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer)
#define LOG_INST_1(hcl,fmt,a1) HCL_LOG2(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1) #define LOG_INST_1(hcl,fmt,a1) HCL_LOG2(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1)
#define LOG_INST_2(hcl,fmt,a1,a2) HCL_LOG3(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2) #define LOG_INST_2(hcl,fmt,a1,a2) HCL_LOG3(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2)
@ -46,7 +35,7 @@
#define LOG_INST_4(hcl,fmt,a1,a2,a3,a4) HCL_LOG5(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4) #define LOG_INST_4(hcl,fmt,a1,a2,a3,a4) HCL_LOG5(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4)
#define LOG_INST_5(hcl,fmt,a1,a2,a3,a4,a5) HCL_LOG6(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4, a5) #define LOG_INST_5(hcl,fmt,a1,a2,a3,a4,a5) HCL_LOG6(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4, a5)
#define LOG_INST_6(hcl,fmt,a1,a2,a3,a4,a5,a6) HCL_LOG7(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4, a5, a6) #define LOG_INST_6(hcl,fmt,a1,a2,a3,a4,a5,a6) HCL_LOG7(hcl, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3, a4, a5, a6)
#endif
#define FETCH_BYTE_CODE(hcl) (cdptr[ip++]) #define FETCH_BYTE_CODE(hcl) (cdptr[ip++])
#define FETCH_BYTE_CODE_TO(hcl,v_ooi) (v_ooi = FETCH_BYTE_CODE(hcl)) #define FETCH_BYTE_CODE_TO(hcl,v_ooi) (v_ooi = FETCH_BYTE_CODE(hcl))
@ -682,6 +671,7 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end)
} }
} }
/* TODO: this needs changes... */ /* TODO: this needs changes... */
/* print literal frame contents */ /* print literal frame contents */
for (ip = 0; ip < hcl->code.lit.len; ip++) for (ip = 0; ip < hcl->code.lit.len; ip++)