Skip to content

Commit

Permalink
Eliminate p6scalarfromdesc ext-op for a desugar
Browse files Browse the repository at this point in the history
No semantic change here, just a change in how we achieve it. This is
both potentially slower (sequence of VM instructions rather than a C
op) but potentially faster (spesh can eliminate a branch that it could
not when it was just calling a chunk of opaque C code).

This does also make the slight improvement that we only ever create one
default container descriptor now, whereas before we might have had many
copies of it serialized across different precompilations.
  • Loading branch information
jnthn committed Jun 11, 2018
1 parent 20bf96f commit ff952e6
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 46 deletions.
42 changes: 42 additions & 0 deletions src/Perl6/Actions.nqp
Expand Up @@ -667,6 +667,48 @@ register_op_desugar('p6forstmt', -> $qast {
QAST::WVal.new( :value($qast.ann('Nil')) )
)
});
register_op_desugar('p6scalarfromdesc', -> $qast {
my $desc := QAST::Node.unique('descriptor');
my $Scalar := QAST::WVal.new( :value(nqp::gethllsym('perl6', 'Scalar')) );
my $default_cont_spec := nqp::gethllsym('perl6', 'default_cont_spec');
QAST::Stmt.new(
QAST::Op.new(
:op('bind'),
QAST::Var.new( :name($desc), :scope('local'), :decl('var') ),
$qast[0]
),
QAST::Op.new(
:op('unless'),
QAST::Op.new(
:op('isconcrete'),
QAST::Var.new( :name($desc), :scope('local') ),
),
QAST::Op.new(
:op('bind'),
QAST::Var.new( :name($desc), :scope('local') ),
QAST::WVal.new( :value($default_cont_spec) )
)
),
QAST::Op.new(
:op('p6bindattrinvres'),
QAST::Op.new(
:op('p6bindattrinvres'),
QAST::Op.new( :op('create'), $Scalar ),
$Scalar,
QAST::SVal.new( :value('$!descriptor') ),
QAST::Var.new( :name($desc), :scope('local') )
),
$Scalar,
QAST::SVal.new( :value('$!value') ),
QAST::Op.new(
:op('getattr'),
QAST::Var.new( :name($desc), :scope('local') ),
QAST::WVal.new( :value($default_cont_spec.WHAT) ),
QAST::SVal.new( :value('$!default') )
)
)
)
});

sub can-use-p6forstmt($block) {
my $past_block := $block.ann('past_block');
Expand Down
11 changes: 11 additions & 0 deletions src/Perl6/Metamodel/BOOTSTRAP.nqp
Expand Up @@ -1357,6 +1357,12 @@ BEGIN {
# Scalar needs to be registered as a container type.
nqp::setcontspec(Scalar, 'rakudo_scalar', nqp::null());

# Cache a single default Scalar container spec, to ensure we only get
# one of them.
Scalar.HOW.cache_add(Scalar, 'default_cont_spec',
Perl6::Metamodel::ContainerDescriptor.new(
:of(Mu), :default(Any), :rw(1), :name('element')));

# Set up various native reference types.
sub setup_native_ref_type($type, $primitive, $ref_kind) {
$type.HOW.add_parent($type, Any);
Expand Down Expand Up @@ -3232,6 +3238,11 @@ nqp::neverrepossess(PROCESS.WHO);
nqp::neverrepossess(nqp::getattr(PROCESS.WHO, Map, '$!storage'));
nqp::bindhllsym('perl6', 'PROCESS', PROCESS);

# Stash Scalar and a default container spec away in the HLL state.
nqp::bindhllsym('perl6', 'Scalar', Scalar);
nqp::bindhllsym('perl6', 'default_cont_spec',
Scalar.HOW.cache_get(Scalar, 'default_cont_spec'));

# HLL configuration: interop, boxing and exit handling.
nqp::sethllconfig('perl6', nqp::hash(
'int_box', Int,
Expand Down
2 changes: 1 addition & 1 deletion src/Perl6/Metamodel/ContainerDescriptor.nqp
Expand Up @@ -5,7 +5,7 @@ class Perl6::Metamodel::ContainerDescriptor {
has $!default;
has int $!dynamic;

method BUILD(:$of, :$rw, :$name, :$default, :$dynamic) {
method BUILD(:$of, int :$rw, str :$name, :$default, int :$dynamic) {
$!of := $of;
$!rw := $rw;
$!name := $name;
Expand Down
4 changes: 0 additions & 4 deletions src/vm/moar/Perl6/Ops.nqp
Expand Up @@ -41,9 +41,6 @@ MAST::ExtOpRegistry.register_extop('p6box_u',
MAST::ExtOpRegistry.register_extop('p6bool',
$MVM_operand_obj +| $MVM_operand_write_reg,
$MVM_operand_int64 +| $MVM_operand_read_reg);
MAST::ExtOpRegistry.register_extop('p6scalarfromdesc',
$MVM_operand_obj +| $MVM_operand_write_reg,
$MVM_operand_obj +| $MVM_operand_read_reg);
MAST::ExtOpRegistry.register_extop('p6var',
$MVM_operand_obj +| $MVM_operand_write_reg,
$MVM_operand_obj +| $MVM_operand_read_reg);
Expand Down Expand Up @@ -318,7 +315,6 @@ my $p6bool := -> $qastcomp, $op {
MAST::InstructionList.new(@ops, $res_reg, $MVM_reg_obj)
};
$ops.add_hll_op('perl6', 'p6bool', $p6bool);
$ops.add_hll_moarop_mapping('perl6', 'p6scalarfromdesc', 'p6scalarfromdesc');
$ops.add_hll_op('perl6', 'p6invokehandler', -> $qastcomp, $op {
$qastcomp.as_mast(QAST::Op.new( :op('call'), $op[0], $op[1] ));
});
Expand Down
41 changes: 0 additions & 41 deletions src/vm/moar/ops/perl6_ops.c
Expand Up @@ -53,9 +53,6 @@ static MVMObject *False = NULL;
static MVMObject *ContainerDescriptor = NULL;
static MVMObject *Nil = NULL;

/* Default container descriptor. */
static MVMObject *default_cont_desc = NULL;

/* Useful string constants. */
static MVMString *str_return = NULL;
static MVMString *str_dispatcher = NULL;
Expand Down Expand Up @@ -125,21 +122,6 @@ static void p6settypes(MVMThreadContext *tc, MVMuint8 *cur_op) {
get_type(tc, conf, "Nil", Nil);
});

/* Set up default container descriptor. */
{
MVMString *element;
default_cont_desc = MVM_repr_alloc_init(tc, ContainerDescriptor);
MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&default_cont_desc, "DefaultContainerDescriptor");
element = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "<element>");
MVM_ASSIGN_REF(tc, &(default_cont_desc->header),
((Rakudo_ContainerDescriptor *)default_cont_desc)->of, Mu);
MVM_ASSIGN_REF(tc, &(default_cont_desc->header),
((Rakudo_ContainerDescriptor *)default_cont_desc)->name, element);
((Rakudo_ContainerDescriptor *)default_cont_desc)->rw = 1;
MVM_ASSIGN_REF(tc, &(default_cont_desc->header),
((Rakudo_ContainerDescriptor *)default_cont_desc)->the_default, Any);
}

/* Strings. */
str_return = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "RETURN");
MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&str_return, "RETURN");
Expand Down Expand Up @@ -235,28 +217,6 @@ static void p6bool_discover(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshIns
#endif
}

/* Creates a Scalar from the specified descriptor. */
static MVMuint8 s_p6scalarfromdesc[] = {
MVM_operand_obj | MVM_operand_write_reg,
MVM_operand_obj | MVM_operand_read_reg,
};
static void p6scalarfromdesc(MVMThreadContext *tc, MVMuint8 *cur_op) {
MVMObject *new_scalar = MVM_repr_alloc_init(tc, Scalar);
MVMObject *descriptor = GET_REG(tc, 2).o;
if (MVM_is_null(tc, descriptor) || !IS_CONCRETE(descriptor)) {
descriptor = default_cont_desc;
}
MVM_ASSIGN_REF(tc, &(new_scalar->header), ((Rakudo_Scalar *)new_scalar)->descriptor, descriptor);
MVM_ASSIGN_REF(tc, &(new_scalar->header), ((Rakudo_Scalar *)new_scalar)->value,
((Rakudo_ContainerDescriptor *)descriptor)->the_default);
GET_REG(tc, 0).o = new_scalar;
}
static void p6scalarfromdesc_discover(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshIns *ins) {
MVMSpeshFacts *tfacts = MVM_spesh_get_and_use_facts(tc, g, ins->operands[0]);
tfacts->flags |= MVM_SPESH_FACT_CONCRETE | MVM_SPESH_FACT_KNOWN_TYPE;
tfacts->type = Scalar;
}

static MVMuint8 s_p6recont_ro[] = {
MVM_operand_obj | MVM_operand_write_reg,
MVM_operand_obj | MVM_operand_read_reg,
Expand Down Expand Up @@ -741,7 +701,6 @@ MVM_DLL_EXPORT void Rakudo_ops_init(MVMThreadContext *tc) {
MVM_ext_register_extop(tc, "p6box_u", p6box_u, 2, s_p6box_u, NULL, p6box_u_discover, MVM_EXTOP_PURE | MVM_EXTOP_ALLOCATING);
MVM_ext_register_extop(tc, "p6settypes", p6settypes, 1, s_p6settypes, NULL, NULL, 0);
MVM_ext_register_extop(tc, "p6bool", p6bool, 2, s_p6bool, NULL, p6bool_discover, MVM_EXTOP_PURE);
MVM_ext_register_extop(tc, "p6scalarfromdesc", p6scalarfromdesc, 2, s_p6scalarfromdesc, NULL, p6scalarfromdesc_discover, MVM_EXTOP_PURE | MVM_EXTOP_ALLOCATING);
MVM_ext_register_extop(tc, "p6recont_ro", p6recont_ro, 2, s_p6recont_ro, NULL, NULL, MVM_EXTOP_PURE);
MVM_ext_register_extop(tc, "p6var", p6var, 2, s_p6var, NULL, NULL, MVM_EXTOP_PURE | MVM_EXTOP_ALLOCATING);
MVM_ext_register_extop(tc, "p6reprname", p6reprname, 2, s_p6reprname, NULL, p6reprname_discover, MVM_EXTOP_PURE | MVM_EXTOP_ALLOCATING);
Expand Down

0 comments on commit ff952e6

Please sign in to comment.