Commit b4e3ede1 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Statically resolve tuple-pack-then-unpack, since we use that for LANDINGPAD

This seems like a cleaner way to allow type-specific codegen -- make
all types by default defer to UNKNOWN's handling of unpack().  Override
the unpack() method in [Unboxed]TupleType to do the unpacking statically
if possible.
parent 7bb48009
......@@ -380,6 +380,22 @@ public:
assert(vals.size() == 1);
return reinterpret_cast<Box*>(vals[0]);
}
std::vector<CompilerVariable*> unpack(IREmitter& emitter, const OpInfo& info, VAR* var, int num_into) override {
llvm::Value* unpacked = emitter.createCall2(info.unw_info, g.funcs.unpackIntoArray, var->getValue(),
getConstantInt(num_into, g.i64));
assert(unpacked->getType() == g.llvm_value_type_ptr->getPointerTo());
std::vector<CompilerVariable*> rtn;
for (int i = 0; i < num_into; i++) {
llvm::Value* ptr = emitter.getBuilder()->CreateConstGEP1_32(unpacked, i);
llvm::Value* val = emitter.getBuilder()->CreateLoad(ptr);
assert(val->getType() == g.llvm_value_type_ptr);
rtn.push_back(new ConcreteCompilerVariable(UNKNOWN, val, true));
}
return rtn;
}
};
ConcreteCompilerType* UNKNOWN = new UnknownType();
......@@ -1986,6 +2002,18 @@ public:
rtn += e->numFrameArgs();
return rtn;
}
std::vector<CompilerVariable*> unpack(IREmitter& emitter, const OpInfo& info, VAR* var, int num_into) override {
if (num_into != elt_types.size()) {
return ValuedCompilerType::unpack(emitter, info, var, num_into);
}
// Not sure if this is right:
for (auto e : *var->getValue())
e->incvref();
return *var->getValue();
}
};
CompilerType* makeTupleType(const std::vector<CompilerType*>& elt_types) {
......
......@@ -158,6 +158,8 @@ public:
return getConcreteType()->guaranteedClass();
}
virtual void serializeToFrame(VAR* v, std::vector<llvm::Value*>& stackmap_args) = 0;
virtual std::vector<CompilerVariable*> unpack(IREmitter& emitter, const OpInfo& info, VAR* var, int num_into);
};
template <class V> class ValuedCompilerType : public _ValuedCompilerType<V> { public: };
......@@ -264,6 +266,8 @@ public:
AST_TYPE::AST_TYPE op_type, BinExpType exp_type) = 0;
virtual void serializeToFrame(std::vector<llvm::Value*>& stackmap_args) = 0;
virtual std::vector<CompilerVariable*> unpack(IREmitter& emitter, const OpInfo& info, int num_into) = 0;
};
template <class V> class ValuedCompilerVariable : public CompilerVariable {
......@@ -357,6 +361,10 @@ public:
void serializeToFrame(std::vector<llvm::Value*>& stackmap_args) override {
type->serializeToFrame(this, stackmap_args);
}
std::vector<CompilerVariable*> unpack(IREmitter& emitter, const OpInfo& info, int num_into) override {
return type->unpack(emitter, info, this, num_into);
}
};
// template <>
......@@ -383,6 +391,17 @@ CompilerType* makeFuncType(ConcreteCompilerType* rtn_type, const std::vector<Con
ConcreteCompilerVariable* boolFromI1(IREmitter&, llvm::Value*);
llvm::Value* i1FromBool(IREmitter&, ConcreteCompilerVariable*);
template <typename V>
std::vector<CompilerVariable*> _ValuedCompilerType<V>::unpack(IREmitter& emitter, const OpInfo& info, VAR* var,
int num_into) {
assert((CompilerType*)this != UNKNOWN);
ConcreteCompilerVariable* converted = makeConverted(emitter, var, UNKNOWN);
auto r = UNKNOWN->unpack(emitter, info, converted, num_into);
converted->decvref(emitter);
return r;
}
} // namespace pyston
#endif
......@@ -1406,9 +1406,7 @@ private:
assert(state != PARTIAL);
int ntargets = target->elts.size();
// TODO can do faster unpacking of non-instantiated tuples; ie for something like
// a, b = 1, 2
// We shouldn't need to do any runtime error checking or allocations
std::vector<CompilerVariable*> unpacked = val->unpack(emitter, getOpInfoForNode(target, unw_info), ntargets);
#ifndef NDEBUG
for (auto e : target->elts) {
......@@ -1417,19 +1415,8 @@ private:
}
#endif
ConcreteCompilerVariable* converted_val = val->makeConverted(emitter, val->getBoxType());
llvm::Value* unpacked = emitter.createCall2(unw_info, g.funcs.unpackIntoArray, converted_val->getValue(),
getConstantInt(ntargets, g.i64));
assert(unpacked->getType() == g.llvm_value_type_ptr->getPointerTo());
converted_val->decvref(emitter);
for (int i = 0; i < ntargets; i++) {
llvm::Value* ptr = emitter.getBuilder()->CreateConstGEP1_32(unpacked, i);
llvm::Value* val = emitter.getBuilder()->CreateLoad(ptr);
assert(val->getType() == g.llvm_value_type_ptr);
CompilerVariable* thisval = new ConcreteCompilerVariable(UNKNOWN, val, true);
CompilerVariable* thisval = unpacked[i];
_doSet(target->elts[i], thisval, unw_info);
thisval->decvref(emitter);
}
......
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