Skip to content

Commit 104f2df

Browse files
authored
Merge pull request #1433 from clasp-developers/bytecode-compiler-opt
Bytecode compiler opt
2 parents 06fa238 + 64dbbcb commit 104f2df

20 files changed

+731
-798
lines changed

include/clasp/core/bytecode_compiler.h

Lines changed: 123 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef bytecode_compiler_H
22
#define bytecode_compiler_H
33

4+
#include <variant>
45
#include <clasp/core/common.h>
56
#include <clasp/core/compPackage.fwd.h>
67

@@ -54,6 +55,14 @@ class LexicalVarInfo_O : public VarInfo_O {
5455
}
5556
};
5657

58+
struct LexicalVarInfoV {
59+
LexicalVarInfoV(LexicalVarInfo_sp info) : _info(info) {};
60+
// Because we mutate infos, and store them in lexenvs, we have to
61+
// allocate them. This wrapper is just for var_info_v purposes.
62+
LexicalVarInfo_sp _info;
63+
LexicalVarInfo_sp info() const { return _info; }
64+
};
65+
5766
FORWARD(SpecialVarInfo);
5867
class SpecialVarInfo_O : public VarInfo_O {
5968
LISP_CLASS(comp, CompPkg, SpecialVarInfo_O, "SpecialVarInfo", VarInfo_O);
@@ -74,6 +83,13 @@ class SpecialVarInfo_O : public VarInfo_O {
7483
CL_DEFMETHOD bool globalp() const { return this->_globalp; }
7584
};
7685

86+
struct SpecialVarInfoV {
87+
SpecialVarInfoV(bool globalp) : _globalp(globalp) {};
88+
SpecialVarInfoV(SpecialVarInfo_sp info) : _globalp(info->globalp()) {};
89+
bool _globalp;
90+
bool globalp() const { return _globalp; }
91+
};
92+
7793
FORWARD(SymbolMacroVarInfo);
7894
class SymbolMacroVarInfo_O : public VarInfo_O {
7995
LISP_CLASS(comp, CompPkg, SymbolMacroVarInfo_O, "SymbolMacroVarInfo", VarInfo_O);
@@ -91,6 +107,13 @@ class SymbolMacroVarInfo_O : public VarInfo_O {
91107
CL_DEFMETHOD Function_sp expander() const { return this->_expander; }
92108
};
93109

110+
struct SymbolMacroVarInfoV {
111+
SymbolMacroVarInfoV(Function_sp expander) : _expander(expander) {};
112+
SymbolMacroVarInfoV(SymbolMacroVarInfo_sp info) : _expander(info->expander()) {};
113+
Function_sp _expander;
114+
Function_sp expander() const { return _expander; }
115+
};
116+
94117
FORWARD(ConstantVarInfo);
95118
class ConstantVarInfo_O : public VarInfo_O {
96119
LISP_CLASS(comp, CompPkg, ConstantVarInfo_O, "ConstantVarInfo", VarInfo_O);
@@ -107,6 +130,19 @@ class ConstantVarInfo_O : public VarInfo_O {
107130
CL_DEFMETHOD T_sp value() const { return this->_value; }
108131
};
109132

133+
struct ConstantVarInfoV {
134+
ConstantVarInfoV(T_sp value) : _value(value) {};
135+
ConstantVarInfoV(ConstantVarInfo_sp info) : _value(info->value()) {};
136+
T_sp _value;
137+
T_sp value() const { return _value; }
138+
};
139+
140+
// non-heaped infos, to avoid consing. see var_info_v.
141+
// We use this thing instead of monostate for clarity.
142+
struct NoVarInfoV {};
143+
144+
typedef std::variant<NoVarInfoV, LexicalVarInfoV, SpecialVarInfoV, SymbolMacroVarInfoV, ConstantVarInfoV> VarInfoV;
145+
110146
FORWARD(FunInfo);
111147
class FunInfo_O : public General_O {
112148
LISP_ABSTRACT_CLASS(comp, CompPkg, FunInfo_O, "FunInfo", General_O);
@@ -131,6 +167,13 @@ class GlobalFunInfo_O : public FunInfo_O {
131167
CL_DEFMETHOD T_sp cmexpander() const { return this->_cmexpander; }
132168
};
133169

170+
struct GlobalFunInfoV {
171+
GlobalFunInfoV(T_sp cmexpander) : _cmexpander(cmexpander) {};
172+
GlobalFunInfoV(GlobalFunInfo_sp info) : _cmexpander(info->cmexpander()) {};
173+
T_sp _cmexpander;
174+
T_sp cmexpander() const { return _cmexpander; }
175+
};
176+
134177
FORWARD(LocalFunInfo);
135178
class LocalFunInfo_O : public FunInfo_O {
136179
LISP_CLASS(comp, CompPkg, LocalFunInfo_O, "LocalFunInfo", FunInfo_O);
@@ -147,6 +190,12 @@ class LocalFunInfo_O : public FunInfo_O {
147190
CL_DEFMETHOD T_sp funVar() const { return this->fun_var; }
148191
};
149192

193+
struct LocalFunInfoV {
194+
LocalFunInfoV(LocalFunInfo_sp info) : _info(info) {};
195+
LocalFunInfo_sp _info;
196+
LocalFunInfo_sp info() const { return _info; }
197+
};
198+
150199
// We have separate global and local macro classes because it is sometimes
151200
// important to know that a binding is local - for example, a local binding
152201
// shadows a global setf expander.
@@ -167,6 +216,13 @@ class GlobalMacroInfo_O : public FunInfo_O {
167216
CL_DEFMETHOD Function_sp expander() const { return this->_expander; }
168217
};
169218

219+
struct GlobalMacroInfoV {
220+
GlobalMacroInfoV(Function_sp expander) : _expander(expander) {};
221+
GlobalMacroInfoV(GlobalMacroInfo_sp info) : _expander(info->expander()) {};
222+
Function_sp _expander;
223+
Function_sp expander() const { return _expander; }
224+
};
225+
170226
FORWARD(LocalMacroInfo);
171227
class LocalMacroInfo_O : public FunInfo_O {
172228
LISP_CLASS(comp, CompPkg, LocalMacroInfo_O, "LocalMacroInfo", FunInfo_O);
@@ -183,8 +239,19 @@ class LocalMacroInfo_O : public FunInfo_O {
183239
CL_DEFMETHOD Function_sp expander() const { return this->_expander; }
184240
};
185241

242+
struct LocalMacroInfoV {
243+
LocalMacroInfoV(Function_sp expander) : _expander(expander) {};
244+
LocalMacroInfoV(LocalMacroInfo_sp info) : _expander(info->expander()) {};
245+
Function_sp _expander;
246+
Function_sp expander() const { return _expander; }
247+
};
248+
249+
struct NoFunInfoV {};
250+
251+
typedef std::variant<NoFunInfoV, GlobalFunInfoV, LocalFunInfoV, GlobalMacroInfoV, LocalMacroInfoV> FunInfoV;
252+
186253
FORWARD(Lexenv);
187-
FORWARD(Context);
254+
class Context; // forward decl
188255
class Lexenv_O : public General_O {
189256
LISP_CLASS(comp, CompPkg, Lexenv_O, "Lexenv", General_O);
190257
public:
@@ -219,7 +286,9 @@ class Lexenv_O : public General_O {
219286
* environment. The max local count in the current function is also
220287
* updated.
221288
*/
222-
CL_DEFMETHOD Lexenv_sp bind_vars(List_sp vars, Context_sp context);
289+
Lexenv_sp bind_vars(List_sp vars, const Context context);
290+
// Ditto but with just one.
291+
Lexenv_sp bind1var(Symbol_sp var, const Context context);
223292
// Add VARS as special in ENV.
224293
CL_DEFMETHOD Lexenv_sp add_specials(List_sp vars);
225294
// Add FUNCTION NAMES as notinline in ENV.
@@ -246,74 +315,67 @@ class Lexenv_O : public General_O {
246315

247316
// Context contains information about what the current form needs
248317
// to know about what it is enclosed by.
318+
// Because they are only ever passed "down" and used within the
319+
// compiler, they are POD rather than Lisp objects, to save some time
320+
// on consing and GC.
321+
// (Profiling has shown that the compiler spends a lot of time consing.)
249322
FORWARD(Label);
250323
FORWARD(Cfunction);
251324
FORWARD(Module);
252-
class Context_O : public General_O {
253-
LISP_CLASS(comp, CompPkg, Context_O, "Context", General_O);
325+
class Context {
254326
public:
255-
T_sp _receiving;
327+
int _receiving;
256328
List_sp _dynenv;
257329
T_sp _cfunction;
258330
public:
259-
Context_O(T_sp receiving, T_sp dynenv, T_sp cfunction)
331+
Context(int receiving, T_sp dynenv, T_sp cfunction)
260332
: _receiving(receiving), _dynenv(dynenv), _cfunction(cfunction) {}
261-
CL_LISPIFY_NAME(Context/make)
262-
CL_DEF_CLASS_METHOD
263-
static Context_sp make(T_sp receiving, T_sp dynenv, T_sp cfunction) {
264-
return gctools::GC<Context_O>::allocate<gctools::RuntimeStage>(receiving, dynenv, cfunction);
265-
}
266-
CL_LISPIFY_NAME(context/receiving)
267-
CL_DEFMETHOD T_sp receiving() { return this->_receiving; }
268-
CL_LISPIFY_NAME(context/dynenv)
269-
CL_DEFMETHOD List_sp dynenv() { return this->_dynenv; }
270-
CL_DEFMETHOD Cfunction_sp cfunction() {
333+
// Sub constructors
334+
Context(const Context& parent, int receiving)
335+
: _receiving(receiving), _dynenv(parent.dynenv()),
336+
_cfunction(parent.cfunction()) {}
337+
// Plop the de on the front.
338+
Context(const Context& parent, T_sp de)
339+
: _receiving(parent.receiving()),
340+
_dynenv(Cons_O::create(de, parent.dynenv())),
341+
_cfunction(parent.cfunction()) {}
342+
int receiving() const { return this->_receiving; }
343+
List_sp dynenv() const { return this->_dynenv; }
344+
Cfunction_sp cfunction() const {
271345
return gc::As<Cfunction_sp>(this->_cfunction);
272346
}
273-
CL_DEFMETHOD Module_sp module();
274-
public:
275-
// Make a new context that's like this one but with a possibly-different
276-
// RECEIVING.
277-
CL_DEFMETHOD Context_sp sub(T_sp receiving) {
278-
return Context_O::make(receiving, this->_dynenv, this->_cfunction);
279-
}
280-
// Make a new context that's like this one but with the given thing
281-
// plopped on the dynenv.
282-
CL_DEFMETHOD Context_sp subde(T_sp de) {
283-
return Context_O::make(this->_receiving, Cons_O::create(de, this->_dynenv),
284-
this->_cfunction);
285-
}
286-
CL_DEFMETHOD size_t literal_index(T_sp literal);
287-
CL_DEFMETHOD size_t new_literal_index(T_sp literal);
288-
CL_DEFMETHOD size_t closure_index(T_sp info);
289-
CL_DEFMETHOD void assemble0(uint8_t opcode);
290-
CL_DEFMETHOD void assemble1(uint8_t opcode, size_t operand1);
291-
CL_DEFMETHOD void assemble2(uint8_t opcode,
292-
size_t operand1, size_t operand2);
347+
Module_sp module() const;
348+
public:
349+
size_t literal_index(T_sp literal) const;
350+
size_t new_literal_index(T_sp literal) const;
351+
size_t closure_index(T_sp info) const;
352+
void assemble0(uint8_t opcode) const;
353+
void assemble1(uint8_t opcode, size_t operand1) const;
354+
void assemble2(uint8_t opcode, size_t operand1, size_t operand2) const;
293355
void emit_control_label(Label_sp,
294-
uint8_t opcode8, uint8_t opcode16, uint8_t opcode24);
295-
CL_DEFMETHOD void emit_jump(Label_sp label);
296-
CL_DEFMETHOD void emit_jump_if(Label_sp label);
297-
CL_DEFMETHOD void emit_entry_or_save_sp(LexicalVarInfo_sp info);
298-
CL_DEFMETHOD void emit_ref_or_restore_sp(LexicalVarInfo_sp info);
299-
CL_DEFMETHOD void emit_exit(Label_sp label);
300-
CL_DEFMETHOD void emit_exit_or_jump(LexicalVarInfo_sp info, Label_sp label);
301-
CL_DEFMETHOD void maybe_emit_entry_close(LexicalVarInfo_sp info);
302-
CL_DEFMETHOD void emit_catch(Label_sp label);
303-
CL_DEFMETHOD void emit_jump_if_supplied(Label_sp label, size_t indx);
304-
CL_DEFMETHOD void reference_lexical_info(LexicalVarInfo_sp info);
305-
CL_DEFMETHOD void maybe_emit_make_cell(LexicalVarInfo_sp info);
306-
CL_DEFMETHOD void maybe_emit_cell_ref(LexicalVarInfo_sp info);
307-
CL_DEFMETHOD void maybe_emit_encage(LexicalVarInfo_sp info);
308-
CL_DEFMETHOD void emit_lexical_set(LexicalVarInfo_sp info);
309-
CL_DEFMETHOD void emit_parse_key_args(size_t max_count, size_t key_count,
310-
size_t key_start, size_t indx,
311-
bool aokp);
312-
CL_DEFMETHOD void emit_bind(size_t count, size_t offset);
313-
CL_DEFMETHOD void emit_call(size_t argcount);
314-
CL_DEFMETHOD void emit_mv_call();
315-
CL_DEFMETHOD void emit_special_bind(Symbol_sp sym);
316-
CL_DEFMETHOD void emit_unbind(size_t count);
356+
uint8_t opcode8, uint8_t opcode16, uint8_t opcode24) const;
357+
void emit_jump(Label_sp label) const;
358+
void emit_jump_if(Label_sp label) const;
359+
void emit_entry_or_save_sp(LexicalVarInfo_sp info) const;
360+
void emit_ref_or_restore_sp(LexicalVarInfo_sp info) const;
361+
void emit_exit(Label_sp label) const;
362+
void emit_exit_or_jump(LexicalVarInfo_sp info, Label_sp label) const;
363+
void maybe_emit_entry_close(LexicalVarInfo_sp info) const;
364+
void emit_catch(Label_sp label) const;
365+
void emit_jump_if_supplied(Label_sp label, size_t indx) const;
366+
void reference_lexical_info(LexicalVarInfo_sp info) const;
367+
void maybe_emit_make_cell(LexicalVarInfo_sp info) const;
368+
void maybe_emit_cell_ref(LexicalVarInfo_sp info) const;
369+
void maybe_emit_encage(LexicalVarInfo_sp info) const;
370+
void emit_lexical_set(LexicalVarInfo_sp info) const;
371+
void emit_parse_key_args(size_t max_count, size_t key_count,
372+
size_t key_start, size_t indx,
373+
bool aokp) const;
374+
void emit_bind(size_t count, size_t offset) const;
375+
void emit_call(size_t argcount) const;
376+
void emit_mv_call() const;
377+
void emit_special_bind(Symbol_sp sym) const;
378+
void emit_unbind(size_t count) const;
317379
};
318380

319381
FORWARD(Annotation);
@@ -374,7 +436,7 @@ class Label_O : public Annotation_O {
374436
return gctools::GC<Label_O>::allocate<gctools::RuntimeStage>();
375437
}
376438
public:
377-
CL_DEFMETHOD void contextualize(Context_sp context);
439+
void contextualize(const Context context);
378440
};
379441

380442
FORWARD(Fixup);
@@ -399,7 +461,7 @@ class Fixup_O : public Annotation_O {
399461
public:
400462
// Mark the fixup in the instruction stream during assembly.
401463
// FIXME: This name sucks, but emit_fixup seems wayy too confusing.
402-
CL_DEFMETHOD void contextualize(Context_sp context);
464+
void contextualize(const Context context);
403465
// Compute the final size (in bytes) for the fixed up code.
404466
CL_DEFMETHOD virtual size_t resize() = 0;
405467
// Emit the final code into the bytecode vector.

include/clasp/core/exceptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ void throwTooFewArgumentsError(core::T_sp closure,size_t given, size_t required)
261261

262262
void throwTooManyArgumentsError(core::T_sp closure, size_t given, size_t required);
263263

264-
void throwUnrecognizedKeywordArgumentError(core::T_sp closure, T_sp kw);
264+
void throwOddKeywordsError(core::T_sp closure);
265+
void throwUnrecognizedKeywordArgumentError(core::T_sp closure, core::T_sp kw);
265266

266267
void wrongNumberOfArguments(core::T_sp closure, size_t givenNumberOfArguments, size_t requiredNumberOfArguments);
267268

include/clasp/core/multipleValues.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,18 +402,23 @@ namespace core {
402402
* FIXME: Formalize with a macro or templates or something? */
403403
inline void returnTypeSaveToTemp(size_t nvals, T_O* primary, T_O** temp) {
404404
if (nvals > 0) { // don't store even the primary unless the space actually exists
405-
core::MultipleValues& mv = core::lisp_multipleValues();
406405
temp[0] = primary;
407-
for (size_t i = 1; i < nvals; ++i) {
408-
temp[i] = mv._Values[i];
406+
if (nvals > 1) {
407+
// Only grab this when we really have to - thread local variable
408+
// access is pretty expensive.
409+
core::MultipleValues& mv = core::lisp_multipleValues();
410+
for (size_t i = 1; i < nvals; ++i)
411+
temp[i] = mv._Values[i];
409412
}
410413
}
411414
}
412415
// Build and return a return_type from a temporary vector. See above.
413416
inline gctools::return_type returnTypeLoadFromTemp(size_t nvals, T_O** temp) {
414-
core::MultipleValues& mv = core::lisp_multipleValues();
415-
for (size_t i = 1; i < nvals; ++i) {
416-
mv._Values[i] = temp[i];
417+
if (nvals > 1) {
418+
core::MultipleValues& mv = core::lisp_multipleValues();
419+
for (size_t i = 1; i < nvals; ++i) {
420+
mv._Values[i] = temp[i];
421+
}
417422
}
418423
return gctools::return_type(nvals == 0 ? nil<core::T_O>().raw_() : temp[0], nvals);
419424
}

src/analysis/clasp_gc.sif

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"llvmo::UndefValue_O" "llvmo::CallBase_O" "core::Path_O"
2424
"mp::SharedMutex_O" "asttooling::DerivableASTFrontendAction"
2525
"core::InstanceCreator_O" "core::IOStreamStream_O" "core::Scope_O"
26-
"comp::Context_O" "llvmo::InsertPoint_O" "core::FunctionDescription_O"
26+
"llvmo::InsertPoint_O" "core::FunctionDescription_O"
2727
"core::ComplexVector_double_O" "core::StrWNs_O" "core::UnknownDynEnv_O"
2828
"core::EchoStream_O" "core::HashTableBase_O" "core::SimpleMDArrayBit_O"
2929
"core::MDArrayBit_O" "core::ComplexVector_byte16_t_O"
@@ -4752,18 +4752,6 @@
47524752
{class-kind :stamp-name "STAMPWTAG_llvmo__InsertPoint_O" :stamp-key "llvmo::InsertPoint_O"
47534753
:parent-class "core::General_O" :lisp-class-base "core::General_O"
47544754
:root-class "core::T_O" :stamp-wtag 3 :definition-data "IS_POLYMORPHIC"}
4755-
{class-kind :stamp-name "STAMPWTAG_comp__Context_O" :stamp-key "comp::Context_O"
4756-
:parent-class "core::General_O" :lisp-class-base "core::General_O"
4757-
:root-class "core::T_O" :stamp-wtag 3 :definition-data "IS_POLYMORPHIC"}
4758-
{fixed-field :offset-type-cxx-identifier "SMART_PTR_OFFSET"
4759-
:offset-ctype "gctools::smart_ptr<core::T_O>" :offset-base-ctype "comp::Context_O"
4760-
:layout-offset-field-names ("_receiving")}
4761-
{fixed-field :offset-type-cxx-identifier "SMART_PTR_OFFSET"
4762-
:offset-ctype "gctools::smart_ptr<core::List_V>" :offset-base-ctype "comp::Context_O"
4763-
:layout-offset-field-names ("_dynenv")}
4764-
{fixed-field :offset-type-cxx-identifier "SMART_PTR_OFFSET"
4765-
:offset-ctype "gctools::smart_ptr<core::T_O>" :offset-base-ctype "comp::Context_O"
4766-
:layout-offset-field-names ("_cfunction")}
47674755
{class-kind :stamp-name "STAMPWTAG_core__Scope_O" :stamp-key "core::Scope_O"
47684756
:parent-class "core::General_O" :lisp-class-base "core::General_O"
47694757
:root-class "core::T_O" :stamp-wtag 3 :definition-data "IS_POLYMORPHIC"}

0 commit comments

Comments
 (0)