Skip to content

Commit 0f30e9c

Browse files
committed
feat: add more hir gen paths, added lir infra, added max munch infra
1 parent 66ae67f commit 0f30e9c

21 files changed

Lines changed: 385 additions & 17 deletions

include/cinder/alloc/arena.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22

3-
#include <algorithm>
43
#include <bit>
54
#include <cassert>
65
#include <cstddef>

include/cinder/ast/ast_dumper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ class ASTDumper : public ASTVisitor {
367367

368368
void visit(SubscriptExpr& expr) override {
369369
print_indent();
370-
print_stmt_kind("ArraySubscriptExpr");
370+
print_stmt_kind("SubscriptExpr");
371371
print_addr(&expr);
372372
print_loc(expr.span());
373373
out_ << "\n";

include/cinder/hir/builder.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class Builder {
4545
// Casts
4646

4747
// Memory
48+
Instruction* create_load(type::QualType load_type, Value* address);
49+
void create_store(Value* address, type::QualType store_type);
50+
Instruction* create_gep(type::QualType type, Value* ptr, const std::vector<Value*>& offsets);
4851
Instruction* create_alloca(type::QualType allocated_type,
4952
std::string_view name); // Subject to Change I guess
5053

include/cinder/hir/function.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,23 @@ class Argument;
1414

1515
class Function final : public Value {
1616
public:
17-
explicit Function(std::string_view name, type::QualType type, Module* parent)
18-
: Value(ValueKind::Function, type), name_(name), parent_(parent) {}
17+
explicit Function(std::string_view name, type::QualType type, Module* parent, Linkage linkage)
18+
: Value(ValueKind::Function, type), name_(name), parent_(parent), linkage_(linkage) {}
1919

2020
void add_block(BasicBlock* basic_block) { blocks_.push_back(basic_block); }
2121
void add_argument(Argument* basic_block) { arguments_.push_back(basic_block); }
2222

2323
std::string_view name() const { return name_; }
2424
const std::vector<BasicBlock*>& blocks() const { return blocks_; }
2525
Module* parent() const { return parent_; }
26+
Linkage linkage() const { return linkage_; }
2627

2728
private:
2829
std::string_view name_;
2930
std::vector<BasicBlock*> blocks_;
3031
std::vector<Argument*> arguments_;
3132
Module* parent_;
33+
Linkage linkage_;
3234
};
3335

3436
class Argument : public Value {

include/cinder/hir/hir.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
#include "cinder/hir/module.hpp"
77
#include "cinder/hir/opcode.hpp"
88
#include "cinder/hir/value.hpp"
9+
10+
namespace cinder::hir {} // namespace cinder::hir

include/cinder/hir/instruction.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace cinder::hir {
66

77
class BasicBlock;
88

9-
class Instruction final : public Value, public arena::ListHook<Instruction> {
9+
class Instruction : public Value, public arena::ListHook<Instruction> {
1010
public:
1111
explicit Instruction(Opcode opcode, type::QualType type, BasicBlock* parent,
1212
std::vector<Value*> operands)
@@ -43,4 +43,5 @@ class PoisonValue final : public Value {
4343
public:
4444
PoisonValue(type::QualType type) : Value(ValueKind::Poison, type) {}
4545
};
46+
4647
} // namespace cinder::hir

include/cinder/hir/value.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class Use {
99
public:
1010
};
1111

12+
enum class Linkage : uint8_t { Internal, External };
1213
enum class ValueKind {
1314
Function,
1415
BasicBlock,

include/cinder/hirgen/hirgen.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class HIRGen {
2929
hir::Value* emit_integer_literal(ast::IntegerLiteralExpr* expr);
3030
hir::Value* emit_binary_expr(ast::BinaryExpr* expr);
3131
hir::Value* emit_decl_ref_expr(ast::DeclRefExpr* expr);
32+
hir::Value* emit_subscript_expr(ast::SubscriptExpr* expr);
3233
hir::Value* emit_call_expr(ast::CallExpr* expr);
3334
hir::Value* emit_rvalue(ast::Expr* expr);
3435
hir::Value* emit_lvalue(ast::Expr* expr);

include/cinder/isel/isel.hpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
#include <unordered_map>
3+
4+
#include "cinder/alloc/arena.hpp"
5+
#include "cinder/hir/hir.hpp"
6+
#include "cinder/lir/aarch64/aarch64.hpp"
7+
#include "cinder/lir/lir.hpp"
8+
9+
namespace cinder::isel {
10+
11+
class Isel {
12+
public:
13+
explicit Isel(arena::Arena& arena) : arena_(arena) {}
14+
lir::aarch64::Function* run(hir::Function* function);
15+
16+
private:
17+
using Register = lir::aarch64::Register;
18+
using Opcode = lir::aarch64::Opcode;
19+
20+
void compute_use_counts(hir::Function* function);
21+
bool foldable(hir::Value* value) const;
22+
const hir::ConstantInt* foldable_const(hir::Value* operand) const;
23+
24+
Register munch(hir::Value* value);
25+
Register munch_binary(hir::Instruction* inst);
26+
Register munch_const(const hir::ConstantInt* constant);
27+
Register munch_srem(hir::Instruction* inst);
28+
void munch_ret(hir::Instruction* inst);
29+
30+
Register fresh_vreg() { return Register::vreg(next_vreg_++, Register::RegClass::GPR64); }
31+
Register emit_rr(Opcode op, Register lhs, Register rhs);
32+
Register emit_ri(Opcode op, Register lhs, std::uint64_t imm);
33+
34+
arena::Arena& arena_;
35+
lir::aarch64::BasicBlock* insert_point_ = nullptr;
36+
std::uint32_t next_vreg_ = 0;
37+
38+
std::unordered_map<const hir::Value*, int> use_counts_;
39+
std::unordered_map<const hir::Value*, Register> emitted_;
40+
};
41+
} // namespace cinder::isel
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#pragma once
2+
#include <cstdint>
3+
#include <vector>
4+
5+
#include "cinder/alloc/arena_list.hpp"
6+
7+
namespace cinder::lir::aarch64 {
8+
9+
enum class Opcode : uint8_t {
10+
COPY,
11+
PHI,
12+
13+
ADDXrr,
14+
ADDXri,
15+
16+
SUBXrr,
17+
SUBXri,
18+
MSUBrrr,
19+
20+
MULXrr,
21+
SDIVrr,
22+
23+
ANDXrr,
24+
ORRXrr,
25+
EORXrr,
26+
27+
LSLXri,
28+
LSRXri,
29+
ASRXri,
30+
31+
MOVZ,
32+
MOVK,
33+
34+
LDRXui,
35+
STRXui,
36+
37+
CMPXrr,
38+
CMPXri,
39+
40+
B,
41+
B_EQ,
42+
B_NE,
43+
B_LT,
44+
B_LE,
45+
B_GE,
46+
47+
BL,
48+
RET,
49+
};
50+
class Register final {
51+
public:
52+
enum class Kind : uint8_t { Virtual, Phyiscal };
53+
enum class RegClass : uint8_t {
54+
GPR32,
55+
GPR64,
56+
FPR32,
57+
FPR64,
58+
59+
VECTOR_128
60+
};
61+
62+
explicit constexpr Register(Kind kind, uint32_t id, RegClass reg_class)
63+
: id_(id), kind_(kind), reg_class_(reg_class) {}
64+
65+
static constexpr Register vreg(uint32_t id, RegClass reg_class) {
66+
return Register(Kind::Virtual, id, reg_class);
67+
}
68+
69+
static constexpr Register preg(uint32_t id, RegClass reg_class) {
70+
return Register(Kind::Phyiscal, id, reg_class);
71+
}
72+
73+
[[nodiscard]] uint32_t id() const { return id_; }
74+
[[nodiscard]] RegClass reg_class() const { return reg_class_; }
75+
[[nodiscard]] Kind kind() const { return kind_; }
76+
77+
private:
78+
uint32_t id_;
79+
Kind kind_;
80+
RegClass reg_class_;
81+
};
82+
83+
class StackSlot final {};
84+
85+
class Operand {
86+
public:
87+
enum class Kind { Register, Immediate, StackSlot };
88+
static constexpr Operand reg(Register r) { return Operand(r); }
89+
static constexpr Operand imm(std::uint64_t value) { return Operand(value); }
90+
static constexpr Operand slot(StackSlot s) { return Operand(s); }
91+
92+
[[nodiscard]] Kind kind() const { return kind_; }
93+
94+
[[nodiscard]] bool is_register() const { return kind_ == Kind::Register; }
95+
[[nodiscard]] bool is_immediate() const { return kind_ == Kind::Register; }
96+
[[nodiscard]] bool is_stack_slot() const { return kind_ == Kind::Register; }
97+
98+
[[nodiscard]] Register reg() const {
99+
assert(kind_ == Kind::Register && "Called reg() on non register operand");
100+
return reg_;
101+
}
102+
[[nodiscard]] uint64_t imm() const {
103+
assert(kind_ == Kind::Immediate && "Called imm() on non immediate operand");
104+
return imm_;
105+
}
106+
[[nodiscard]] StackSlot stack_slot() const {
107+
assert(kind_ == Kind::StackSlot && "Called stack_slot() on non stack_slot operand");
108+
return stack_slot_;
109+
}
110+
111+
private:
112+
explicit constexpr Operand(Register reg) : kind_(Kind::Register), reg_(reg) {}
113+
explicit constexpr Operand(uint64_t imm) : kind_(Kind::Immediate), imm_(imm) {}
114+
explicit constexpr Operand(StackSlot slot) : kind_(Kind::StackSlot), stack_slot_(slot) {}
115+
116+
Kind kind_;
117+
union {
118+
Register reg_;
119+
uint64_t imm_;
120+
StackSlot stack_slot_;
121+
};
122+
};
123+
124+
class Instruction final : public arena::ListHook<Instruction> {
125+
public:
126+
explicit Instruction(Opcode opcode, std::vector<Operand> uses, std::vector<Register> defs,
127+
std::vector<Register> implicit_uses = {},
128+
std::vector<Register> implicit_defs = {})
129+
: opcode_(opcode),
130+
defs_(std::move(defs)),
131+
uses_(std::move(uses)),
132+
implicit_defs_(std::move(implicit_defs)),
133+
implicit_uses_(std::move(implicit_uses)) {}
134+
135+
[[nodiscard]] Opcode opcode() const { return opcode_; }
136+
137+
[[nodiscard]] const std::vector<Operand>& uses() const { return uses_; }
138+
[[nodiscard]] std::vector<Operand>& uses_mut() { return uses_; }
139+
140+
[[nodiscard]] Operand operand(unsigned n) const { return uses_[n]; }
141+
142+
[[nodiscard]] const std::vector<Register>& defs() const { return defs_; }
143+
[[nodiscard]] std::vector<Register>& defs_mut() { return defs_; }
144+
145+
[[nodiscard]] const std::vector<Register>& implicit_uses() const { return implicit_uses_; }
146+
[[nodiscard]] const std::vector<Register>& implicit_defs() const { return implicit_defs_; }
147+
148+
private:
149+
Opcode opcode_;
150+
std::vector<Register> defs_;
151+
std::vector<Operand> uses_;
152+
std::vector<Register> implicit_defs_;
153+
std::vector<Register> implicit_uses_;
154+
};
155+
156+
class BasicBlock final : public arena::ListHook<BasicBlock> {
157+
public:
158+
void add_instruction(Instruction* instruction) { instructions_.push_back(instruction); }
159+
160+
arena::ArenaList<Instruction>& instructions_mut() { return instructions_; }
161+
const arena::ArenaList<Instruction>& instructions() const { return instructions_; }
162+
163+
private:
164+
arena::ArenaList<Instruction> instructions_;
165+
};
166+
167+
class Function final : public arena::ListHook<Function> {
168+
public:
169+
private:
170+
arena::ArenaList<BasicBlock> blocks_;
171+
};
172+
173+
class Module final {
174+
public:
175+
private:
176+
arena::ArenaList<Function> functions_;
177+
};
178+
} // namespace cinder::lir::aarch64

0 commit comments

Comments
 (0)