1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Write ctx_diff() function to compate ctx_t objects

This commit is contained in:
Maxime Chevalier-Boisvert 2021-01-22 14:57:44 -05:00 committed by Alan Wu
parent 7efde1bfb4
commit 738160db0a
2 changed files with 44 additions and 5 deletions

View file

@ -103,6 +103,42 @@ ctx_get_top_type(ctx_t* ctx)
return ctx->temp_types[ctx->stack_size - 1];
}
/**
Compute a difference score for two context objects
Returns 0 if the two contexts are the same
Returns -1 if incompatible
Returns > 0 if different but compatible
*/
int ctx_diff(const ctx_t* src, const ctx_t* dst)
{
if (dst->stack_size != src->stack_size)
return -1;
if (dst->self_is_object != src->self_is_object)
return -1;
// Difference sum
int diff = 0;
// For each temporary variable
for (size_t i = 0; i < MAX_TEMP_TYPES; ++i)
{
int t_src = src->temp_types[i];
int t_dst = dst->temp_types[i];
if (t_dst != t_src)
{
// It's OK to lose some type information
if (t_dst == T_NONE)
diff += 1;
else
return -1;
}
}
return diff;
}
// Add an incoming branch for a given block version
static void add_incoming(block_t* p_block, uint32_t branch_idx)
{
@ -118,16 +154,18 @@ static void add_incoming(block_t* p_block, uint32_t branch_idx)
block_t* find_block_version(blockid_t blockid, const ctx_t* ctx)
{
// If there exists a version for this block id
st_data_t st_version;
if (rb_st_lookup(version_tbl, (st_data_t)&blockid, &st_version)) {
return (block_t*)st_version;
}
block_t* first_version;
if (!rb_st_lookup(version_tbl, (st_data_t)&blockid, (st_data_t*)&first_version))
return NULL;
//
// TODO: use the ctx parameter to search existing versions for a match
//
return NULL;
// Check that the version found is actually compatible
RUBY_ASSERT(ctx_diff(ctx, &first_version->ctx) >= 0);
return first_version;
}
// Compile a new block version immediately
block_t* gen_block_version(blockid_t blockid, const ctx_t* start_ctx)

View file

@ -130,6 +130,7 @@ x86opnd_t ctx_stack_push(ctx_t* ctx, int type);
x86opnd_t ctx_stack_pop(ctx_t* ctx, size_t n);
x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx);
int ctx_get_top_type(ctx_t* ctx);
int ctx_diff(const ctx_t* src, const ctx_t* dst);
block_t* find_block_version(blockid_t blockid, const ctx_t* ctx);
block_t* gen_block_version(blockid_t blockid, const ctx_t* ctx);