Skip to content

Commit 183fcbf

Browse files
committed
feat: better isel and subscript selection
1 parent 785215e commit 183fcbf

16 files changed

Lines changed: 485 additions & 69 deletions

File tree

include/cinder/hir/builder.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Builder {
1212
[[nodiscard]] const BasicBlock* insert_point() const { return insert_point_; }
1313

1414
ConstantInt* const_i32(int32_t value);
15+
ConstantInt* const_i64(int64_t value);
1516
Function* create_function(Module* parent, std::string_view name, type::QualType function_type);
1617
Argument* create_argument(std::string_view name, Function* parent, type::QualType type,
1718
uint8_t index);
@@ -43,6 +44,7 @@ class Builder {
4344
// Comparisons
4445

4546
// Casts
47+
Value* create_sext(type::QualType type, Value* val);
4648

4749
// Memory
4850
Instruction* create_load(type::QualType load_type, Value* address);

include/cinder/isel/isel.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include "cinder/lir/aarch64/aarch64_builder.hpp"
88

99
namespace cinder::isel {
10+
struct MemAddr {
11+
lir::aarch64::Register base;
12+
std::uint64_t imm;
13+
};
1014

1115
/// Greedy maximal-munch instruction selection, HIR -> AArch64 LIR.
1216
///
@@ -38,7 +42,14 @@ class Isel {
3842
Register munch_const(const hir::ConstantInt* constant);
3943
Register munch_srem(hir::Instruction* inst);
4044
Register munch_call(hir::Instruction* inst);
41-
45+
Register munch_load(hir::Instruction* inst);
46+
Register munch_gep(hir::Instruction* inst);
47+
Register munch_sext(hir::Instruction* inst);
48+
void munch_store(hir::Instruction* inst);
49+
Register materialize_const(std::uint64_t value);
50+
MemAddr match_address(hir::Value* val, unsigned access_byte);
51+
const hir::ConstantInt* index_const(hir::Value* val) const;
52+
static std::uint64_t gep_element_size(hir::Instruction* gep);
4253
void munch_ret(hir::Instruction* inst);
4354

4455
lir::aarch64::Aarch64Builder builder_;

include/cinder/lir/aarch64/aarch64.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum class Opcode : uint8_t {
1515
PHI,
1616

1717
ADDXrr,
18+
ADDXrs,
1819
ADDWrr,
1920
ADDXri,
2021
ADDWri,
@@ -53,6 +54,14 @@ enum class Opcode : uint8_t {
5354
STRXui,
5455
STRWui,
5556

57+
SXTBr,
58+
SXTHr,
59+
SXTWr,
60+
61+
LDRBui,
62+
LDRHui,
63+
STRBui,
64+
STRHui,
5665
CMPXrr,
5766
CMPWrr,
5867
CMPXri,

include/cinder/lir/aarch64/aarch64_builder.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ class Aarch64Builder {
6767
void create_ret(Register implicit_value);
6868

6969
Register emit_rr(Opcode opcode, Register lhs, Register rhs);
70+
Register emit_r(Opcode opcode, Register lhs);
7071
Register emit_rrr(Opcode opcode, Register a, Register b, Register c);
7172
Register emit_ri(Opcode opcode, Register lhs, std::uint64_t imm);
73+
Register emit_load(Opcode op, Register base, std::uint64_t imm);
74+
void emit_store(Opcode op, Register src, Register base, std::uint64_t imm);
75+
Register emit_rr_shift(Opcode op, Register rn, Register rm, unsigned shift);
7276

7377
private:
7478
Instruction* insert(Instruction* instruction);

include/cinder/lir/aarch64/target_spec.hpp

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

33
#include <array>
4+
#include <cstdint>
45

56
#include "cinder/lir/aarch64/aarch64.hpp"
67
namespace cinder::lir::aarch64 {
@@ -72,7 +73,7 @@ static constexpr Register w30 = Register::preg(30, Register::RegClass::GPR32);
7273
static constexpr Register fp = x29;
7374
static constexpr Register lr = x30;
7475

75-
static constexpr std::array<Register, 8> arg_registers{x0, x1, x2, x3, x4, x5, x6, x7};
76+
static constexpr std::array<uint8_t, 8> arg_registers{0, 1, 2, 3, 4, 5, 6, 7};
7677

7778
static constexpr std::array<Register, 19> caller_saved{
7879
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18};

src/driver/driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ bool CompilationUnit::compile() {
7070
lir::aarch64::Module* lir_module = isel.run(module);
7171
// std::cout << lir_printer.print_module(*lir_module);
7272
regalloc::allocate_registers(*lir_module, arena);
73-
std::cout << lir_printer.print_module(*lir_module);
73+
// std::cout << lir_printer.print_module(*lir_module);
7474
lir::aarch64::AsmEmitter emitter{};
7575
std::string asm_string = emitter.emit_module(*lir_module);
7676
std::ofstream out_file("out.s");

src/hir/builder.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ ConstantInt* Builder::const_i32(std::int32_t value) {
1313
static_cast<std::uint64_t>(value));
1414
}
1515

16+
ConstantInt* Builder::const_i64(std::int64_t value) {
17+
return arena_.create<ConstantInt>(type::QualType{types_.get_int()},
18+
static_cast<std::uint64_t>(value));
19+
}
20+
1621
Function* Builder::create_function(Module* parent, std::string_view name,
1722
type::QualType function_type) {
1823
auto* function = arena_.create<Function>(name, function_type, parent, Linkage::Internal);
@@ -99,6 +104,17 @@ Instruction* Builder::create_ashr(Value* lhs, Value* rhs) {
99104
return create_binary(Opcode::AShr, lhs, rhs);
100105
}
101106

107+
Value* Builder::create_sext(type::QualType type, Value* val) {
108+
if (val->kind() == hir::ValueKind::ConstantInt) {
109+
const auto* c = static_cast<const hir::ConstantInt*>(val);
110+
// value() is already int64_t; sign extension of a signed value to a wider
111+
// signed type is the identity on the stored representation.
112+
return const_i64(c->value());
113+
}
114+
auto* inst =
115+
arena_.create<Instruction>(Opcode::SExt, type, insert_point_, std::vector<Value*>{val});
116+
return insert(inst);
117+
}
102118
Instruction* Builder::create_gep(type::QualType type, Value* ptr,
103119
const std::vector<Value*>& offsets) {
104120
std::vector<Value*> operands(offsets);

src/hirgen/hirgen.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ hir::Value* HIRGen::emit_lvalue(ast::Expr* expr) {
173173
base = emit_rvalue(sub->base()); // load the pointer value
174174
}
175175
hir::Value* index = emit_rvalue(sub->index());
176-
return builder_.create_gep(expr->type().value(), base, {index}); // pointer-to-element
176+
hir::Value* sign_extended = builder_.create_sext(expr->type().value(), index);
177+
return builder_.create_gep(expr->type().value(), base,
178+
{sign_extended}); // pointer-to-element
177179
}
178180
default:
179181
break;

0 commit comments

Comments
 (0)