more c++ migration for ast/ir/code; reached a working condition here

This commit is contained in:
Wolfgang Bumiller 2015-01-20 20:25:56 +01:00
parent f09c6a5d63
commit 566e761546
10 changed files with 252 additions and 189 deletions

18
algo.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef GMQCC_ALGO_HDR
#define GMQCC_ALGO_HDR
namespace algo {
template<typename ITER>
void shiftback(ITER element, ITER end) {
//typename ITER::value_type backup(move(*element)); // hold the element
typename std::remove_reference<decltype(*element)>::type backup(move(*element)); // hold the element
ITER p = element++;
for (; element != end; p = element++)
*p = move(*element);
*p = move(backup);
}
} // ::algo
#endif

42
ast.cpp
View file

@ -8,6 +8,8 @@
#include "fold.h"
//#include "parser.h"
#include "algo.h"
#define ast_instantiate(T, ctx, destroyfn) \
T* self = (T*)mem_a(sizeof(T)); \
if (!self) { \
@ -387,6 +389,7 @@ void ast_value_delete(ast_value* self)
}
ast_expression_delete((ast_expression*)self);
self->~ast_value();
mem_d(self);
}
@ -1211,8 +1214,9 @@ void ast_function_delete(ast_function *self)
}
for (auto &it : self->static_names)
mem_d(it);
for (auto &it : self->blocks)
ast_delete(it);
// FIXME::DELME:: unique_ptr used on ast_block
//for (auto &it : self->blocks)
// ast_delete(it);
if (self->varargs)
ast_delete(self->varargs);
if (self->argc)
@ -1844,7 +1848,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
for (auto &it : self->blocks) {
cgen = it->codegen;
if (!(*cgen)((ast_expression*)it, self, false, &dummy))
if (!(*cgen)(it.get(), self, false, &dummy))
return false;
}
@ -2105,8 +2109,12 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
return false;
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id);
func->ir_func->blocks.emplace_back(merge);
algo::shiftback(func->ir_func->blocks.begin() + merge_id,
func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[merge_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id);
//func->ir_func->blocks.emplace_back(merge);
func->curblock = merge;
phi = ir_block_create_phi(func->curblock, ast_ctx(self),
@ -3011,8 +3019,12 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
}
/* Move 'bout' to the end */
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
func->ir_func->blocks.emplace_back(bout);
algo::shiftback(func->ir_func->blocks.begin() + bout_id,
func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bout_id].release(); // it's a vector<unique_ptr<>>
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
//func->ir_func->blocks.emplace_back(bout);
return true;
}
@ -3151,8 +3163,12 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
/* enter the else and move it down */
func->curblock = bnot;
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id);
func->ir_func->blocks.emplace_back(bnot);
algo::shiftback(func->ir_func->blocks.begin() + bnot_id,
func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bnot_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id);
//func->ir_func->blocks.emplace_back(bnot);
} else {
/* The default case */
/* Remember where to fall through from: */
@ -3209,8 +3225,12 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
func->breakblocks.pop_back();
/* Move 'bout' to the end, it's nicer */
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
func->ir_func->blocks.emplace_back(bout);
algo::shiftback(func->ir_func->blocks.begin() + bout_id,
func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bout_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
//func->ir_func->blocks.emplace_back(bout);
return true;
}

2
ast.h
View file

@ -626,7 +626,7 @@ struct ast_function
* here to use in ast_function_label.
*/
char labelbuf[64];
std::vector<ast_block*> blocks;
std::vector<std::unique_ptr<ast_block>> blocks;
ast_value *varargs;
ast_value *argc;
ast_value *fixedparams;

View file

@ -106,35 +106,39 @@ void code_pop_statement(code_t *code)
code->columnnums.pop_back();
}
code_t *code_init() {
void *code_t::operator new(std::size_t bytes) {
return mem_a(bytes);
}
void code_t::operator delete(void *ptr) {
mem_d(ptr);
}
code_t::code_t()
{
static lex_ctx_t empty_ctx = {0, 0, 0};
static prog_section_function_t empty_function = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}};
static prog_section_statement_t empty_statement = {0,{0},{0},{0}};
static prog_section_def_t empty_def = {0, 0, 0};
code_t *code = (code_t*)mem_a(sizeof(code_t));
int i = 0;
string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);
memset(code, 0, sizeof(code_t));
code->entfields = 0;
code->string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);
// The way progs.dat is suppose to work is odd, there needs to be
// some null (empty) statements, functions, and 28 globals
globals.insert(globals.begin(), 28, 0);
/*
* The way progs.dat is suppose to work is odd, there needs to be
* some null (empty) statements, functions, and 28 globals
*/
for(; i < 28; i++)
code->globals.push_back(0);
chars.push_back('\0');
functions.push_back(empty_function);
code->chars.push_back('\0');
code->functions.push_back(empty_function);
code_push_statement(this, &empty_statement, empty_ctx);
code_push_statement(code, &empty_statement, empty_ctx);
defs.push_back(empty_def);
fields.push_back(empty_def);
}
code->defs.push_back(empty_def);
code->fields.push_back(empty_def);
return code;
code_t::~code_t()
{
util_htdel(string_cache);
}
void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin);
@ -342,8 +346,3 @@ bool code_write(code_t *code, const char *filename, const char *lnofile) {
code_stats(filename, lnofile, code, &code_header);
return true;
}
void code_cleanup(code_t *code) {
util_htdel(code->string_cache);
mem_d(code);
}

10
gmqcc.h
View file

@ -502,6 +502,10 @@ typedef int32_t qcint_t;
typedef uint32_t qcuint_t;
struct code_t {
void* operator new(std::size_t);
void operator delete(void*);
code_t();
~code_t();
std::vector<prog_section_statement_t> statements;
std::vector<int> linenums;
std::vector<int> columnnums;
@ -510,10 +514,10 @@ struct code_t {
std::vector<prog_section_function_t> functions;
std::vector<int> globals;
std::vector<char> chars;
uint16_t crc;
uint32_t entfields;
uint16_t crc = 0;
uint32_t entfields = 0;
ht string_cache;
qcint_t string_cached_empty;
qcint_t string_cached_empty = 0;
};
/*

View file

@ -80,7 +80,7 @@ ast_expression *intrin::isfinite_() {
)
);
func->blocks.push_back(block);
func->blocks.emplace_back(block);
reg(val, func);
return (ast_expression*)val;;
@ -125,7 +125,7 @@ ast_expression *intrin::isinf_() {
);
val->type_params.push_back(x);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
@ -170,7 +170,7 @@ ast_expression *intrin::isnan_() {
);
val->type_params.push_back(arg1);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
@ -200,7 +200,7 @@ ast_expression *intrin::isnormal_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -236,7 +236,7 @@ ast_expression *intrin::signbit_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -289,7 +289,7 @@ ast_expression *intrin::acosh_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -342,7 +342,7 @@ ast_expression *intrin::asinh_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -391,7 +391,7 @@ ast_expression *intrin::atanh_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -504,7 +504,7 @@ ast_expression *intrin::exp_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -534,7 +534,7 @@ ast_expression *intrin::exp2_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -569,7 +569,7 @@ ast_expression *intrin::expm1_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1014,7 +1014,7 @@ ast_expression *intrin::pow_() {
);
/* } */
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1110,7 +1110,7 @@ ast_expression *intrin::mod_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1149,7 +1149,7 @@ ast_expression *intrin::fabs_() {
val->type_params.push_back(arg1);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1221,7 +1221,7 @@ ast_expression *intrin::epsilon_() {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1261,7 +1261,7 @@ ast_expression *intrin::nan_() {
)
);
func->blocks.push_back(block);
func->blocks.emplace_back(block);
reg(val, func);
return (ast_expression*)val;
}
@ -1308,7 +1308,7 @@ ast_expression *intrin::inf_() {
)
);
func->blocks.push_back(block);
func->blocks.emplace_back(block);
reg(val, func);
return (ast_expression*)val;
}
@ -1852,7 +1852,7 @@ ast_expression *intrin::ln_() {
)
);
func->blocks.push_back(block);
func->blocks.emplace_back(block);
reg(val, func);
return (ast_expression*)val;
}
@ -1876,7 +1876,7 @@ ast_expression *intrin::log_variant(const char *name, float base) {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}
@ -1933,7 +1933,7 @@ ast_expression *intrin::shift_variant(const char *name, size_t instr) {
)
);
func->blocks.push_back(body);
func->blocks.emplace_back(body);
reg(val, func);
return (ast_expression*)val;
}

226
ir.cpp
View file

@ -203,7 +203,6 @@ static bool GMQCC_WARN ir_block_create_store(ir_block*, lex_ctx_t, ir_value *tar
static void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...));
static bool ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
static void ir_instr_delete(ir_instr*);
static void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
/* error functions */
@ -285,7 +284,8 @@ void ir_builder::operator delete(void *ptr)
}
ir_builder::ir_builder(const std::string& modulename)
: name(modulename)
: name(modulename),
code(new code_t)
{
htglobals = util_htnew(IR_HT_SIZE);
htfields = util_htnew(IR_HT_SIZE);
@ -302,8 +302,6 @@ ir_builder::ir_builder(const std::string& modulename)
vinstr_temp[i] = new ir_value("vinstr_temp", store_value, TYPE_NOEXPR);
vinstr_temp[i]->cvq = CV_CONST;
}
code = code_init();
}
ir_builder::~ir_builder()
@ -321,7 +319,8 @@ ir_builder::~ir_builder()
delete vinstr_temp[i];
}
code_cleanup(code);
extparams.clear();
extparam_protos.clear();
}
static ir_function* ir_builder_get_function(ir_builder *self, const char *name)
@ -527,7 +526,7 @@ static bool ir_function_pass_peephole(ir_function *self)
(void)!ir_instr_op(oper, 0, store->_ops[0], true);
vec_remove(block->instr, i, 1);
ir_instr_delete(store);
delete store;
}
else if (inst->opcode == VINSTR_COND)
{
@ -569,7 +568,7 @@ static bool ir_function_pass_peephole(ir_function *self)
return false;
}
vec_remove(tmp->instr, inotid, 1);
ir_instr_delete(inot);
delete inot;
/* swap ontrue/onfalse */
tmp = inst->bops[0];
inst->bops[0] = inst->bops[1];
@ -627,7 +626,7 @@ static bool ir_function_pass_tailrecursion(ir_function *self)
++opts_optimizationcount[OPTIM_PEEPHOLE];
call->_ops[0] = store->_ops[0];
vec_remove(block->instr, vec_size(block->instr) - 2, 1);
ir_instr_delete(store);
delete store;
}
else
continue;
@ -664,8 +663,8 @@ static bool ir_function_pass_tailrecursion(ir_function *self)
return false;
}
ir_instr_delete(call);
ir_instr_delete(ret);
delete call;
delete ret;
}
return true;
@ -767,7 +766,7 @@ ir_block::ir_block(ir_function* owner, const std::string& name)
ir_block::~ir_block()
{
for (size_t i = 0; i != vec_size(instr); ++i)
ir_instr_delete(instr[i]);
delete instr[i];
vec_free(instr);
vec_free(entries);
vec_free(exits);
@ -786,55 +785,54 @@ static void ir_block_delete_quick(ir_block* self)
*IR Instructions
*/
static ir_instr* ir_instr_new(lex_ctx_t ctx, ir_block* owner, int op)
void* ir_instr::operator new(std::size_t bytes) {
return mem_a(bytes);
}
void ir_instr::operator delete(void *data) {
mem_d(data);
}
ir_instr::ir_instr(lex_ctx_t ctx, ir_block* owner_, int op)
: opcode(op),
context(ctx),
owner(owner_)
{
ir_instr *self = new ir_instr;
self->owner = owner;
self->context = ctx;
self->opcode = op;
self->_ops[0] = nullptr;
self->_ops[1] = nullptr;
self->_ops[2] = nullptr;
self->bops[0] = nullptr;
self->bops[1] = nullptr;
self->eid = 0;
self->likely = true;
return self;
}
ir_instr::~ir_instr()
{
// The following calls can only delete from
// vectors, we still want to delete this instruction
// so ignore the return value. Since with the warn_unused_result attribute
// gcc doesn't care about an explicit: (void)foo(); to ignore the result,
// I have to improvise here and use if(foo());
for (auto &it : phi) {
size_t idx;
if (vec_ir_instr_find(it.value->writes, this, &idx))
it.value->writes.erase(it.value->writes.begin() + idx);
if (vec_ir_instr_find(it.value->reads, this, &idx))
it.value->reads.erase(it.value->reads.begin() + idx);
}
for (auto &it : params) {
size_t idx;
if (vec_ir_instr_find(it->writes, this, &idx))
it->writes.erase(it->writes.begin() + idx);
if (vec_ir_instr_find(it->reads, this, &idx))
it->reads.erase(it->reads.begin() + idx);
}
(void)!ir_instr_op(this, 0, nullptr, false);
(void)!ir_instr_op(this, 1, nullptr, false);
(void)!ir_instr_op(this, 2, nullptr, false);
}
static void ir_instr_delete_quick(ir_instr *self)
{
self->phi.clear();
self->params.clear();
delete self;
}
static void ir_instr_delete(ir_instr *self)
{
/* The following calls can only delete from
* vectors, we still want to delete this instruction
* so ignore the return value. Since with the warn_unused_result attribute
* gcc doesn't care about an explicit: (void)foo(); to ignore the result,
* I have to improvise here and use if(foo());
*/
for (auto &it : self->phi) {
size_t idx;
if (vec_ir_instr_find(it.value->writes, self, &idx))
it.value->writes.erase(it.value->writes.begin() + idx);
if (vec_ir_instr_find(it.value->reads, self, &idx))
it.value->reads.erase(it.value->reads.begin() + idx);
}
for (auto &it : self->params) {
size_t idx;
if (vec_ir_instr_find(it->writes, self, &idx))
it->writes.erase(it->writes.begin() + idx);
if (vec_ir_instr_find(it->reads, self, &idx))
it->reads.erase(it->reads.begin() + idx);
}
(void)!ir_instr_op(self, 0, nullptr, false);
(void)!ir_instr_op(self, 1, nullptr, false);
(void)!ir_instr_op(self, 2, nullptr, false);
mem_d(self);
}
static bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
{
if (v && v->vtype == TYPE_NOEXPR) {
@ -1119,7 +1117,7 @@ static bool ir_value_life_merge(ir_value *self, size_t s)
{
/* merge */
before->end = life_found->end;
self->life.erase(self->life.begin()+1);
self->life.erase(self->life.begin()+i);
return true;
}
if (before->end + 1 == s)
@ -1297,14 +1295,14 @@ bool ir_block_create_store_op(ir_block *self, lex_ctx_t ctx, int op, ir_value *t
return false;
}
in = ir_instr_new(ctx, self, op);
in = new ir_instr(ctx, self, op);
if (!in)
return false;
if (!ir_instr_op(in, 0, target, (op < INSTR_STOREP_F || op > INSTR_STOREP_FNC)) ||
!ir_instr_op(in, 1, what, false))
{
ir_instr_delete(in);
delete in;
return false;
}
vec_push(self->instr, in);
@ -1317,14 +1315,14 @@ bool ir_block_create_state_op(ir_block *self, lex_ctx_t ctx, ir_value *frame, ir
if (!ir_check_unreachable(self))
return false;
in = ir_instr_new(ctx, self, INSTR_STATE);
in = new ir_instr(ctx, self, INSTR_STATE);
if (!in)
return false;
if (!ir_instr_op(in, 0, frame, false) ||
!ir_instr_op(in, 1, think, false))
{
ir_instr_delete(in);
delete in;
return false;
}
vec_push(self->instr, in);
@ -1387,12 +1385,12 @@ bool ir_block_create_return(ir_block *self, lex_ctx_t ctx, ir_value *v)
self->final = true;
self->is_return = true;
in = ir_instr_new(ctx, self, INSTR_RETURN);
in = new ir_instr(ctx, self, INSTR_RETURN);
if (!in)
return false;
if (v && !ir_instr_op(in, 0, v, false)) {
ir_instr_delete(in);
delete in;
return false;
}
@ -1407,13 +1405,13 @@ bool ir_block_create_if(ir_block *self, lex_ctx_t ctx, ir_value *v,
if (!ir_check_unreachable(self))
return false;
self->final = true;
/*in = ir_instr_new(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/
in = ir_instr_new(ctx, self, VINSTR_COND);
/*in = new ir_instr(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/
in = new ir_instr(ctx, self, VINSTR_COND);
if (!in)
return false;
if (!ir_instr_op(in, 0, v, false)) {
ir_instr_delete(in);
delete in;
return false;
}
@ -1435,7 +1433,7 @@ bool ir_block_create_jump(ir_block *self, lex_ctx_t ctx, ir_block *to)
if (!ir_check_unreachable(self))
return false;
self->final = true;
in = ir_instr_new(ctx, self, VINSTR_JUMP);
in = new ir_instr(ctx, self, VINSTR_JUMP);
if (!in)
return false;
@ -1459,16 +1457,16 @@ ir_instr* ir_block_create_phi(ir_block *self, lex_ctx_t ctx, const char *label,
ir_instr *in;
if (!ir_check_unreachable(self))
return nullptr;
in = ir_instr_new(ctx, self, VINSTR_PHI);
in = new ir_instr(ctx, self, VINSTR_PHI);
if (!in)
return nullptr;
out = ir_value_out(self->owner, label, store_value, ot);
if (!out) {
ir_instr_delete(in);
delete in;
return nullptr;
}
if (!ir_instr_op(in, 0, out, true)) {
ir_instr_delete(in);
delete in;
return nullptr;
}
vec_push(self->instr, in);
@ -1485,9 +1483,8 @@ void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
ir_phi_entry_t pe;
if (!vec_ir_block_find(self->owner->entries, b, nullptr)) {
/* Must not be possible to cause this, otherwise the AST
* is doing something wrong.
*/
// Must not be possible to cause this, otherwise the AST
// is doing something wrong.
irerror(self->context, "Invalid entry block for PHI");
exit(EXIT_FAILURE);
}
@ -1505,7 +1502,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
ir_instr *in;
if (!ir_check_unreachable(self))
return nullptr;
in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
in = new ir_instr(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
if (!in)
return nullptr;
if (noreturn) {
@ -1514,13 +1511,13 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
}
out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
if (!out) {
ir_instr_delete(in);
delete in;
return nullptr;
}
if (!ir_instr_op(in, 0, out, true) ||
!ir_instr_op(in, 1, func, false))
{
ir_instr_delete(in);
delete in;
return nullptr;
}
vec_push(self->instr, in);
@ -1528,7 +1525,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
if (noreturn) {
if (!ir_block_create_return(self, ctx, nullptr)) {
compile_error(ctx, "internal error: failed to generate dummy-return instruction");
ir_instr_delete(in);
delete in;
return nullptr;
}
}
@ -1715,7 +1712,7 @@ static ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx_t ctx, co
if (!out)
return nullptr;
instr = ir_instr_new(ctx, self, op);
instr = new ir_instr(ctx, self, op);
if (!instr) {
return nullptr;
}
@ -1731,7 +1728,7 @@ static ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx_t ctx, co
return out;
on_error:
ir_instr_delete(instr);
delete instr;
return nullptr;
}
@ -1830,7 +1827,7 @@ static bool ir_block_naive_phi(ir_block *self)
b->final = true;
}
}
ir_instr_delete(instr);
delete instr;
}
return true;
}
@ -2190,12 +2187,8 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
ir_instr *instr;
ir_value *value;
size_t i, o, p, mem;
/* bitmasks which operands are read from or written to */
// bitmasks which operands are read from or written to
size_t read, write;
char dbg_ind[16];
dbg_ind[0] = '#';
dbg_ind[1] = '0';
(void)dbg_ind;
self->living.clear();
@ -2397,21 +2390,17 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
bool ir_function_calculate_liferanges(ir_function *self)
{
size_t i, s;
bool changed;
/* parameters live at 0 */
for (i = 0; i < vec_size(self->params); ++i)
for (size_t i = 0; i < vec_size(self->params); ++i)
if (!ir_value_life_merge(self->locals[i].get(), 0))
compile_error(self->context, "internal error: failed value-life merging");
bool changed;
do {
self->run_id++;
changed = false;
i = self->blocks.size();
while (i--) {
ir_block_life_propagate(self->blocks[i].get(), &changed);
}
for (auto i = self->blocks.rbegin(); i != self->blocks.rend(); ++i)
ir_block_life_propagate(i->get(), &changed);
} while (changed);
if (self->blocks.size()) {
@ -2424,7 +2413,8 @@ bool ir_function_calculate_liferanges(ir_function *self)
continue;
self->flags |= IR_FLAG_HAS_UNINITIALIZED;
/* find the instruction reading from it */
for (s = 0; s < v->reads.size(); ++s) {
size_t s = 0;
for (; s < v->reads.size(); ++s) {
if (v->reads[s]->eid == v->life[0].end)
break;
}
@ -2902,7 +2892,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
if (p-8 >= ir->extparams.size())
ir_gen_extparam(ir);
targetparam = ir->extparams[p-8].get();
targetparam = ir->extparams[p-8];
stmt.opcode = INSTR_STORE_F;
stmt.o3.u1 = 0;
@ -3069,7 +3059,7 @@ static qcint_t ir_builder_filestring(ir_builder *ir, const char *filename)
return i;
}
str = code_genstring(ir->code, filename);
str = code_genstring(ir->code.get(), filename);
ir->filenames.push_back(filename);
ir->filestrings.push_back(str);
return str;
@ -3137,7 +3127,7 @@ static void ir_gen_extparam(ir_builder *ir)
else
global = ir->extparam_protos[ir->extparams.size()].get();
def.name = code_genstring(ir->code, global->name.c_str());
def.name = code_genstring(ir->code.get(), global->name.c_str());
def.type = TYPE_VECTOR;
def.offset = ir->code->globals.size();
@ -3168,7 +3158,7 @@ static bool gen_function_extparam_copy(code_t *code, ir_function *self)
if (ext >= ir->extparams.size())
ir_gen_extparam(ir);
ir_value *ep = ir->extparams[ext].get();
ir_value *ep = ir->extparams[ext];
stmt.opcode = type_store_instr[self->locals[i]->vtype];
if (self->locals[i]->vtype == TYPE_FIELD &&
@ -3210,7 +3200,7 @@ static bool gen_function_varargs_copy(code_t *code, ir_function *self)
while (ext >= ir->extparams.size())
ir_gen_extparam(ir);
ep = ir->extparams[ext].get();
ep = ir->extparams[ext];
stmt.o1.u1 = ir_value_code_addr(ep);
stmt.o2.u1 = ir_value_code_addr(self->locals[i].get());
@ -3315,15 +3305,15 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global)
irerror(irfun->context, "Failed to generate locals for function %s", irfun->name.c_str());
return false;
}
if (!gen_function_extparam_copy(ir->code, irfun)) {
if (!gen_function_extparam_copy(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate extparam-copy code for function %s", irfun->name.c_str());
return false;
}
if (irfun->max_varargs && !gen_function_varargs_copy(ir->code, irfun)) {
if (irfun->max_varargs && !gen_function_varargs_copy(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate vararg-copy code for function %s", irfun->name.c_str());
return false;
}
if (!gen_function_code(ir->code, irfun)) {
if (!gen_function_code(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate code for function %s", irfun->name.c_str());
return false;
}
@ -3426,11 +3416,11 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
if (pushdef) {
if (global->name[0] == '#') {
if (!self->str_immediate)
self->str_immediate = code_genstring(self->code, "IMMEDIATE");
self->str_immediate = code_genstring(self->code.get(), "IMMEDIATE");
def.name = global->code.name = self->str_immediate;
}
else
def.name = global->code.name = code_genstring(self->code, global->name.c_str());
def.name = global->code.name = code_genstring(self->code.get(), global->name.c_str());
}
else
def.name = 0;
@ -3438,9 +3428,9 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
def.offset = ir_value_code_addr(global);
self->code->defs.push_back(def);
if (global->vtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str());
gen_vector_defs(self->code.get(), def, global->name.c_str());
else if (global->vtype == TYPE_FIELD && global->fieldtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str());
gen_vector_defs(self->code.get(), def, global->name.c_str());
return true;
}
}
@ -3475,14 +3465,14 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
return true;
case TYPE_POINTER:
if (pushdef) self->code->defs.push_back(def);
return gen_global_pointer(self->code, global);
return gen_global_pointer(self->code.get(), global);
case TYPE_FIELD:
if (pushdef) {
self->code->defs.push_back(def);
if (global->fieldtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str());
gen_vector_defs(self->code.get(), def, global->name.c_str());
}
return gen_global_field(self->code, global);
return gen_global_field(self->code.get(), global);
case TYPE_ENTITY:
/* fall through */
case TYPE_FLOAT:
@ -3504,7 +3494,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
{
ir_value_code_setaddr(global, self->code->globals.size());
if (global->hasvalue) {
uint32_t load = code_genstring(self->code, global->constval.vstring);
uint32_t load = code_genstring(self->code.get(), global->constval.vstring);
self->code->globals.push_back(load);
} else {
self->code->globals.push_back(0);
@ -3540,7 +3530,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
if (pushdef) {
self->code->defs.push_back(def);
def.type &= ~DEF_SAVEGLOBAL;
gen_vector_defs(self->code, def, global->name.c_str());
gen_vector_defs(self->code.get(), def, global->name.c_str());
}
return global->code.globaladdr >= 0;
}
@ -3607,7 +3597,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
memcpy(name+1, field->name.c_str(), len); // no strncpy - we used strlen above
name[len+1] = 0;
def.name = code_genstring(self->code, name);
def.name = code_genstring(self->code.get(), name);
fld.name = def.name + 1; /* we reuse that string table entry */
} else {
/* in plain QC, there cannot be a global with the same name,
@ -3615,7 +3605,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
* FIXME: fteqcc should create a global as well
* check if it actually uses the same name. Probably does
*/
def.name = code_genstring(self->code, field->name.c_str());
def.name = code_genstring(self->code.get(), field->name.c_str());
fld.name = def.name;
}
@ -3642,8 +3632,8 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
}
if (field->fieldtype == TYPE_VECTOR) {
gen_vector_defs (self->code, def, field->name.c_str());
gen_vector_fields(self->code, fld, field->name.c_str());
gen_vector_defs (self->code.get(), def, field->name.c_str());
gen_vector_fields(self->code.get(), fld, field->name.c_str());
}
return field->code.globaladdr >= 0;
@ -3729,8 +3719,12 @@ static void ir_builder_split_vector(ir_builder *self, ir_value *vec) {
}
static void ir_builder_split_vectors(ir_builder *self) {
for (auto& gp : self->globals) {
ir_value *v = gp.get();
// member values may be added to self->globals during this operation, but
// no new vectors will be added, we need to iterate via an index as
// c++ iterators would be invalidated
const size_t count = self->globals.size();
for (size_t i = 0; i != count; ++i) {
ir_value *v = self->globals[i].get();
if (v->vtype != TYPE_VECTOR || !v->name.length() || v->name[0] != '#')
continue;
ir_builder_split_vector(self, v);
@ -3749,7 +3743,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
}
for (auto& fp : self->fields)
ir_builder_prepare_field(self->code, fp.get());
ir_builder_prepare_field(self->code.get(), fp.get());
for (auto& gp : self->globals) {
ir_value *global = gp.get();
@ -3832,7 +3826,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
last.line = self->code->linenums.back();
last.column = self->code->columnnums.back();
code_push_statement(self->code, &stmt, last);
code_push_statement(self->code.get(), &stmt, last);
}
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY))
@ -3856,7 +3850,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
memcpy(vec_add(lnofile, 5), ".lno", 5);
}
if (!code_write(self->code, filename, lnofile)) {
if (!code_write(self->code.get(), filename, lnofile)) {
vec_free(lnofile);
return false;
}

19
ir.h
View file

@ -108,19 +108,25 @@ struct ir_phi_entry_t {
/* instruction */
struct ir_instr {
void* operator new(std::size_t);
void operator delete(void*);
ir_instr(lex_ctx_t, ir_block *owner, int opcode);
~ir_instr();
int opcode;
lex_ctx_t context;
ir_value *(_ops[3]);
ir_block *(bops[2]);
ir_value *(_ops[3]) = { nullptr, nullptr, nullptr };
ir_block *(bops[2]) = { nullptr, nullptr };
std::vector<ir_phi_entry_t> phi;
std::vector<ir_value *> params;
// For the temp-allocation
size_t eid;
size_t eid = 0;
// For IFs
bool likely;
bool likely = true;
ir_block *owner;
};
@ -262,8 +268,9 @@ struct ir_builder {
ht htglobals;
ht htfields;
std::vector<std::unique_ptr<ir_value>> extparams;
// extparams' ir_values reference the ones from extparam_protos
std::vector<std::unique_ptr<ir_value>> extparam_protos;
std::vector<ir_value*> extparams;
// the highest func->allocated_locals
size_t max_locals = 0;
@ -288,7 +295,7 @@ struct ir_builder {
ir_value *vinstr_temp[IR_MAX_VINSTR_TEMPS];
/* code generator */
code_t *code;
std::unique_ptr<code_t> code;
};
ir_function* ir_builder_create_function(ir_builder*, const std::string& name, qc_type outtype);

View file

@ -4088,7 +4088,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
goto enderrfn;
}
func->blocks.push_back(block);
func->blocks.emplace_back(block);
parser->function = old;
if (!parser_leaveblock(parser))
@ -4348,7 +4348,7 @@ static bool parser_create_array_accessor(parser_t *parser, ast_value *array, con
return false;
}
func->blocks.push_back(body);
func->blocks.emplace_back(body);
*out = fval;
parser->accessors.push_back(fval);
@ -4405,7 +4405,7 @@ static bool parser_create_array_setter_impl(parser_t *parser, ast_value *array)
parseerror(parser, "failed to build accessor search tree");
return false;
}
if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0], root)) {
if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0].get(), root)) {
ast_delete(root);
return false;
}
@ -4457,7 +4457,7 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array,
}
array->setter = fval;
return ast_block_add_expr(func->blocks[0], root);
return ast_block_add_expr(func->blocks[0].get(), root);
cleanup:
if (entity) ast_delete(entity);
if (index) ast_delete(index);
@ -4513,7 +4513,7 @@ static bool parser_create_array_getter_impl(parser_t *parser, ast_value *array)
parseerror(parser, "failed to build accessor search tree");
return false;
}
if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0], root)) {
if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0].get(), root)) {
ast_delete(root);
return false;
}
@ -6123,6 +6123,7 @@ static void parser_remove_ast(parser_t *parser)
void parser_cleanup(parser_t *parser)
{
parser_remove_ast(parser);
parser->~parser_t();
mem_d(parser);
}

View file

@ -76,7 +76,7 @@ static FILE **task_popen(const char *command, const char *mode) {
dup2(errhandle[1], 2);
execvp(argv[0], &argv[0]);
exit(EXIT_FAILURE);
exit(95);
} else {
/* fork failed */
goto task_popen_error_3;
@ -98,11 +98,17 @@ static int task_pclose(FILE **handles) {
close(data->pipes[1]); /* stdout */
close(data->pipes[2]); /* stderr */
waitpid(data->pid, &status, 0);
if (data->pid != waitpid(data->pid, &status, 0)) {
abort();
}
if (!WIFEXITED(status))
return -1;
if (WIFSIGNALED(status))
con_out("got signaled!\n");
mem_d(data);
return status;
return status ? 1 : 0;
}
#define TASK_COMPILE 0
@ -997,6 +1003,10 @@ static size_t task_schedualize(size_t *pad) {
util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i));
con_out("test #%u %*s", i, strlen(space[0]) - strlen(space[1]), "");
//con_out("[[%*s]]",
// (pad[0] + pad[1] - strlen(it.tmpl->description)) + (strlen(it.tmpl->rulesfile) - pad[1]),
// it.tmpl->rulesfile);
//fflush(stdout);
/*
* Generate a task from thin air if it requires execution in
@ -1057,6 +1067,16 @@ static size_t task_schedualize(size_t *pad) {
}
status = task_pclose(it.runhandles);
if (status != 0 && status != 1) {
con_out("compiler failure (returned: %i): `%s` %*s\n",
status,
it.tmpl->description,
(pad[0] + pad[1] - strlen(it.tmpl->description)) + (strlen(it.tmpl->rulesfile) - pad[1]),
it.tmpl->rulesfile
);
failed++;
continue;
}
if ((!strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS)
|| ( strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) {
con_out("failure: `%s` %*s %*s\n",