don't just store a 'bool constant' in the ast/ir, store the complete qualifier: 'int cvq', moved CV_ defines into gmqcc.h

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-30 13:47:28 +01:00
parent 8e043c8447
commit 5e23e8296d
6 changed files with 47 additions and 43 deletions

2
ast.c
View file

@ -322,7 +322,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
self->name = name ? util_strdup(name) : NULL;
self->expression.vtype = t;
self->expression.next = NULL;
self->constant = false;
self->cvq = CV_NONE;
self->hasvalue = false;
self->uses = 0;
memset(&self->constval, 0, sizeof(self->constval));

2
ast.h
View file

@ -159,7 +159,7 @@ struct ast_value_s
ast_value *next;
*/
bool constant;
bool cvq; /* const/var qualifier */
bool hasvalue;
union {
double vfloat;

View file

@ -328,6 +328,11 @@ enum {
TYPE_COUNT
};
/* const/var qualifiers */
#define CV_NONE 0
#define CV_CONST 1
#define CV_VAR -1
extern const char *type_name[TYPE_COUNT];
extern size_t type_sizeof[TYPE_COUNT];

37
ir.c
View file

@ -361,7 +361,7 @@ ir_function* ir_builder_create_function(ir_builder *self, const char *name, int
return NULL;
}
fn->value->isconst = true;
fn->value->hasvalue = true;
fn->value->outtype = outtype;
fn->value->constval.vfunc = fn;
fn->value->context = fn->context;
@ -841,7 +841,8 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
self->reads = NULL;
self->writes = NULL;
self->isconst = false;
self->cvq = CV_NONE;
self->hasvalue = false;
self->context.file = "<@no context>";
self->context.line = 0;
self->name = NULL;
@ -919,7 +920,7 @@ void ir_value_delete(ir_value* self)
size_t i;
if (self->name)
mem_d((void*)self->name);
if (self->isconst)
if (self->hasvalue)
{
if (self->vtype == TYPE_STRING)
mem_d((void*)self->constval.vstring);
@ -947,7 +948,7 @@ bool ir_value_set_float(ir_value *self, float f)
if (self->vtype != TYPE_FLOAT)
return false;
self->constval.vfloat = f;
self->isconst = true;
self->hasvalue = true;
return true;
}
@ -956,7 +957,7 @@ bool ir_value_set_func(ir_value *self, int f)
if (self->vtype != TYPE_FUNCTION)
return false;
self->constval.vint = f;
self->isconst = true;
self->hasvalue = true;
return true;
}
@ -965,7 +966,7 @@ bool ir_value_set_vector(ir_value *self, vector v)
if (self->vtype != TYPE_VECTOR)
return false;
self->constval.vvec = v;
self->isconst = true;
self->hasvalue = true;
return true;
}
@ -974,7 +975,7 @@ bool ir_value_set_field(ir_value *self, ir_value *fld)
if (self->vtype != TYPE_FIELD)
return false;
self->constval.vpointer = fld;
self->isconst = true;
self->hasvalue = true;
return true;
}
@ -994,7 +995,7 @@ bool ir_value_set_string(ir_value *self, const char *str)
if (self->vtype != TYPE_STRING)
return false;
self->constval.vstring = ir_strdup(str);
self->isconst = true;
self->hasvalue = true;
return true;
}
@ -1004,7 +1005,7 @@ bool ir_value_set_int(ir_value *self, int i)
if (self->vtype != TYPE_INTEGER)
return false;
self->constval.vint = i;
self->isconst = true;
self->hasvalue = true;
return true;
}
#endif
@ -2440,7 +2441,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
static bool gen_global_field(ir_value *global)
{
if (global->isconst)
if (global->hasvalue)
{
ir_value *fld = global->constval.vpointer;
if (!fld) {
@ -2485,7 +2486,7 @@ static bool gen_global_field(ir_value *global)
static bool gen_global_pointer(ir_value *global)
{
if (global->isconst)
if (global->hasvalue)
{
ir_value *target = global->constval.vpointer;
if (!target) {
@ -2825,7 +2826,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
size_t i;
size_t local_var_end;
if (!global->isconst || (!global->constval.vfunc))
if (!global->hasvalue || (!global->constval.vfunc))
{
irerror(global->context, "Invalid state of function-global: not constant: %s", global->name);
return false;
@ -3035,7 +3036,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
case TYPE_FLOAT:
{
ir_value_code_setaddr(global, vec_size(code_globals));
if (global->isconst) {
if (global->hasvalue) {
iptr = (int32_t*)&global->constval.ivec[0];
vec_push(code_globals, *iptr);
} else {
@ -3050,7 +3051,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
case TYPE_STRING:
{
ir_value_code_setaddr(global, vec_size(code_globals));
if (global->isconst) {
if (global->hasvalue) {
vec_push(code_globals, code_genstring(global->constval.vstring));
} else {
vec_push(code_globals, 0);
@ -3064,7 +3065,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
{
size_t d;
ir_value_code_setaddr(global, vec_size(code_globals));
if (global->isconst) {
if (global->hasvalue) {
iptr = (int32_t*)&global->constval.ivec[0];
vec_push(code_globals, iptr[0]);
if (global->code.globaladdr < 0)
@ -3090,7 +3091,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
}
case TYPE_FUNCTION:
ir_value_code_setaddr(global, vec_size(code_globals));
if (!global->isconst) {
if (!global->hasvalue) {
vec_push(code_globals, 0);
if (global->code.globaladdr < 0)
return false;
@ -3268,7 +3269,7 @@ void ir_builder_dump(ir_builder *b, int (*oprintf)(const char*, ...))
for (i = 0; i < vec_size(b->globals); ++i)
{
oprintf("global ");
if (b->globals[i]->isconst)
if (b->globals[i]->hasvalue)
oprintf("%s = ", b->globals[i]->name);
ir_value_dump(b->globals[i], oprintf);
oprintf("\n");
@ -3435,7 +3436,7 @@ void ir_value_dump_string(const char *str, int (*oprintf)(const char*, ...))
void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...))
{
if (v->isconst) {
if (v->hasvalue) {
switch (v->vtype) {
default:
case TYPE_VOID:

4
ir.h
View file

@ -42,12 +42,14 @@ typedef struct ir_value_s {
int fieldtype;
/* and the output type of a function */
int outtype;
/* 'const' vs 'var' qualifier */
int cvq;
struct ir_instr_s **reads;
struct ir_instr_s **writes;
/* constantvalues */
bool isconst;
bool hasvalue;
union {
float vfloat;
int vint;

View file

@ -88,10 +88,6 @@ typedef struct {
qcint memberof;
} parser_t;
#define CV_NONE 0
#define CV_CONST 1
#define CV_VAR -1
static void parser_enterblock(parser_t *parser);
static bool parser_leaveblock(parser_t *parser);
static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
@ -221,7 +217,7 @@ static ast_value* parser_const_float(parser_t *parser, double d)
return parser->imm_float[i];
}
out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
out->constant = true;
out->cvq = CV_CONST;
out->hasvalue = true;
out->constval.vfloat = d;
vec_push(parser->imm_float, out);
@ -267,7 +263,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
} else
out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
out->constant = true;
out->cvq = CV_CONST;
out->hasvalue = true;
out->constval.vstring = parser_strdup(str);
vec_push(parser->imm_string, out);
@ -283,7 +279,7 @@ static ast_value* parser_const_vector(parser_t *parser, vector v)
return parser->imm_vector[i];
}
out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
out->constant = true;
out->cvq = CV_CONST;
out->hasvalue = true;
out->constval.vvec = v;
vec_push(parser->imm_vector, out);
@ -531,7 +527,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
(exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
exprs[0]->expression.vtype != T)
#define CanConstFold1(A) \
(ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && ((ast_value*)(A))->constant)
(ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && (((ast_value*)(A))->cvq == CV_CONST))
#define CanConstFold(A, B) \
(CanConstFold1(A) && CanConstFold1(B))
#define ConstV(i) (asvalue[(i)]->constval.vvec)
@ -954,7 +950,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
}
}
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
@ -971,7 +967,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
addop = INSTR_ADD_F;
else
addop = INSTR_SUB_F;
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
if (ast_istype(exprs[0], ast_entfield)) {
@ -999,7 +995,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
addop = INSTR_SUB_F;
subop = INSTR_ADD_F;
}
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
if (ast_istype(exprs[0], ast_entfield)) {
@ -1028,7 +1024,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
ty1, ty2);
return false;
}
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
if (ast_istype(exprs[0], ast_entfield))
@ -1065,7 +1061,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
ty1, ty2);
return false;
}
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
if (ast_istype(exprs[0], ast_entfield))
@ -1109,7 +1105,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
ty1, ty2);
return false;
}
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
if (ast_istype(exprs[0], ast_entfield))
@ -1139,7 +1135,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
if (!out)
return false;
if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
}
asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
@ -2166,7 +2162,7 @@ static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **ou
}
if (!OPTS_FLAG(RELAXED_SWITCH)) {
opval = (ast_value*)swcase.value;
if (!ast_istype(swcase.value, ast_value)) { /* || !opval->constant) { */
if (!ast_istype(swcase.value, ast_value)) { /* || opval->cvq != CV_CONST) { */
parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
ast_unref(operand);
return false;
@ -3630,7 +3626,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
}
if (is_const_var == CV_CONST)
var->constant = true;
var->cvq = CV_CONST;
/* Part 1:
* check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
@ -3997,7 +3993,7 @@ skipvar:
if (!localblock) {
cval = (ast_value*)cexp;
if (!ast_istype(cval, ast_value) || !cval->hasvalue || !cval->constant)
if (!ast_istype(cval, ast_value) || !cval->hasvalue || cval->cvq != CV_CONST)
parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
else
{
@ -4005,7 +4001,7 @@ skipvar:
!OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
is_const_var != CV_VAR)
{
var->constant = true;
var->cvq = CV_CONST;
}
var->hasvalue = true;
if (cval->expression.vtype == TYPE_STRING)
@ -4017,8 +4013,8 @@ skipvar:
} else {
bool cvq;
shunt sy = { NULL, NULL };
cvq = var->constant;
var->constant = false;
cvq = var->cvq;
var->cvq = CV_NONE;
vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
@ -4031,7 +4027,7 @@ skipvar:
}
vec_free(sy.out);
vec_free(sy.ops);
var->constant = cvq;
var->cvq = cvq;
}
}