Commit 584f94a8 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Lots more annotations

parent d3c92a78
......@@ -513,6 +513,12 @@ void RewriterVar::xdecref() {
}
void Rewriter::_incref(RewriterVar* var) {
// Small optimization: skip any time we want to do xincref(NULL)
if (var->isConstant() && var->constant_value == 0) {
assert(var->nullable);
return;
}
assert(!var->nullable);
//assembler->trap();
//auto reg = var->getInReg();
......
......@@ -314,6 +314,7 @@ public:
#ifndef NDEBUG
// XXX: for testing, reset these on deallocation so that we will see the next time they get set.
~RewriterVar() {
rewriter = (Rewriter*)-1;
reftype = (RefType)-1;
num_refs_consumed = -11;
}
......
......@@ -256,6 +256,7 @@ public:
void delattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr) override {
llvm::Constant* ptr = embedRelocatablePtr(attr, g.llvm_boxedstring_type_ptr);
emitter.setType(ptr, RefType::BORROWED);
// TODO
// bool do_patchpoint = ENABLE_ICDELATTRS;
......@@ -283,8 +284,8 @@ public:
llvm::Value* cls_value = emitter.getBuilder()->CreateLoad(cls_ptr);
assert(cls_value->getType() == g.llvm_class_type_ptr);
llvm::Value* rtn
= emitter.getBuilder()->CreateICmpEQ(cls_value, embedRelocatablePtr(cls, g.llvm_class_type_ptr));
llvm::Value* rtn = emitter.getBuilder()->CreateICmpEQ(
cls_value, emitter.setType(embedRelocatablePtr(cls, g.llvm_class_type_ptr), RefType::BORROWED));
return rtn;
}
......@@ -1604,12 +1605,14 @@ CompilerVariable* makeUnboxedFloat(IREmitter& emitter, llvm::Value* v) {
}
ConcreteCompilerVariable* makeLong(Box* v) {
return new ConcreteCompilerVariable(LONG, embedRelocatablePtr(v, g.llvm_value_type_ptr));
ConcreteCompilerVariable* makeLong(IREmitter& emitter, Box* v) {
return new ConcreteCompilerVariable(
LONG, emitter.setType(embedRelocatablePtr(v, g.llvm_value_type_ptr), RefType::BORROWED));
}
ConcreteCompilerVariable* makePureImaginary(Box* v) {
return new ConcreteCompilerVariable(BOXED_COMPLEX, embedRelocatablePtr(v, g.llvm_value_type_ptr));
ConcreteCompilerVariable* makePureImaginary(IREmitter& emitter, Box* v) {
return new ConcreteCompilerVariable(
BOXED_COMPLEX, emitter.setType(embedRelocatablePtr(v, g.llvm_value_type_ptr), RefType::BORROWED));
}
class KnownClassobjType : public ValuedCompilerType<BoxedClass*> {
......@@ -1742,11 +1745,13 @@ public:
ASSERT(rtattr, "%s.%s", debugName().c_str(), attr->data());
if (rtattr->cls == function_cls) {
CompilerVariable* clattr = new ConcreteCompilerVariable(
typeFromClass(function_cls), embedRelocatablePtr(rtattr, g.llvm_value_type_ptr));
typeFromClass(function_cls),
emitter.setType(embedRelocatablePtr(rtattr, g.llvm_value_type_ptr), RefType::BORROWED));
return InstanceMethodType::makeIM(
var, clattr,
new ConcreteCompilerVariable(UNKNOWN, embedRelocatablePtr(cls, g.llvm_value_type_ptr)));
new ConcreteCompilerVariable(
UNKNOWN, emitter.setType(embedRelocatablePtr(cls, g.llvm_value_type_ptr), RefType::BORROWED)));
}
}
......@@ -1895,6 +1900,7 @@ public:
llvm_value = embedRelocatablePtr(value, g.llvm_value_type_ptr);
else
llvm_value = getNullPtr(g.llvm_value_type_ptr);
emitter.setType(llvm_value, RefType::BORROWED);
new_args.push_back(new ConcreteCompilerVariable(UNKNOWN, llvm_value));
}
......@@ -2465,6 +2471,7 @@ public:
}
llvm::Value* rtn = emitter.getBuilder()->CreateCall2(g.funcs.createTuple, nelts, scratch);
emitter.setType(rtn, RefType::OWNED);
return new ConcreteCompilerVariable(other_type, rtn);
}
......
......@@ -353,8 +353,8 @@ CompilerVariable* makeUnboxedFloat(IREmitter&, ConcreteCompilerVariable*);
CompilerVariable* makeUnboxedFloat(IREmitter&, llvm::Value*);
ConcreteCompilerVariable* makeBool(bool);
ConcreteCompilerVariable* makeLong(Box*);
ConcreteCompilerVariable* makePureImaginary(Box*);
ConcreteCompilerVariable* makeLong(IREmitter&, Box*);
ConcreteCompilerVariable* makePureImaginary(IREmitter&, Box*);
CompilerVariable* makeStr(BoxedString*);
CompilerVariable* makeUnicode(Box*);
......
......@@ -218,6 +218,7 @@ llvm::Value* IRGenState::getFrameInfoVar() {
// frame_info.boxedLocals = createDict()
// (Since this can call into the GC, we have to initialize it to NULL first as we did above.)
this->boxed_locals = builder.CreateCall(g.funcs.createDict);
getRefcounts()->setType(this->boxed_locals, RefType::OWNED);
builder.CreateStore(this->boxed_locals, boxed_locals_gep);
}
......@@ -782,6 +783,7 @@ private:
llvm::Value* name_arg
= embedRelocatablePtr(irstate->getSourceInfo()->parent_module->getStringConstant(name, true),
g.llvm_boxedstring_type_ptr);
emitter.setType(name_arg, RefType::BORROWED);
llvm::Value* r
= emitter.createCall2(unw_info, g.funcs.importFrom, converted_module->getValue(), name_arg);
......@@ -819,9 +821,10 @@ private:
assert(ast_str->str_type == AST_Str::STR);
const std::string& module_name = ast_str->str_data;
llvm::Value* imported = emitter.createCall(unw_info, g.funcs.import,
llvm::Value* imported = emitter.createCall(
unw_info, g.funcs.import,
{ getConstantInt(level, g.i32), converted_froms->getValue(),
embedRelocatablePtr(module_name.c_str(), g.i8_ptr),
emitter.setType(embedRelocatablePtr(module_name.c_str(), g.i8_ptr), RefType::BORROWED),
getConstantInt(module_name.size(), g.i64) });
ConcreteCompilerVariable* v = new ConcreteCompilerVariable(UNKNOWN, imported);
return v;
......@@ -1085,8 +1088,8 @@ private:
ConcreteCompilerVariable* getEllipsis() {
llvm::Constant* ellipsis = embedRelocatablePtr(Ellipsis, g.llvm_value_type_ptr, "cEllipsis");
auto ellipsis_cls = Ellipsis->cls;
emitter.setType(ellipsis, RefType::BORROWED);
auto ellipsis_cls = Ellipsis->cls;
return new ConcreteCompilerVariable(typeFromClass(ellipsis_cls), ellipsis);
}
......@@ -1185,6 +1188,7 @@ private:
} else if (vst == ScopeInfo::VarScopeType::NAME) {
llvm::Value* boxedLocals = irstate->getBoxedLocalsVar();
llvm::Value* attr = embedRelocatablePtr(node->id.getBox(), g.llvm_boxedstring_type_ptr);
emitter.setType(attr, RefType::BORROWED);
llvm::Value* module = irstate->getGlobals();
llvm::Value* r = emitter.createCall3(unw_info, g.funcs.boxedLocalsGet, boxedLocals, attr, module);
return new ConcreteCompilerVariable(UNKNOWN, r);
......@@ -1196,7 +1200,8 @@ private:
llvm::CallSite call = emitter.createCall(
unw_info, g.funcs.assertNameDefined,
{ getConstantInt(0, g.i1), embedRelocatablePtr(node->id.c_str(), g.i8_ptr),
embedRelocatablePtr(UnboundLocalError, g.llvm_class_type_ptr), getConstantInt(true, g.i1) });
emitter.setType(embedRelocatablePtr(UnboundLocalError, g.llvm_class_type_ptr), RefType::BORROWED),
getConstantInt(true, g.i1) });
call.setDoesNotReturn();
return undefVariable();
}
......@@ -1209,7 +1214,8 @@ private:
emitter.createCall(
unw_info, g.funcs.assertNameDefined,
{ i1FromBool(emitter, is_defined_var), embedRelocatablePtr(node->id.c_str(), g.i8_ptr),
embedRelocatablePtr(UnboundLocalError, g.llvm_class_type_ptr), getConstantInt(true, g.i1) });
emitter.setType(embedRelocatablePtr(UnboundLocalError, g.llvm_class_type_ptr), RefType::BORROWED),
getConstantInt(true, g.i1) });
// At this point we know the name must be defined (otherwise the assert would have fired):
_popFake(defined_name);
......@@ -1230,9 +1236,10 @@ private:
} else if (node->num_type == AST_Num::FLOAT) {
return makeFloat(node->n_float);
} else if (node->num_type == AST_Num::COMPLEX) {
return makePureImaginary(irstate->getSourceInfo()->parent_module->getPureImaginaryConstant(node->n_float));
return makePureImaginary(emitter,
irstate->getSourceInfo()->parent_module->getPureImaginaryConstant(node->n_float));
} else {
return makeLong(irstate->getSourceInfo()->parent_module->getLongConstant(node->n_long));
return makeLong(emitter, irstate->getSourceInfo()->parent_module->getLongConstant(node->n_long));
}
}
......@@ -1299,6 +1306,7 @@ private:
} else if (node->str_type == AST_Str::UNICODE) {
llvm::Value* rtn = embedRelocatablePtr(
irstate->getSourceInfo()->parent_module->getUnicodeConstant(node->str_data), g.llvm_value_type_ptr);
emitter.setType(rtn, RefType::BORROWED);
return new ConcreteCompilerVariable(typeFromClass(unicode_cls), rtn);
} else {
......@@ -1404,8 +1412,10 @@ private:
ConcreteCompilerVariable* converted_attr_dict = attr_dict->makeConverted(emitter, attr_dict->getBoxType());
llvm::Value* classobj = emitter.createCall3(
unw_info, g.funcs.createUserClass, embedRelocatablePtr(node->name.getBox(), g.llvm_boxedstring_type_ptr),
unw_info, g.funcs.createUserClass,
emitter.setType(embedRelocatablePtr(node->name.getBox(), g.llvm_boxedstring_type_ptr), RefType::BORROWED),
bases_tuple->getValue(), converted_attr_dict->getValue());
emitter.setType(classobj, RefType::OWNED);
// Note: createuserClass is free to manufacture non-class objects
CompilerVariable* cls = new ConcreteCompilerVariable(UNKNOWN, classobj);
......@@ -1703,6 +1713,7 @@ private:
// TODO inefficient
llvm::Value* boxedLocals = irstate->getBoxedLocalsVar();
llvm::Value* attr = embedRelocatablePtr(name.getBox(), g.llvm_boxedstring_type_ptr);
emitter.setType(attr, RefType::BORROWED);
emitter.createCall3(unw_info, g.funcs.boxedLocalsSet, boxedLocals, attr,
val->makeConverted(emitter, UNKNOWN)->getValue());
} else {
......@@ -1888,13 +1899,15 @@ private:
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
// Can't use delattr since the errors are different:
emitter.createCall2(unw_info, g.funcs.delGlobal, irstate->getGlobals(),
embedRelocatablePtr(target->id.getBox(), g.llvm_boxedstring_type_ptr));
emitter.setType(embedRelocatablePtr(target->id.getBox(), g.llvm_boxedstring_type_ptr),
RefType::BORROWED));
return;
}
if (vst == ScopeInfo::VarScopeType::NAME) {
llvm::Value* boxedLocals = irstate->getBoxedLocalsVar();
llvm::Value* attr = embedRelocatablePtr(target->id.getBox(), g.llvm_boxedstring_type_ptr);
emitter.setType(attr, RefType::BORROWED);
emitter.createCall2(unw_info, g.funcs.boxedLocalsDel, boxedLocals, attr);
return;
}
......@@ -1904,10 +1917,10 @@ private:
assert(vst == ScopeInfo::VarScopeType::FAST);
if (symbol_table.count(target->id) == 0) {
llvm::CallSite call
= emitter.createCall(unw_info, g.funcs.assertNameDefined,
llvm::CallSite call = emitter.createCall(
unw_info, g.funcs.assertNameDefined,
{ getConstantInt(0, g.i1), embedConstantPtr(target->id.c_str(), g.i8_ptr),
embedRelocatablePtr(NameError, g.llvm_class_type_ptr),
emitter.setType(embedRelocatablePtr(NameError, g.llvm_class_type_ptr), RefType::BORROWED),
getConstantInt(true /*local_error_msg*/, g.i1) });
call.setDoesNotReturn();
return;
......@@ -1917,9 +1930,10 @@ private:
ConcreteCompilerVariable* is_defined_var = static_cast<ConcreteCompilerVariable*>(_getFake(defined_name, true));
if (is_defined_var) {
emitter.createCall(unw_info, g.funcs.assertNameDefined,
emitter.createCall(
unw_info, g.funcs.assertNameDefined,
{ i1FromBool(emitter, is_defined_var), embedConstantPtr(target->id.c_str(), g.i8_ptr),
embedRelocatablePtr(NameError, g.llvm_class_type_ptr),
emitter.setType(embedRelocatablePtr(NameError, g.llvm_class_type_ptr), RefType::BORROWED),
getConstantInt(true /*local_error_msg*/, g.i1) });
_popFake(defined_name);
}
......@@ -2244,7 +2258,7 @@ private:
ConcreteCompilerVariable* converted = v->makeConverted(emitter, v->getBoxType());
args.push_back(converted->getValue());
} else {
args.push_back(embedRelocatablePtr(None, g.llvm_value_type_ptr, "cNone"));
args.push_back(emitter.getNone()->getValue());
}
}
......
......@@ -104,6 +104,11 @@ void addIncrefs(llvm::Value* v, bool nullable, int num_refs, llvm::Instruction*
llvm::IRBuilder<true> builder(incref_pt);
// Deal with subtypes of Box:
while (v->getType() != g.llvm_value_type_ptr) {
v = builder.CreateConstInBoundsGEP2_32(v, 0, 0);
}
if (nullable) {
cur_block = incref_pt->getParent();
continue_block = cur_block->splitBasicBlock(incref_pt);
......@@ -148,6 +153,12 @@ void addDecrefs(llvm::Value* v, bool nullable, int num_refs, llvm::Instruction*
assert(num_refs > 0);
llvm::IRBuilder<true> builder(decref_pt);
// Deal with subtypes of Box:
while (v->getType() != g.llvm_value_type_ptr) {
v = builder.CreateConstInBoundsGEP2_32(v, 0, 0);
}
#ifdef Py_REF_DEBUG
auto reftotal_gv = g.cur_module->getOrInsertGlobal("_Py_RefTotal", g.i64);
auto reftotal = new llvm::LoadInst(reftotal_gv, "", decref_pt);
......@@ -671,8 +682,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
if (VERBOSITY()) {
fprintf(stderr, "After refcounts:\n");
fprintf(stderr, "\033[35m");
f->dump();
//dumpPrettyIR(f);
dumpPrettyIR(f);
fprintf(stderr, "\033[0m");
}
}
......
......@@ -79,7 +79,7 @@ enum class RefType {
UNKNOWN
#ifndef NDEBUG
// Set this to non-zero to make it possible for the debugger to
= 0
= 1
#endif
,
OWNED,
......
......@@ -1868,34 +1868,40 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
if (flags == METH_VARARGS) {
rtn = (Box*)func(self->passthrough, arg1);
if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1)
->setType(RefType::OWNED);
} else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)func)(self->passthrough, arg1, arg2);
if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2);
rewrite_args->arg2)->setType(RefType::OWNED);
} else if (flags == METH_NOARGS) {
rtn = (Box*)func(self->passthrough, NULL);
if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(
true, (void*)func, r_passthrough, rewrite_args->rewriter->loadConst(0, Location::forArg(1)));
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough,
rewrite_args->rewriter->loadConst(0, Location::forArg(1)))
->setType(RefType::OWNED);
} else if (flags == METH_O) {
rtn = (Box*)func(self->passthrough, arg1);
if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1)
->setType(RefType::OWNED);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
assert(paramspec.totalReceived() <= 3); // would need to pass through oargs
rtn = ((Box * (*)(Box*, Box*, Box*, Box*))func)(self->passthrough, arg1, arg2, arg3);
if (rewrite_args) {
if (paramspec.totalReceived() == 1)
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
else if (paramspec.totalReceived() == 2)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough,
rewrite_args->arg1, rewrite_args->arg2);
rewrite_args->arg1)->setType(RefType::OWNED);
else if (paramspec.totalReceived() == 2)
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2)->setType(RefType::OWNED);
else if (paramspec.totalReceived() == 3)
rewrite_args->out_rtn = rewrite_args->rewriter->call(
true, (void*)func, r_passthrough, rewrite_args->arg1, rewrite_args->arg2, rewrite_args->arg3);
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2, rewrite_args->arg3)->setType(RefType::OWNED);
else
abort();
}
......
......@@ -1248,9 +1248,9 @@ void Box::setattr(BoxedString* attr, BORROWED(Box*) val, SetattrRewriteArgs* rew
// will tell the auto-refcount system to decref it.
r_hattrs->getAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs))
->setType(RefType::OWNED);
// TODO make this stealing
r_hattrs->setAttr(offset * sizeof(Box*) + offsetof(HCAttrs::AttrList, attrs),
rewrite_args->attrval);
rewrite_args->attrval->refConsumed();
rewrite_args->out_success = true;
}
......@@ -2591,7 +2591,9 @@ template <ExceptionStyle S> Box* _getattrEntry(Box* obj, BoxedString* attr, void
if (attr->interned_state == SSTATE_INTERNED_IMMORTAL) {
if (return_convention == ReturnConvention::NO_RETURN) {
assert(!rtn);
rtn = rewriter->loadConst(0, Location::forArg(1));
rtn = rewriter->loadConst(0, Location::forArg(1))
->setType(RefType::BORROWED)
->setNullable(true);
}
rewriter->call(true, (void*)NoexcHelper::call, rtn, rewriter->getArg(0),
rewriter->loadConst((intptr_t)attr, Location::forArg(2)));
......@@ -2770,10 +2772,8 @@ void setattrGeneric(Box* obj, BoxedString* attr, STOLEN(Box*) val, SetattrRewrit
raiseAttributeError(obj, attr->s());
}
// TODO: make setattr() stealing
// TODO: make Box::setattr() stealing
obj->setattr(attr, val, rewrite_args);
if (rewrite_args)
rewrite_args->attrval->refConsumed();
Py_DECREF(val);
}
......@@ -3798,7 +3798,7 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
for (int i = 0; i < num_output_args - 3; i++) {
rewrite_args->args->getAttr(i * sizeof(Box*))
->setType(RefType::BORROWED)
->setNullable(true)
->setNullable(argspec.has_kwargs)
->refConsumed();
}
}
......@@ -6782,6 +6782,7 @@ extern "C" void setGlobal(Box* globals, BoxedString* name, STOLEN(Box*) value) {
setattr(static_cast<BoxedModule*>(globals), name, value);
} else {
RELEASE_ASSERT(globals->cls == dict_cls, "%s", globals->cls->tp_name);
assert(0 && "check refcounting");
static_cast<BoxedDict*>(globals)->d[name] = value;
}
}
......
......@@ -1108,6 +1108,10 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
throw e;
}
AUTO_XDECREF(made);
AUTO_XDECREF(arg2);
AUTO_XDECREF(arg3);
if (!rewrite_success)
rewrite_args = NULL;
......
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