Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ set(CODON_HPPFILES
codon/cir/transform/folding/const_prop.h
codon/cir/transform/folding/folding.h
codon/cir/transform/folding/rule.h
codon/cir/transform/lowering/await.h
codon/cir/transform/lowering/imperative.h
codon/cir/transform/lowering/pipeline.h
codon/cir/transform/manager.h
Expand Down Expand Up @@ -347,6 +348,7 @@ set(CODON_CPPFILES
codon/cir/transform/folding/const_fold.cpp
codon/cir/transform/folding/const_prop.cpp
codon/cir/transform/folding/folding.cpp
codon/cir/transform/lowering/await.cpp
codon/cir/transform/lowering/imperative.cpp
codon/cir/transform/lowering/pipeline.cpp
codon/cir/transform/manager.cpp
Expand Down
7 changes: 7 additions & 0 deletions codon/cir/analyze/dataflow/capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ struct ExtractVars : public util::ConstVisitor {

void visit(const FlowInstr *v) override { process(v->getValue()); }

void visit(const CoroHandleInstr *v) override {}

void visit(const dsl::CustomInstr *v) override {
// TODO
}
Expand Down Expand Up @@ -649,6 +651,11 @@ struct CaptureTracker : public util::Operator {
[&](DerivedSet &dset) { dset.result.returnCaptures = true; });
}

void handle(AwaitInstr *v) override {
forEachDSetOf(v->getValue(),
[&](DerivedSet &dset) { dset.result.returnCaptures = true; });
}

void handle(ThrowInstr *v) override {
forEachDSetOf(v->getValue(), [&](DerivedSet &dset) { dset.setExternCaptured(); });
}
Expand Down
7 changes: 7 additions & 0 deletions codon/cir/analyze/dataflow/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,11 @@ void CFVisitor::visit(const YieldInstr *v) {
defaultInsert(v);
}

void CFVisitor::visit(const AwaitInstr *v) {
process(v->getValue());
defaultInsert(v);
}

void CFVisitor::visit(const ThrowInstr *v) {
if (v->getValue())
process(v->getValue());
Expand All @@ -426,6 +431,8 @@ void CFVisitor::visit(const FlowInstr *v) {
defaultInsert(v);
}

void CFVisitor::visit(const CoroHandleInstr *v) { defaultInsert(v); }

void CFVisitor::visit(const dsl::CustomInstr *v) {
v->getCFBuilder()->buildCFNodes(this);
}
Expand Down
2 changes: 2 additions & 0 deletions codon/cir/analyze/dataflow/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,10 @@ class CFVisitor : public util::ConstVisitor {
void visit(const ContinueInstr *v) override;
void visit(const ReturnInstr *v) override;
void visit(const YieldInstr *v) override;
void visit(const AwaitInstr *v) override;
void visit(const ThrowInstr *v) override;
void visit(const FlowInstr *v) override;
void visit(const CoroHandleInstr *v) override;
void visit(const dsl::CustomInstr *v) override;

template <typename NodeType> void process(const NodeType *v) {
Expand Down
6 changes: 6 additions & 0 deletions codon/cir/analyze/module/side_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ struct SideEfectAnalyzer : public util::ConstVisitor {
set(v, max(Status::NO_CAPTURE, process(v->getValue())));
}

void visit(const AwaitInstr *v) override {
set(v, max(Status::NO_CAPTURE, process(v->getValue())));
}

void visit(const ThrowInstr *v) override {
process(v->getValue());
set(v, Status::UNKNOWN, Status::NO_CAPTURE);
Expand All @@ -341,6 +345,8 @@ struct SideEfectAnalyzer : public util::ConstVisitor {
set(v, max(process(v->getFlow()), process(v->getValue())));
}

void visit(const CoroHandleInstr *v) override { set(v, Status::PURE); }

void visit(const dsl::CustomInstr *v) override {
set(v, v->getSideEffectStatus(/*local=*/true),
v->getSideEffectStatus(/*local=*/false));
Expand Down
10 changes: 9 additions & 1 deletion codon/cir/func.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Func : public AcceptorExtend<Func, Var> {
std::string unmangledName;
/// whether the function is a generator
bool generator;
/// whether the function is an async function
bool async;
/// Parent type if func is a method, or null if not
types::Type *parentType;

Expand All @@ -36,7 +38,7 @@ class Func : public AcceptorExtend<Func, Var> {
/// @param name the function's name
explicit Func(std::string name = "")
: AcceptorExtend(nullptr, true, false, std::move(name)), generator(false),
parentType(nullptr) {}
async(false), parentType(nullptr) {}

/// Re-initializes the function with a new type and names.
/// @param newType the function's new type
Expand Down Expand Up @@ -73,6 +75,12 @@ class Func : public AcceptorExtend<Func, Var> {
/// @param v the new value
void setGenerator(bool v = true) { generator = v; }

/// @return true if the function is an async function
bool isAsync() const { return async; }
/// Sets the function's async flag.
/// @param v the new value
void setAsync(bool v = true) { async = v; }

/// @return the variable corresponding to the given argument name
/// @param n the argument name
Var *getArgVar(const std::string &n);
Expand Down
25 changes: 25 additions & 0 deletions codon/cir/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,24 @@ int YieldInInstr::doReplaceUsedType(const std::string &name, types::Type *newTyp
return 0;
}

const char AwaitInstr::NodeId = 0;

int AwaitInstr::doReplaceUsedValue(id_t id, Value *newValue) {
if (value->getId() == id) {
value = newValue;
return 1;
}
return 0;
}

int AwaitInstr::doReplaceUsedType(const std::string &name, types::Type *newType) {
if (type->getName() == name) {
type = newType;
return 1;
}
return 0;
}

const char TernaryInstr::NodeId = 0;

int TernaryInstr::doReplaceUsedValue(id_t id, Value *newValue) {
Expand Down Expand Up @@ -265,5 +283,12 @@ int FlowInstr::doReplaceUsedValue(id_t id, Value *newValue) {
return replacements;
}

const char CoroHandleInstr::NodeId = 0;

types::Type *CoroHandleInstr::doGetType() const {
auto *M = getModule();
return M->getPointerType(M->getByteType());
}

} // namespace ir
} // namespace codon
51 changes: 50 additions & 1 deletion codon/cir/instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ class YieldInInstr : public AcceptorExtend<YieldInInstr, Instr> {
/// @param v the new value
void setSuspending(bool v = true) { suspend = v; }

/// Sets the type being inspected
/// Sets the type.
/// @param t the new type
void setType(types::Type *t) { type = t; }

Expand Down Expand Up @@ -477,6 +477,7 @@ class ReturnInstr : public AcceptorExtend<ReturnInstr, ControlFlowInstr> {
int doReplaceUsedValue(id_t id, Value *newValue) override;
};

/// Instr representing a yield statement.
class YieldInstr : public AcceptorExtend<YieldInstr, Instr> {
private:
/// the value
Expand Down Expand Up @@ -509,6 +510,40 @@ class YieldInstr : public AcceptorExtend<YieldInstr, Instr> {
int doReplaceUsedValue(id_t id, Value *newValue) override;
};

/// Instr representing an await statement.
class AwaitInstr : public AcceptorExtend<AwaitInstr, Instr> {
private:
/// the value
Value *value;
/// the type of the result
types::Type *type;

public:
static const char NodeId;

explicit AwaitInstr(Value *value, types::Type *type, std::string name = "")
: AcceptorExtend(std::move(name)), value(value), type(type) {}

/// @return the value
Value *getValue() { return value; }
/// @return the value
const Value *getValue() const { return value; }
/// Sets the value.
/// @param v the new value
void setValue(Value *v) { value = v; }

/// Sets the type.
/// @param t the new type
void setType(types::Type *t) { type = t; }

protected:
types::Type *doGetType() const override { return type; }
std::vector<Value *> doGetUsedValues() const override { return {value}; }
std::vector<types::Type *> doGetUsedTypes() const override { return {type}; }
int doReplaceUsedValue(id_t id, Value *newValue) override;
int doReplaceUsedType(const std::string &name, types::Type *newType) override;
};

class ThrowInstr : public AcceptorExtend<ThrowInstr, Instr> {
private:
/// the value
Expand Down Expand Up @@ -573,5 +608,19 @@ class FlowInstr : public AcceptorExtend<FlowInstr, Instr> {
int doReplaceUsedValue(id_t id, Value *newValue) override;
};

/// Instr for obtaining the coroutine handle of the enclosing function.
/// Not emitted by any front-end; instead used internally in IR lowering.
class CoroHandleInstr : public AcceptorExtend<CoroHandleInstr, Instr> {
public:
static const char NodeId;

/// Constructs a coroutine handle instruction.
/// @param name the name
explicit CoroHandleInstr(std::string name = "") : AcceptorExtend(std::move(name)) {}

protected:
types::Type *doGetType() const override;
};

} // namespace ir
} // namespace codon
96 changes: 52 additions & 44 deletions codon/cir/llvm/llvisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2051,8 +2051,9 @@ void LLVMVisitor::visit(const BodiedFunc *x) {
}

auto *startBlock = llvm::BasicBlock::Create(*context, "start", func);
const bool generator = x->isGenerator() || x->isAsync();

if (x->isGenerator()) {
if (generator) {
func->setPresplitCoroutine();
auto *generatorType = cast<types::GeneratorType>(returnType);
seqassertn(generatorType, "{} is not a generator type", *returnType);
Expand Down Expand Up @@ -2140,7 +2141,7 @@ void LLVMVisitor::visit(const BodiedFunc *x) {
process(x->getBody());
B->SetInsertPoint(block);

if (x->isGenerator()) {
if (generator) {
B->CreateBr(coro.exit);
} else {
if (cast<types::VoidType>(returnType)) {
Expand Down Expand Up @@ -2251,12 +2252,7 @@ llvm::Type *LLVMVisitor::getLLVMType(types::Type *t) {
}

if (auto *x = cast<types::RefType>(t)) {
auto *p = B->getPtrTy();
if (x->isPolymorphic()) {
return llvm::StructType::get(*context, {p, p});
} else {
return p;
}
return B->getPtrTy();
}

if (auto *x = cast<types::FuncType>(t)) {
Expand Down Expand Up @@ -2425,37 +2421,37 @@ llvm::DIType *LLVMVisitor::getDITypeHelper(
if (auto *x = cast<types::RefType>(t)) {
auto *ref = db.builder->createReferenceType(
llvm::dwarf::DW_TAG_reference_type, getDITypeHelper(x->getContents(), cache));
if (x->isPolymorphic()) {
auto *p = B->getPtrTy();
auto pointerSizeInBits = layout.getTypeAllocSizeInBits(p);
auto *rtti = db.builder->createBasicType("rtti", pointerSizeInBits,
llvm::dwarf::DW_ATE_address);
auto *structType = llvm::StructType::get(p, p);
auto *structLayout = layout.getStructLayout(structType);
auto *srcInfo = getSrcInfo(x);
llvm::DIFile *file = db.getFile(srcInfo->file);
std::vector<llvm::Metadata *> members;

llvm::DICompositeType *diType = db.builder->createStructType(
file, x->getName(), file, srcInfo->line, structLayout->getSizeInBits(),
/*AlignInBits=*/0, llvm::DINode::FlagZero, /*DerivedFrom=*/nullptr,
db.builder->getOrCreateArray(members));

members.push_back(db.builder->createMemberType(
diType, "data", file, srcInfo->line, pointerSizeInBits,
/*AlignInBits=*/0, structLayout->getElementOffsetInBits(0),
llvm::DINode::FlagZero, ref));

members.push_back(db.builder->createMemberType(
diType, "rtti", file, srcInfo->line, pointerSizeInBits,
/*AlignInBits=*/0, structLayout->getElementOffsetInBits(1),
llvm::DINode::FlagZero, rtti));

db.builder->replaceArrays(diType, db.builder->getOrCreateArray(members));
return diType;
} else {
return ref;
}
// if (x->isPolymorphic()) {
// auto *p = B->getPtrTy();
// auto pointerSizeInBits = layout.getTypeAllocSizeInBits(p);
// auto *rtti = db.builder->createBasicType("rtti", pointerSizeInBits,
// llvm::dwarf::DW_ATE_address);
// auto *structType = llvm::StructType::get(p, p);
// auto *structLayout = layout.getStructLayout(structType);
// auto *srcInfo = getSrcInfo(x);
// llvm::DIFile *file = db.getFile(srcInfo->file);
// std::vector<llvm::Metadata *> members;

// llvm::DICompositeType *diType = db.builder->createStructType(
// file, x->getName(), file, srcInfo->line, structLayout->getSizeInBits(),
// /*AlignInBits=*/0, llvm::DINode::FlagZero, /*DerivedFrom=*/nullptr,
// db.builder->getOrCreateArray(members));

// members.push_back(db.builder->createMemberType(
// diType, "data", file, srcInfo->line, pointerSizeInBits,
// /*AlignInBits=*/0, structLayout->getElementOffsetInBits(0),
// llvm::DINode::FlagZero, ref));

// members.push_back(db.builder->createMemberType(
// diType, "rtti", file, srcInfo->line, pointerSizeInBits,
// /*AlignInBits=*/0, structLayout->getElementOffsetInBits(1),
// llvm::DINode::FlagZero, rtti));

// db.builder->replaceArrays(diType, db.builder->getOrCreateArray(members));
// return diType;
// } else {
return ref;
// }
}

if (auto *x = cast<types::FuncType>(t)) {
Expand Down Expand Up @@ -3284,9 +3280,10 @@ void LLVMVisitor::visit(const ExtractInstr *x) {
process(x->getVal());
B->SetInsertPoint(block);
if (auto *refType = cast<types::RefType>(memberedType)) {
if (refType->isPolymorphic())
value =
B->CreateExtractValue(value, 0); // polymorphic ref type is tuple (data, rtti)
if (refType->isPolymorphic()) {
// polymorphic ref type is ref to (data, rtti)
value = B->CreateLoad(B->getPtrTy(), value);
}
value = B->CreateLoad(getLLVMType(refType->getContents()), value);
}
value = B->CreateExtractValue(value, index);
Expand All @@ -3304,8 +3301,10 @@ void LLVMVisitor::visit(const InsertInstr *x) {
llvm::Value *rhs = value;

B->SetInsertPoint(block);
if (refType->isPolymorphic())
lhs = B->CreateExtractValue(lhs, 0); // polymorphic ref type is tuple (data, rtti)
if (refType->isPolymorphic()) {
// polymorphic ref type is ref to (data, rtti)
lhs = B->CreateLoad(B->getPtrTy(), lhs);
}
llvm::Value *load = B->CreateLoad(getLLVMType(refType->getContents()), lhs);
load = B->CreateInsertValue(load, rhs, index);
B->CreateStore(load, lhs);
Expand Down Expand Up @@ -3511,6 +3510,10 @@ void LLVMVisitor::visit(const YieldInstr *x) {
}
}

void LLVMVisitor::visit(const AwaitInstr *x) {
seqassertn(false, "await instruction not lowered");
}

void LLVMVisitor::visit(const ThrowInstr *x) {
if (DisableExceptions) {
B->SetInsertPoint(block);
Expand Down Expand Up @@ -3545,6 +3548,11 @@ void LLVMVisitor::visit(const FlowInstr *x) {
process(x->getValue());
}

void LLVMVisitor::visit(const CoroHandleInstr *x) {
seqassertn(coro.handle, "no coroutine handle");
value = coro.handle;
}

void LLVMVisitor::visit(const dsl::CustomInstr *x) {
B->SetInsertPoint(block);
value = x->getBuilder()->buildValue(this);
Expand Down
2 changes: 2 additions & 0 deletions codon/cir/llvm/llvisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,10 @@ class LLVMVisitor : public util::ConstVisitor {
void visit(const ContinueInstr *) override;
void visit(const ReturnInstr *) override;
void visit(const YieldInstr *) override;
void visit(const AwaitInstr *) override;
void visit(const ThrowInstr *) override;
void visit(const FlowInstr *) override;
void visit(const CoroHandleInstr *) override;
void visit(const dsl::CustomInstr *) override;
};

Expand Down
Loading
Loading