Use an instruction instead of a special-case boolean instruction.
This commit is contained in:
parent
fb5a8a5a73
commit
8a44109f93
11
13/ast.cpp
11
13/ast.cpp
|
@ -3,6 +3,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "binop.hpp"
|
#include "binop.hpp"
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
#include "instruction.hpp"
|
||||||
#include "type.hpp"
|
#include "type.hpp"
|
||||||
#include "type_env.hpp"
|
#include "type_env.hpp"
|
||||||
#include "env.hpp"
|
#include "env.hpp"
|
||||||
|
@ -308,9 +309,13 @@ struct case_strategy_bool {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
into.push_back(instruction_ptr(new instruction_if(
|
instruction_ijump* ijump = new instruction_ijump();
|
||||||
std::move(ms.get_case_for(true)),
|
instruction_ptr inst(ijump);
|
||||||
std::move(ms.get_case_for(false)))));
|
ijump->branches.push_back(std::move(ms.get_case_for(false)));
|
||||||
|
ijump->tag_mappings[0] = 0;
|
||||||
|
ijump->branches.push_back(std::move(ms.get_case_for(true)));
|
||||||
|
ijump->tag_mappings[1] = 1;
|
||||||
|
into.push_back(std::move(inst));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ void instruction_jump::print(int indent, std::ostream& to) const {
|
||||||
|
|
||||||
void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const {
|
void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const {
|
||||||
auto top_node = ctx.create_peek(f, ctx.create_size(0));
|
auto top_node = ctx.create_peek(f, ctx.create_size(0));
|
||||||
auto tag = ctx.unwrap_data_tag(top_node);
|
auto tag = get_case_value(ctx, top_node);
|
||||||
auto safety_block = ctx.create_basic_block("safety", f);
|
auto safety_block = ctx.create_basic_block("safety", f);
|
||||||
auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size());
|
auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size());
|
||||||
std::vector<BasicBlock*> blocks;
|
std::vector<BasicBlock*> blocks;
|
||||||
|
@ -122,43 +122,12 @@ void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const {
|
||||||
ctx.get_builder().SetInsertPoint(safety_block);
|
ctx.get_builder().SetInsertPoint(safety_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_if::print(int indent, std::ostream& to) const {
|
Value* instruction_jump::get_case_value(llvm_context& ctx, Value* v) const {
|
||||||
print_indent(indent, to);
|
return ctx.unwrap_data_tag(v);
|
||||||
to << "If(" << std::endl;
|
|
||||||
for(auto& instruction : on_true) {
|
|
||||||
instruction->print(indent + 2, to);
|
|
||||||
}
|
|
||||||
to << std::endl;
|
|
||||||
for(auto& instruction : on_false) {
|
|
||||||
instruction->print(indent + 2, to);
|
|
||||||
}
|
|
||||||
print_indent(indent, to);
|
|
||||||
to << ")" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_if::gen_llvm(llvm_context& ctx, llvm::Function* f) const {
|
Value* instruction_ijump::get_case_value(llvm_context& ctx, Value* v) const {
|
||||||
auto top_node = ctx.create_peek(f, ctx.create_size(0));
|
return ctx.unwrap_num(v);
|
||||||
auto num = ctx.unwrap_num(top_node);
|
|
||||||
|
|
||||||
auto nonzero_block = ctx.create_basic_block("nonzero", f);
|
|
||||||
auto zero_block = ctx.create_basic_block("zero", f);
|
|
||||||
auto resume_block = ctx.create_basic_block("resume", f);
|
|
||||||
auto switch_op = ctx.get_builder().CreateSwitch(num, nonzero_block, 2);
|
|
||||||
|
|
||||||
switch_op->addCase(ctx.create_i32(0), zero_block);
|
|
||||||
ctx.get_builder().SetInsertPoint(nonzero_block);
|
|
||||||
for(auto& instruction : on_true) {
|
|
||||||
instruction->gen_llvm(ctx, f);
|
|
||||||
}
|
|
||||||
ctx.get_builder().CreateBr(resume_block);
|
|
||||||
|
|
||||||
ctx.get_builder().SetInsertPoint(zero_block);
|
|
||||||
for(auto& instruction : on_false) {
|
|
||||||
instruction->gen_llvm(ctx, f);
|
|
||||||
}
|
|
||||||
ctx.get_builder().CreateBr(resume_block);
|
|
||||||
|
|
||||||
ctx.get_builder().SetInsertPoint(resume_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_slide::print(int indent, std::ostream& to) const {
|
void instruction_slide::print(int indent, std::ostream& to) const {
|
||||||
|
|
|
@ -99,19 +99,12 @@ struct instruction_jump : public instruction {
|
||||||
|
|
||||||
void print(int indent, std::ostream& to) const;
|
void print(int indent, std::ostream& to) const;
|
||||||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
||||||
|
|
||||||
|
virtual llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct instruction_if : public instruction {
|
struct instruction_ijump : public instruction_jump {
|
||||||
std::vector<instruction_ptr> on_true;
|
llvm::Value* get_case_value(llvm_context& ctx, llvm::Value*) const;
|
||||||
std::vector<instruction_ptr> on_false;
|
|
||||||
|
|
||||||
instruction_if(
|
|
||||||
std::vector<instruction_ptr> t,
|
|
||||||
std::vector<instruction_ptr> f)
|
|
||||||
: on_true(std::move(t)), on_false(std::move(f)) {}
|
|
||||||
|
|
||||||
void print(int indent, std::ostream& to) const;
|
|
||||||
void gen_llvm(llvm_context& ctx, llvm::Function* f) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct instruction_slide : public instruction {
|
struct instruction_slide : public instruction {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user