summaryrefslogtreecommitdiff
path: root/willow/lib
diff options
context:
space:
mode:
Diffstat (limited to 'willow/lib')
-rw-r--r--willow/lib/IR/IRBuilder.cpp210
-rw-r--r--willow/lib/IR/TypeContext.cpp31
-rw-r--r--willow/lib/IR/Value.cpp54
-rw-r--r--willow/lib/IR/Verifier.cpp29
4 files changed, 281 insertions, 43 deletions
diff --git a/willow/lib/IR/IRBuilder.cpp b/willow/lib/IR/IRBuilder.cpp
new file mode 100644
index 0000000..62e7a98
--- /dev/null
+++ b/willow/lib/IR/IRBuilder.cpp
@@ -0,0 +1,210 @@
+#include <willow/IR/IRBuilder.h>
+
+namespace willow {
+
+AddInst *IRBuilder::BuildAdd(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new AddInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+MulInst *IRBuilder::BuildMul(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new MulInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+SubInst *IRBuilder::BuildSub(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new SubInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+DivInst *IRBuilder::BuildDiv(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new DivInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+ModInst *IRBuilder::BuildMod(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new ModInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+ShlInst *IRBuilder::BuildShl(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new ShlInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+ShrInst *IRBuilder::BuildShr(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new ShrInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+AshlInst *IRBuilder::BuildAshl(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new AshlInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+AshrInst *IRBuilder::BuildAshr(Type type, Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new AshrInst{type, lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+EqInst *IRBuilder::BuildEq(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new EqInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+LtInst *IRBuilder::BuildLt(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new LtInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+GtInst *IRBuilder::BuildGt(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new GtInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+LeInst *IRBuilder::BuildLe(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new LeInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+GeInst *IRBuilder::BuildGe(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new GeInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+AndInst *IRBuilder::BuildAnd(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new AndInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+OrInst *IRBuilder::BuildOr(Value *lhs, Value *rhs,
+ std::optional<Location> loc) {
+ auto *inst = new OrInst{ctx.types().IntType(1), lhs, rhs, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+NotInst *IRBuilder::BuildNot(Value *val, std::optional<Location> loc) {
+ auto *inst = new NotInst{ctx.types().IntType(1), val, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+JmpInst *IRBuilder::BuildJmp(BasicBlock *dst, std::optional<Location> loc) {
+
+ auto *inst = new JmpInst{ctx.types().VoidType(), dst, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+BrInst *IRBuilder::BuildBr(Value *predicate, BasicBlock *truedst,
+ BasicBlock *falsedst, std::optional<Location> loc) {
+ auto *inst =
+ new BrInst{ctx.types().VoidType(), predicate, truedst, falsedst, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+RetInst *IRBuilder::BuildRet(Value *val, std::optional<Location> loc) {
+ auto *inst = new RetInst{ctx.types().VoidType(), val, loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+RetInst *IRBuilder::BuildRet(std::optional<Location> loc) {
+ auto *inst = new RetInst{ctx.types().VoidType(), loc};
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+PhiInst *IRBuilder::BuildPhi(
+ Type ty, std::initializer_list<std::pair<BasicBlock *, Value *>> args,
+ std::optional<Location> loc) {
+ auto *inst = new PhiInst(ty, args, loc);
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+AllocaInst *IRBuilder::BuildAlloca(Type ty, std::optional<Location> loc) {
+ Type pty = ctx.types().PtrType(ty);
+ auto *inst = new AllocaInst(pty, loc);
+ insert_point->insertAfter(*inst);
+ insert_point++;
+
+ return inst;
+}
+
+}; // namespace willow
diff --git a/willow/lib/IR/TypeContext.cpp b/willow/lib/IR/TypeContext.cpp
index e69de29..21e5173 100644
--- a/willow/lib/IR/TypeContext.cpp
+++ b/willow/lib/IR/TypeContext.cpp
@@ -0,0 +1,31 @@
+#include <willow/IR/TypeContext.h>
+
+namespace willow {
+
+Type TypeContext::IntType(std::size_t width) {
+ auto [it, _] = icache.try_emplace(IntTypeImpl::Key{width},
+ std::make_unique<IntTypeImpl>(width));
+
+ return Type(it->second.get());
+}
+
+Type TypeContext::PtrType(Type pointee) {
+ auto [it, _] = pcache.try_emplace(
+ PtrTypeImpl::Key{pointee}, std::make_unique<PtrTypeImpl>(pointee));
+
+ return Type(it->second.get());
+}
+
+Type TypeContext::VoidType() { return Type(voidty.get()); }
+
+Type TypeContext::BasicBlockType() { return Type{labelty.get()}; }
+
+Type TypeContext::FunctionType(Type ret, std::initializer_list<Type> params) {
+ auto [it, _] =
+ fncache.try_emplace(FunctionTypeImpl::Key{ret, params},
+ std::make_unique<FunctionTypeImpl>(ret, params));
+
+ return Type(it->second.get());
+};
+
+};
diff --git a/willow/lib/IR/Value.cpp b/willow/lib/IR/Value.cpp
index 13e029f..0bd1079 100644
--- a/willow/lib/IR/Value.cpp
+++ b/willow/lib/IR/Value.cpp
@@ -1,27 +1,27 @@
-#include <willow/IR/Value.h>
-#include <willow/IR/Constant.h>
-#include <ostream>
-
-std::ostream &operator<<(std::ostream &os, const willow::Value &v) {
- using willow::ValueKind;
- auto ty = v.getType();
- if (!v.isVoid())
- os << ty << " ";
-
- switch (v.getValueKind()) {
- case ValueKind::Parameter:
- [[fallthrough]];
- case ValueKind::Instruction: {
- return os << "%" << v.getName();
- }
- case ValueKind::BasicBlock: {
- return os << "^" << v.getName();
- }
- case ValueKind::Function: {
- return os << "@" << v.getName();
- }
- case ValueKind::Constant: {
- return os << *static_cast<const willow::Constant*>(&v);
- }
- }
-}
+// #include <willow/IR/Value.h>
+// #include <willow/IR/Constant.h>
+// #include <ostream>
+//
+// std::ostream &operator<<(std::ostream &os, const willow::Value &v) {
+// using willow::ValueKind;
+// auto ty = v.getType();
+// if (!v.isVoid())
+// os << ty << " ";
+//
+// switch (v.getValueKind()) {
+// case ValueKind::Parameter:
+// [[fallthrough]];
+// case ValueKind::Instruction: {
+// return os << "%" << v.getName();
+// }
+// case ValueKind::BasicBlock: {
+// return os << "^" << v.getName();
+// }
+// case ValueKind::Function: {
+// return os << "@" << v.getName();
+// }
+// case ValueKind::Constant: {
+// return os << *static_cast<const willow::Constant*>(&v);
+// }
+// }
+// }
diff --git a/willow/lib/IR/Verifier.cpp b/willow/lib/IR/Verifier.cpp
index d19bc83..b622f10 100644
--- a/willow/lib/IR/Verifier.cpp
+++ b/willow/lib/IR/Verifier.cpp
@@ -1,3 +1,4 @@
+#include <iostream>
#include <willow/IR/BasicBlock.h>
#include <willow/IR/Diagnostic.h>
#include <willow/IR/DiagnosticEngine.h>
@@ -75,20 +76,19 @@ LogicalResult verifyBasicBlock(WillowContext &ctx, const BasicBlock &BB,
DiagnosticEngine &diags) {
if (BB.empty())
return emit(diags, Severity::Error, BB.getLoc())
- << "Basic block '" << BB.getName() << "' has an empty body";
+ << "Basic block has empty body";
- if (!BB.trailer()->isTerminator())
+ if (!BB.trailer().isTerminator())
return emit(diags, Severity::Error, BB.getLoc())
- << "Basic block '" << BB.getName()
- << "' does not end with a terminator";
+ << "Basic block does not end with a terminator";
bool has_failed = false;
- for (auto &inst : BB.getBody()) {
+ for (auto& inst : BB) {
// verify inst
if (failed(verifyInst(ctx, inst, diags)))
has_failed = true;
- if (&inst != BB.trailer() && inst.isTerminator())
+ if (&inst != &BB.trailer() && inst.isTerminator())
return emit(diags, Severity::Error, BB.getLoc())
<< "Illegal terminator in the middle of a block";
}
@@ -219,11 +219,9 @@ LogicalResult verifyInst(WillowContext &ctx, const Instruction &inst,
if (aty == pty)
continue;
- DiagnosticBuilder d(diags, Severity::Error, inst.getLoc());
- d << "invalid argument: expected '" << pty << "', got '" << aty << "'";
- if (param.hasName())
- d.note(Diagnostic{Severity::Remark,
- std::format("param name: {}", param.getName())});
+ return emit(diags, Severity::Error, inst.getLoc())
+ << "invalid argument: expected '" << pty << "', got '" << aty
+ << "'";
return failure();
}
@@ -266,8 +264,7 @@ LogicalResult verifyInst(WillowContext &ctx, const Instruction &inst,
if (BB && fn && (pred->getParent() != fn))
return emit(diags, Severity::Error, inst.getLoc())
- << "basic block: '" << pred->getName()
- << "' is not a child of function '" << fn->getName() << "'";
+ << "invalid predecessor";
}
return success();
@@ -344,14 +341,14 @@ LogicalResult verifyBinaryIntegerCmp(WillowContext &ctx,
}
LogicalResult verifyResult(const Instruction &inst, DiagnosticEngine &diags) {
- if (inst.hasName())
- return success();
+ if (!inst.getType().isVoid())
+ return success();
return emit(diags, Severity::Error, inst.getLoc()) << "expected ssa result";
}
LogicalResult verifyNoResult(const Instruction &inst, DiagnosticEngine &diags) {
- if (!inst.hasName())
+ if (inst.getType().isVoid())
return success();
return emit(diags, Severity::Error, inst.getLoc()) << "unexpected ssa result";