Skip to content

Commit 0e11b5e

Browse files
committed
bytecode: add support for constant tuples
1 parent 14586ac commit 0e11b5e

File tree

7 files changed

+98
-43
lines changed

7 files changed

+98
-43
lines changed

src/analysis/type_analysis.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ class BasicBlockTypePropagator : public StmtVisitor {
130130
return old_type;
131131
}
132132

133-
CompilerType* getConstantType(int vreg) {
134-
Box* o = code_constants.getConstant(vreg);
133+
CompilerType* getConstantType(Box* o) {
135134
if (o->cls == int_cls)
136135
return INT;
137136
else if (o->cls == float_cls)
@@ -148,10 +147,19 @@ class BasicBlockTypePropagator : public StmtVisitor {
148147
return NONE;
149148
else if (o->cls == ellipsis_cls)
150149
return typeFromClass(ellipsis_cls);
151-
else
150+
else if (o->cls == tuple_cls) {
151+
auto* tuple = (BoxedTuple*)o;
152+
std::vector<CompilerType*> elt_types;
153+
for (int i = 0; i < tuple->size(); ++i) {
154+
elt_types.push_back(getConstantType(tuple->elts[i]));
155+
}
156+
return makeTupleType(elt_types);
157+
} else
152158
RELEASE_ASSERT(0, "");
153159
}
154160

161+
CompilerType* getConstantType(int vreg) { return getConstantType(code_constants.getConstant(vreg)); }
162+
155163
CompilerType* getType(int vreg) {
156164
if (vreg == VREG_UNDEFINED)
157165
return UNDEF;

src/codegen/codegen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct GlobalState {
7373
llvm::Type* llvm_value_type, *llvm_value_type_ptr, *llvm_value_type_ptr_ptr;
7474
llvm::Type* llvm_class_type, *llvm_class_type_ptr;
7575
llvm::Type* llvm_opaque_type;
76-
llvm::Type* llvm_boxedstring_type_ptr, *llvm_dict_type_ptr;
76+
llvm::Type* llvm_boxedstring_type_ptr, *llvm_boxedtuple_type_ptr, *llvm_dict_type_ptr;
7777
llvm::Type* llvm_frame_info_type;
7878
llvm::Type* llvm_code_type_ptr, *llvm_closure_type_ptr, *llvm_generator_type_ptr;
7979
llvm::Type* llvm_module_type_ptr, *llvm_bool_type_ptr;

src/codegen/compvars.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,16 @@ _call(IREmitter& emitter, const OpInfo& info, llvm::Value* func, ExceptionStyle
650650
}
651651
llvm_args.push_back(arg_array);
652652

653-
if (pass_keyword_names)
654-
llvm_args.push_back(embedRelocatablePtr(keyword_names, g.vector_ptr));
653+
if (pass_keyword_names) {
654+
auto keyword_names_value = embedRelocatablePtr(keyword_names, g.llvm_boxedtuple_type_ptr);
655+
emitter.setType(keyword_names_value, RefType::BORROWED);
656+
llvm_args.push_back(keyword_names_value);
657+
}
655658
} else if (pass_keyword_names) {
656659
llvm_args.push_back(getNullPtr(g.llvm_value_type_ptr->getPointerTo()));
657-
llvm_args.push_back(embedRelocatablePtr(keyword_names, g.vector_ptr));
660+
auto keyword_names_value = embedRelocatablePtr(keyword_names, g.llvm_boxedtuple_type_ptr);
661+
emitter.setType(keyword_names_value, RefType::BORROWED);
662+
llvm_args.push_back(keyword_names_value);
658663
}
659664

660665
// f->dump();
@@ -2724,14 +2729,14 @@ CompilerType* makeTupleType(const std::vector<CompilerType*>& elt_types) {
27242729
return TupleType::make(elt_types);
27252730
}
27262731

2727-
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts) {
2732+
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts, ConcreteCompilerVariable* boxed) {
27282733
std::vector<CompilerType*> elt_types;
27292734
for (int i = 0; i < elts.size(); i++) {
27302735
elt_types.push_back(elts[i]->getType());
27312736
}
27322737
TupleType* type = TupleType::make(elt_types);
27332738

2734-
auto alloc_var = std::make_shared<TupleType::Unboxed>(elts, nullptr);
2739+
auto alloc_var = std::make_shared<TupleType::Unboxed>(elts, boxed);
27352740
return new TupleType::VAR(type, alloc_var);
27362741
}
27372742

src/codegen/compvars.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ CompilerVariable* makeUnicode(IREmitter& emitter, llvm::StringRef);
363363
CompilerVariable* makeFunction(IREmitter& emitter, BoxedCode*, llvm::Value* closure, llvm::Value* globals,
364364
const std::vector<ConcreteCompilerVariable*>& defaults);
365365
ConcreteCompilerVariable* undefVariable();
366-
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts);
366+
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts, ConcreteCompilerVariable* boxed = NULL);
367367

368368
CompilerType* typeOfClassobj(BoxedClass*);
369369
CompilerType* makeTupleType(const std::vector<CompilerType*>& elt_types);

src/codegen/irgen/irgenerator.cpp

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,34 +1225,42 @@ class IRGeneratorImpl : public IRGenerator {
12251225
}
12261226
}
12271227

1228+
CompilerVariable* evalConstObj(Box* o) {
1229+
if (o->cls == none_cls)
1230+
return emitter.getNone();
1231+
else if (o->cls == ellipsis_cls)
1232+
return getEllipsis();
1233+
1234+
llvm::Value* rtn = embedRelocatablePtr(o, g.llvm_value_type_ptr);
1235+
emitter.setType(rtn, RefType::BORROWED);
1236+
1237+
if (o->cls == int_cls)
1238+
return makeUnboxedInt(emitter, rtn);
1239+
else if (o->cls == float_cls)
1240+
return makeUnboxedFloat(emitter, rtn);
1241+
else if (o->cls == complex_cls)
1242+
return new ConcreteCompilerVariable(BOXED_COMPLEX, rtn);
1243+
else if (o->cls == long_cls)
1244+
return new ConcreteCompilerVariable(LONG, rtn);
1245+
else if (o->cls == str_cls)
1246+
return new ConcreteCompilerVariable(STR, rtn);
1247+
else if (o->cls == unicode_cls)
1248+
return new ConcreteCompilerVariable(typeFromClass(unicode_cls), rtn);
1249+
else if (o->cls == tuple_cls) {
1250+
auto* tuple = (BoxedTuple*)o;
1251+
std::vector<CompilerVariable*> elts;
1252+
for (int i = 0; i < tuple->size(); ++i) {
1253+
elts.push_back(evalConstObj(tuple->elts[i]));
1254+
}
1255+
return makeTuple(elts, new ConcreteCompilerVariable(BOXED_TUPLE, rtn));
1256+
} else
1257+
RELEASE_ASSERT(0, "");
1258+
}
1259+
12281260
CompilerVariable* evalVReg(int vreg, bool is_kill = true) {
12291261
assert(vreg != VREG_UNDEFINED);
1230-
if (vreg < 0) {
1231-
Box* o = irstate->getCode()->code_constants.getConstant(vreg);
1232-
1233-
if (o->cls == none_cls)
1234-
return emitter.getNone();
1235-
else if (o->cls == ellipsis_cls)
1236-
return getEllipsis();
1237-
1238-
llvm::Value* rtn = embedRelocatablePtr(o, g.llvm_value_type_ptr);
1239-
emitter.setType(rtn, RefType::BORROWED);
1240-
1241-
if (o->cls == int_cls)
1242-
return makeUnboxedInt(emitter, rtn);
1243-
else if (o->cls == float_cls)
1244-
return makeUnboxedFloat(emitter, rtn);
1245-
else if (o->cls == complex_cls)
1246-
return new ConcreteCompilerVariable(BOXED_COMPLEX, rtn);
1247-
else if (o->cls == long_cls)
1248-
return new ConcreteCompilerVariable(LONG, rtn);
1249-
else if (o->cls == str_cls)
1250-
return new ConcreteCompilerVariable(STR, rtn);
1251-
else if (o->cls == unicode_cls)
1252-
return new ConcreteCompilerVariable(typeFromClass(unicode_cls), rtn);
1253-
else
1254-
RELEASE_ASSERT(0, "");
1255-
}
1262+
if (vreg < 0)
1263+
return evalConstObj(irstate->getCode()->code_constants.getConstant(vreg));
12561264
CompilerVariable* rtn = symbol_table[vreg];
12571265
if (is_kill) {
12581266
symbol_table[vreg] = NULL;

src/codegen/runtime_hooks.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ void initGlobalFuncs(GlobalState& g) {
143143
assert(g.llvm_boxedstring_type_ptr);
144144
g.llvm_boxedstring_type_ptr = g.llvm_boxedstring_type_ptr->getPointerTo();
145145

146+
g.llvm_boxedtuple_type_ptr = g.stdlib_module->getTypeByName("class.pyston::BoxedTuple");
147+
assert(g.llvm_boxedtuple_type_ptr);
148+
g.llvm_boxedtuple_type_ptr = g.llvm_boxedtuple_type_ptr->getPointerTo();
149+
146150
g.llvm_dict_type_ptr = g.stdlib_module->getTypeByName("class.pyston::BoxedDict");
147151
assert(g.llvm_dict_type_ptr);
148152
g.llvm_dict_type_ptr = g.llvm_dict_type_ptr->getPointerTo();

src/core/cfg.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,22 @@ class CFGVisitor : public ASTVisitor {
16391639
return rtn;
16401640
}
16411641

1642+
bool isConstObject(AST* node) {
1643+
if (node->type == AST_TYPE::Str || node->type == AST_TYPE::Num)
1644+
return true;
1645+
else if (node->type == AST_TYPE::Tuple) {
1646+
auto* tuple = ast_cast<AST_Tuple>(node);
1647+
assert(tuple->ctx_type == AST_TYPE::Load);
1648+
for (auto&& elt : tuple->elts) {
1649+
if (!isConstObject(elt))
1650+
return false;
1651+
}
1652+
return true;
1653+
} else if (node->type == AST_TYPE::Name && ast_cast<AST_Name>(node)->id.s() == "None")
1654+
return true;
1655+
return false;
1656+
}
1657+
16421658
Box* createConstObject(AST* node) {
16431659
if (node->type == AST_TYPE::Str) {
16441660
auto* str = ast_cast<AST_Str>(node);
@@ -1681,12 +1697,28 @@ class CFGVisitor : public ASTVisitor {
16811697
return r;
16821698
} else
16831699
RELEASE_ASSERT(0, "not implemented");
1700+
} else if (node->type == AST_TYPE::Tuple) {
1701+
auto* tuple_node = ast_cast<AST_Tuple>(node);
1702+
BoxedTuple* tuple = BoxedTuple::create(tuple_node->elts.size());
1703+
for (int i = 0; i < tuple_node->elts.size(); ++i) {
1704+
tuple->elts[i] = createConstObject(tuple_node->elts[i]);
1705+
}
1706+
return tuple;
1707+
} else if (node->type == AST_TYPE::Name && ast_cast<AST_Name>(node)->id.s() == "None") {
1708+
return incref(Py_None);
16841709
}
16851710
RELEASE_ASSERT(0, "not implemented");
16861711
}
16871712

16881713
TmpValue remapTuple(AST_Tuple* node) {
16891714
assert(node->ctx_type == AST_TYPE::Load);
1715+
1716+
// handle tuples where all elements are constants as a constant
1717+
if (isConstObject(node)) {
1718+
Box* tuple = createConstObject(node);
1719+
return TmpValue(addConst(tuple), node->lineno);
1720+
}
1721+
16901722
llvm::SmallVector<TmpValue, 8> remapped_elts;
16911723
for (int i = 0; i < node->elts.size(); ++i) {
16921724
remapped_elts.emplace_back(remapExpr(node->elts[i]));
@@ -2040,12 +2072,6 @@ class CFGVisitor : public ASTVisitor {
20402072
}
20412073

20422074
bool visit_importfrom(AST_ImportFrom* node) override {
2043-
auto tuple = allocAndPush<BST_Tuple>(node->names.size());
2044-
for (int i = 0; i < node->names.size(); i++) {
2045-
unmapExpr(makeStr(node->names[i]->name.s()), &tuple->elts[i]);
2046-
}
2047-
TmpValue tuple_name = createDstName(tuple);
2048-
20492075
BST_ImportName* import = allocAndPush<BST_ImportName>();
20502076
import->lineno = node->lineno;
20512077

@@ -2059,7 +2085,11 @@ class CFGVisitor : public ASTVisitor {
20592085
level = node->level;
20602086
import->level = level;
20612087

2062-
unmapExpr(tuple_name, &import->vreg_from);
2088+
auto* tuple = BoxedTuple::create(node->names.size());
2089+
for (int i = 0; i < node->names.size(); i++) {
2090+
tuple->elts[i] = internStringMortal(node->names[i]->name.s());
2091+
}
2092+
import->vreg_from = addConst(tuple);
20632093
import->index_id = remapInternedString(internString(node->module.s()));
20642094

20652095
TmpValue tmp_module_name = createDstName(import);

0 commit comments

Comments
 (0)