Commit 349c4d4b authored by Marius Wachtler's avatar Marius Wachtler

always_use_version support CAPI and CXX

parent 2974bf34
......@@ -1970,13 +1970,13 @@ static const slotdef* update_one_slot(BoxedClass* type, const slotdef* p) noexce
sanity checks. I'll buy the first person to
point out a bug in this reasoning a beer. */
} else if (offset == offsetof(BoxedClass, tp_descr_get) && descr->cls == function_cls
&& static_cast<BoxedFunction*>(descr)->md->always_use_version) {
CompiledFunction* cf = static_cast<BoxedFunction*>(descr)->md->always_use_version;
if (cf->exception_style == CXX) {
type->tpp_descr_get = (descrgetfunc)cf->code;
&& !static_cast<BoxedFunction*>(descr)->md->always_use_version.empty()) {
auto md = static_cast<BoxedFunction*>(descr)->md;
if (md->always_use_version.get<CAPI>())
specific = md->always_use_version.get<CAPI>();
else {
type->tpp_descr_get = (descrgetfunc)md->always_use_version.get<CXX>()->code;
specific = (void*)slot_tp_tpp_descr_get;
} else {
specific = cf->code;
}
} else if (descr == Py_None && ptr == (void**)&type->tp_hash) {
/* We specifically allow __hash__ to be set to None
......
......@@ -47,7 +47,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_
takes_kwargs(takes_kwargs),
source(std::move(source)),
param_names(this->source->ast, this->source->getInternedStrings()),
always_use_version(NULL),
times_interpreted(0),
internal_callable(NULL, NULL) {
}
......@@ -59,7 +58,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_
takes_kwargs(takes_kwargs),
source(nullptr),
param_names(param_names),
always_use_version(NULL),
times_interpreted(0),
internal_callable(NULL, NULL) {
}
......@@ -81,9 +79,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) {
if (compiled->entry_descriptor == NULL) {
bool could_have_speculations = (source.get() != NULL);
if (!could_have_speculations && versions.size() == 0 && compiled->effort == EffortLevel::MAXIMAL
&& compiled->spec->accepts_all_inputs && compiled->spec->boxed_return_value)
always_use_version = compiled;
if (!could_have_speculations && compiled->effort == EffortLevel::MAXIMAL && compiled->spec->accepts_all_inputs
&& compiled->spec->boxed_return_value
&& (versions.size() == 0 || (versions.size() == 1 && !always_use_version.empty()))) {
always_use_version.get(compiled->exception_style) = compiled;
} else
assert(always_use_version.empty());
assert(compiled->spec->arg_types.size() == numReceivedArgs());
versions.push_back(compiled);
......
......@@ -648,7 +648,7 @@ void CompiledFunction::speculationFailed() {
FunctionMetadata* md = this->md;
assert(md);
assert(this != md->always_use_version);
assert(this != md->always_use_version.get(exception_style));
bool found = false;
for (int i = 0; i < md->versions.size(); i++) {
......
......@@ -95,19 +95,22 @@ public:
ExceptionSwitchable() : capi_val(), cxx_val() {}
ExceptionSwitchable(T capi_val, T cxx_val) : capi_val(std::move(capi_val)), cxx_val(std::move(cxx_val)) {}
template <ExceptionStyle S> T get() {
template <ExceptionStyle S> T& get() {
if (S == CAPI)
return capi_val;
else
return cxx_val;
}
T get(ExceptionStyle S) {
T& get(ExceptionStyle S) {
if (S == CAPI)
return capi_val;
else
return cxx_val;
}
bool empty() const { return !capi_val && !cxx_val; }
void clear() { *this = ExceptionSwitchable<T>(); }
};
template <typename R, typename... Args>
......@@ -470,7 +473,8 @@ public:
FunctionList
versions; // any compiled versions along with their type parameters; in order from most preferred to least
CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases)
ExceptionSwitchable<CompiledFunction*>
always_use_version; // if this version is set, always use it (for unboxed cases)
std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions;
// Profiling counter:
......
......@@ -3959,12 +3959,20 @@ static inline RewriterVar* getArg(int idx, _CallRewriteArgsBase* rewrite_args) {
}
static StatCounter slowpath_pickversion("slowpath_pickversion");
static CompiledFunction* pickVersion(FunctionMetadata* f, ExceptionStyle S, int num_output_args, Box* oarg1, Box* oarg2,
Box* oarg3, Box** oargs) {
template <ExceptionStyle S>
static CompiledFunction* pickVersion(FunctionMetadata* f, int num_output_args, Box* oarg1, Box* oarg2, Box* oarg3,
Box** oargs) {
LOCK_REGION(codegen_rwlock.asWrite());
if (f->always_use_version && f->always_use_version->exception_style == S)
return f->always_use_version;
// if always_use_version is set use it even if the exception style does not match.
// But prefer using the correct style if both are available
if (f->always_use_version.get(S))
return f->always_use_version.get(S);
ExceptionStyle other = S == CAPI ? CXX : CAPI;
if (f->always_use_version.get(other))
return f->always_use_version.get(other);
slowpath_pickversion.log();
CompiledFunction* best_nonexcmatch = NULL;
......@@ -4845,7 +4853,7 @@ Box* callCLFunc(FunctionMetadata* md, CallRewriteArgs* rewrite_args, int num_out
rewrite_args = NULL;
}
CompiledFunction* chosen_cf = pickVersion(md, S, num_output_args, oarg1, oarg2, oarg3, oargs);
CompiledFunction* chosen_cf = pickVersion<S>(md, num_output_args, oarg1, oarg2, oarg3, oargs);
if (!chosen_cf) {
if (rewrite_args) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment