Skip to content

Commit

Permalink
Merge pull request #804 from undingen/more_ics2
Browse files Browse the repository at this point in the history
Rewrite unaryop and property get
  • Loading branch information
kmod committed Aug 7, 2015
2 parents 96febb0 + ebf842d commit 2f5d72d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
18 changes: 16 additions & 2 deletions src/codegen/irgen/irgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,8 +1395,22 @@ class IRGeneratorImpl : public IRGenerator {
ConcreteCompilerVariable* converted = operand->makeConverted(emitter, operand->getBoxType());
operand->decvref(emitter);

llvm::Value* rtn = emitter.createCall2(unw_info, g.funcs.unaryop, converted->getValue(),
getConstantInt(node->op_type, g.i32));
llvm::Value* rtn = NULL;
bool do_patchpoint = ENABLE_ICGENERICS;
if (do_patchpoint) {
ICSetupInfo* pp = createGenericIC(getEmptyOpInfo(unw_info).getTypeRecorder(), true, 256);

std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(converted->getValue());
llvm_args.push_back(getConstantInt(node->op_type, g.i32));

llvm::Value* uncasted = emitter.createIC(pp, (void*)pyston::unaryop, llvm_args, unw_info);
rtn = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
} else {
rtn = emitter.createCall2(unw_info, g.funcs.unaryop, converted->getValue(),
getConstantInt(node->op_type, g.i32));
}

converted->decvref(emitter);

return new ConcreteCompilerVariable(UNKNOWN, rtn, true);
Expand Down
38 changes: 32 additions & 6 deletions src/runtime/objmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,13 +1321,28 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedS
}

else if (descr->cls == property_cls) {
rewrite_args = NULL; // TODO
REWRITE_ABORTED("");

BoxedProperty* prop = static_cast<BoxedProperty*>(descr);
if (prop->prop_get == NULL || prop->prop_get == None) {
raiseExcHelper(AttributeError, "unreadable attribute");
}

if (rewrite_args) {
r_descr->addAttrGuard(offsetof(BoxedProperty, prop_get), (intptr_t)prop->prop_get);

RewriterVar* r_prop_get = r_descr->getAttr(offsetof(BoxedProperty, prop_get));
CallRewriteArgs crewrite_args(rewrite_args->rewriter, r_prop_get, rewrite_args->destination);
crewrite_args.arg1 = rewrite_args->obj;

Box* rtn = runtimeCallInternal1<CXX>(prop->prop_get, &crewrite_args, ArgPassSpec(1), obj);
if (!crewrite_args.out_success) {
rewrite_args = NULL;
} else {
rewrite_args->out_success = true;
rewrite_args->out_rtn = crewrite_args.out_rtn;
}
return rtn;
}

return runtimeCallInternal1<CXX>(prop->prop_get, NULL, ArgPassSpec(1), obj);
}

Expand Down Expand Up @@ -4451,12 +4466,23 @@ extern "C" Box* unaryop(Box* operand, int op_type) {

BoxedString* op_name = getOpName(op_type);

CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* rtn = callattr(operand, op_name, callattr_flags, NULL, NULL, NULL, NULL, NULL);
std::unique_ptr<Rewriter> rewriter(
Rewriter::createRewriter(__builtin_extract_return_addr(__builtin_return_address(0)), 1, "unaryop"));

Box* rtn = NULL;
if (rewriter) {
CallRewriteArgs srewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination());
rtn = callattrInternal0(operand, op_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(0));
if (srewrite_args.out_success && rtn)
rewriter->commitReturning(srewrite_args.out_rtn);
else
rewriter.reset();
} else
rtn = callattrInternal0(operand, op_name, CLASS_ONLY, NULL, ArgPassSpec(0));

if (rtn == NULL) {
raiseExcHelper(TypeError, "bad operand type for unary '%s': '%s'", op_name->c_str(), getTypeName(operand));
}

return rtn;
}

Expand Down
10 changes: 10 additions & 0 deletions test/tests/property_ics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# run_args: -n
# statcheck: noninit_count('slowpath_getattr') <= 25

class C(object):
@property
def prop(self):
return 42
c = C()
for i in xrange(1000):
a = c.prop
7 changes: 7 additions & 0 deletions test/tests/unaryop_ics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# run_args: -n
# statcheck: noninit_count('slowpath_unaryop') <= 10
# statcheck: noninit_count('slowpath_runtimecall') <= 10

for i in xrange(1000):
print -i
print ~i

0 comments on commit 2f5d72d

Please sign in to comment.