]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
moving -Olocal-temps to -O4 until the issues are solved
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index 37f68f940660818d4632c2b5f9d12e4ea8ab5709..6ac74e868c5a8f0610a08d310d05499a87d4495d 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012
+ * Copyright (C) 2012, 2013
  *     Wolfgang Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
@@ -42,7 +42,10 @@ const char *type_name[TYPE_COUNT] = {
     "variant",
     "struct",
     "union",
-    "array"
+    "array",
+
+    "nil",
+    "<no-expression>"
 };
 
 size_t type_sizeof_[TYPE_COUNT] = {
@@ -59,6 +62,8 @@ size_t type_sizeof_[TYPE_COUNT] = {
     0, /* TYPE_STRUCT   */
     0, /* TYPE_UNION    */
     0, /* TYPE_ARRAY    */
+    0, /* TYPE_NIL      */
+    0, /* TYPE_NOESPR   */
 };
 
 uint16_t type_store_instr[TYPE_COUNT] = {
@@ -81,6 +86,8 @@ uint16_t type_store_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 uint16_t field_store_instr[TYPE_COUNT] = {
@@ -103,6 +110,8 @@ uint16_t field_store_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 uint16_t type_storep_instr[TYPE_COUNT] = {
@@ -125,6 +134,8 @@ uint16_t type_storep_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 uint16_t type_eq_instr[TYPE_COUNT] = {
@@ -147,6 +158,8 @@ uint16_t type_eq_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 uint16_t type_ne_instr[TYPE_COUNT] = {
@@ -169,6 +182,8 @@ uint16_t type_ne_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 uint16_t type_not_instr[TYPE_COUNT] = {
@@ -191,6 +206,8 @@ uint16_t type_not_instr[TYPE_COUNT] = {
     AINSTR_END, /* struct */
     AINSTR_END, /* union  */
     AINSTR_END, /* array  */
+    AINSTR_END, /* nil    */
+    AINSTR_END, /* noexpr */
 };
 
 /* protos */
@@ -300,6 +317,9 @@ ir_builder* ir_builder_new(const char *modulename)
         return NULL;
     }
 
+    self->nil = ir_value_var("nil", store_value, TYPE_NIL);
+    self->nil->cvq = CV_CONST;
+
     return self;
 }
 
@@ -325,6 +345,7 @@ void ir_builder_delete(ir_builder* self)
     for (i = 0; i != vec_size(self->fields); ++i) {
         ir_value_delete(self->fields[i]);
     }
+    ir_value_delete(self->nil);
     vec_free(self->fields);
     vec_free(self->filenames);
     vec_free(self->filestrings);
@@ -759,8 +780,10 @@ bool ir_function_finalize(ir_function *self)
         }
     }
 
-    if (!ir_function_naive_phi(self))
+    if (!ir_function_naive_phi(self)) {
+        irerror(self->context, "internal error: ir_function_naive_phi failed");
         return false;
+    }
 
     for (i = 0; i < vec_size(self->locals); ++i) {
         ir_value *v = self->locals[i];
@@ -2297,6 +2320,9 @@ bool ir_function_allocate_locals(ir_function *self)
             if (vec_size(v->writes) == 1 && v->writes[0]->opcode == INSTR_CALL0)
             {
                 v->store = store_return;
+                if (v->members[0]) v->members[0]->store = store_return;
+                if (v->members[1]) v->members[1]->store = store_return;
+                if (v->members[2]) v->members[2]->store = store_return;
                 ++opts_optimizationcount[OPTIM_CALL_STORES];
                 continue;
             }
@@ -2858,7 +2884,7 @@ tailcall:
             if (onfalse->generated) {
                 /* fixup the jump address */
                 code_statements[stidx].o2.s1 = (onfalse->code_start) - (stidx);
-                if (code_statements[stidx].o2.s1 == 1) {
+                if (stidx+2 == vec_size(code_statements) && code_statements[stidx].o2.s1 == 1) {
                     code_statements[stidx] = code_statements[stidx+1];
                     if (code_statements[stidx].o1.s1 < 0)
                         code_statements[stidx].o1.s1++;
@@ -2883,7 +2909,7 @@ tailcall:
                     code_push_statement(&stmt, instr->context.line);
                 return true;
             }
-            else if (code_statements[stidx].o2.s1 == 1) {
+            else if (stidx+2 == vec_size(code_statements) && code_statements[stidx].o2.s1 == 1) {
                 code_statements[stidx] = code_statements[stidx+1];
                 if (code_statements[stidx].o1.s1 < 0)
                     code_statements[stidx].o1.s1++;
@@ -2914,6 +2940,8 @@ tailcall:
 
                 if (param->vtype == TYPE_FIELD)
                     stmt.opcode = field_store_instr[param->fieldtype];
+                else if (param->vtype == TYPE_NIL)
+                    stmt.opcode = INSTR_STORE_V;
                 else
                     stmt.opcode = type_store_instr[param->vtype];
                 stmt.o1.u1 = ir_value_code_addr(param);
@@ -2941,6 +2969,8 @@ tailcall:
 
                 if (param->vtype == TYPE_FIELD)
                     stmt.opcode = field_store_instr[param->fieldtype];
+                else if (param->vtype == TYPE_NIL)
+                    stmt.opcode = INSTR_STORE_V;
                 else
                     stmt.opcode = type_store_instr[param->vtype];
                 stmt.o1.u1 = ir_value_code_addr(param);
@@ -3621,6 +3651,12 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
         }
     }
 
+    /* generate nil */
+    ir_value_code_setaddr(self->nil, vec_size(code_globals));
+    vec_push(code_globals, 0);
+    vec_push(code_globals, 0);
+    vec_push(code_globals, 0);
+
     /* generate global temps */
     self->first_common_globaltemp = vec_size(code_globals);
     for (i = 0; i < self->max_globaltemps; ++i) {
@@ -3766,7 +3802,7 @@ void ir_function_dump(ir_function *f, char *ind,
             attr = "unique ";
         else if (v->locked)
             attr = "locked ";
-        oprintf("%s\t%s: %s@%i ", ind, v->name, attr, (int)v->code.local);
+        oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
         for (l = 0; l < vec_size(v->life); ++l) {
             oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
         }
@@ -3789,13 +3825,36 @@ void ir_function_dump(ir_function *f, char *ind,
         }
     }
     for (i = 0; i < vec_size(f->values); ++i) {
-        size_t l;
+        const char *attr = "";
+        size_t l, m;
         ir_value *v = f->values[i];
-        oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local);
+        if (v->unique_life && v->locked)
+            attr = "unique,locked ";
+        else if (v->unique_life)
+            attr = "unique ";
+        else if (v->locked)
+            attr = "locked ";
+        oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
         for (l = 0; l < vec_size(v->life); ++l) {
             oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
         }
         oprintf("\n");
+        for (m = 0; m < 3; ++m) {
+            ir_value *vm = v->members[m];
+            if (!vm)
+                continue;
+            if (vm->unique_life && vm->locked)
+                attr = "unique,locked ";
+            else if (vm->unique_life)
+                attr = "unique ";
+            else if (vm->locked)
+                attr = "locked ";
+            oprintf("%s\t%s: %s@%i ", ind, vm->name, attr, (int)vm->code.local);
+            for (l = 0; l < vec_size(vm->life); ++l) {
+                oprintf("[%i,%i] ", vm->life[l].start, vm->life[l].end);
+            }
+            oprintf("\n");
+        }
     }
     if (vec_size(f->blocks))
     {