]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
Faster hashing reaching 16 GB/s on Phenom II X4.
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index 56dc1e5cf3aedac4dd5ca73dd7c858ec27489c14..e10bbed51712ecea27d544b466517ecf5ec99749 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -259,7 +259,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
     if (!e) {
         if (pos + 6 >= bufsize)
             goto full;
-        platform_strncpy(buf + pos, "(null)", 6);
+        util_strncpy(buf + pos, "(null)", 6);
         return pos + 6;
     }
 
@@ -268,7 +268,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
 
     switch (e->vtype) {
         case TYPE_VARIANT:
-            platform_strncpy(buf + pos, "(variant)", 9);
+            util_strncpy(buf + pos, "(variant)", 9);
             return pos + 9;
 
         case TYPE_FIELD:
@@ -314,7 +314,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
             if (pos + 1 >= bufsize)
                 goto full;
             buf[pos++] = '[';
-            pos += platform_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
+            pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
             if (pos + 1 >= bufsize)
                 goto full;
             buf[pos++] = ']';
@@ -325,7 +325,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
             typelen = strlen(typestr);
             if (pos + typelen >= bufsize)
                 goto full;
-            platform_strncpy(buf + pos, typestr, typelen);
+            util_strncpy(buf + pos, typestr, typelen);
             return pos + typelen;
     }
 
@@ -438,10 +438,27 @@ bool ast_value_set_name(ast_value *self, const char *name)
 ast_binary* ast_binary_new(lex_ctx_t ctx, int op,
                            ast_expression* left, ast_expression* right)
 {
-    ast_binary *fold;
     ast_instantiate(ast_binary, ctx, ast_binary_delete);
     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen);
 
+    if (ast_istype(right, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
+        ast_unary      *unary  = ((ast_unary*)right);
+        ast_expression *normal = unary->operand;
+
+        /* make a-(-b) => a + b */
+        if (unary->op == VINSTR_NEG_F || unary->op == VINSTR_NEG_V) {
+            if (op == INSTR_SUB_F) {
+                op = INSTR_ADD_F;
+                right = normal;
+                ++opts_optimizationcount[OPTIM_PEEPHOLE];
+            } else if (op == INSTR_SUB_V) {
+                op = INSTR_ADD_V;
+                right = normal;
+                ++opts_optimizationcount[OPTIM_PEEPHOLE];
+            }
+        }
+    }
+
     self->op = op;
     self->left = left;
     self->right = right;
@@ -450,11 +467,6 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, int op,
     ast_propagate_effects(self, left);
     ast_propagate_effects(self, right);
 
-    if (OPTS_OPTIMIZATION(OPTIM_PEEPHOLE) && (fold = (ast_binary*)fold_superfluous(left, right, op))) {
-        ast_binary_delete(self);
-        return fold;
-    }
-
     if (op >= INSTR_EQ_F && op <= INSTR_GT)
         self->expression.vtype = TYPE_FLOAT;
     else if (op == INSTR_AND || op == INSTR_OR) {
@@ -529,10 +541,8 @@ ast_unary* ast_unary_new(lex_ctx_t ctx, int op,
         ast_unary *prev = (ast_unary*)((ast_unary*)expr)->operand;
 
         /* Handle for double negation */
-        if ((((ast_unary*)expr)->op == VINSTR_NEG_V && op == VINSTR_NEG_V) ||
-            (((ast_unary*)expr)->op == VINSTR_NEG_F && op == VINSTR_NEG_F)) {
+        if (((ast_unary*)expr)->op == op)
             prev = (ast_unary*)((ast_unary*)expr)->operand;
-        }
 
         if (ast_istype(prev, ast_unary)) {
             ast_expression_delete((ast_expression*)self);
@@ -1214,6 +1224,9 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype
     self->fixedparams      = NULL;
     self->return_value     = NULL;
 
+    self->static_names     = NULL;
+    self->static_count     = 0;
+
     return self;
 
 cleanup:
@@ -1235,6 +1248,9 @@ void ast_function_delete(ast_function *self)
          */
         ast_unref(self->vtype);
     }
+    for (i = 0; i < vec_size(self->static_names); ++i)
+        mem_d(self->static_names[i]);
+    vec_free(self->static_names);
     for (i = 0; i < vec_size(self->blocks); ++i)
         ast_delete(self->blocks[i]);
     vec_free(self->blocks);
@@ -1463,12 +1479,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
 
             namelen = strlen(self->name);
             name    = (char*)mem_a(namelen + 16);
-            platform_strncpy(name, self->name, namelen);
+            util_strncpy(name, self->name, namelen);
 
             array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
             array->ir_values[0] = v;
             for (ai = 1; ai < array->expression.count; ++ai) {
-                platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+                util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
                 array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
                 if (!array->ir_values[ai]) {
                     mem_d(name);
@@ -1532,12 +1548,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
 
         namelen = strlen(self->name);
         name    = (char*)mem_a(namelen + 16);
-        platform_strncpy(name, self->name, namelen);
+        util_strncpy(name, self->name, namelen);
 
         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
         self->ir_values[0] = v;
         for (ai = 1; ai < self->expression.count; ++ai) {
-            platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+            util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
             self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
             if (!self->ir_values[ai]) {
                 mem_d(name);
@@ -1677,11 +1693,11 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
 
         namelen = strlen(self->name);
         name    = (char*)mem_a(namelen + 16);
-        platform_strncpy(name, self->name, namelen);
+        util_strncpy(name, self->name, namelen);
 
         self->ir_values[0] = v;
         for (ai = 1; ai < self->expression.count; ++ai) {
-            platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+            util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
             self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
             if (!self->ir_values[ai]) {
                 compile_error(ast_ctx(self), "internal_error: ir_builder_create_global failed on `%s`", name);
@@ -1794,6 +1810,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
     ir_value    *dummy;
     ast_expression         *ec;
     ast_expression_codegen *cgen;
+
     size_t    i;
 
     (void)ir;