tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Optimize Copying Small Structures


From: Ziyao
Subject: [Tinycc-devel] Optimize Copying Small Structures
Date: Fri, 8 Jul 2022 21:00:17 +0800

Hi list,

I am working on deal with the calls to memcpy() and memmove() in native
code generated by TinyCC.As of now,I have made this patch to optimize
the copying of small-sized structures.

But it seems to break a test (112_backtrace). I am not familiar with the
bound check part of TinyCC.Could anyone try this patch and give me some
help about bound check?

Tons of thanks for your help

Ziyao

---

diff --git a/tcc.h b/tcc.h
index 9bc12e3..34db372 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1644,6 +1644,8 @@ ST_FUNC void gen_increment_tcov (SValue *sv);
 
 /* ------------ x86_64-gen.c ------------ */
 #ifdef TCC_TARGET_X86_64
+#define TCC_TARGET_NATIVE_STRUCT_COPY
+ST_FUNC void gen_struct_copy(int size);
 ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
 ST_FUNC void gen_opl(int op);
 #ifdef TCC_TARGET_PE
diff --git a/tccgen.c b/tccgen.c
index c170ff3..5e7e002 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3474,9 +3474,37 @@ ST_FUNC void vstore(void)
     if (sbt == VT_STRUCT) {
         /* if structure, only generate pointer */
         /* structure assignment : generate memcpy */
-        /* XXX: optimize if small size */
             size = type_size(&vtop->type, &align);
 
+#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
+            if (size <= (PTR_SIZE << 4)) {
+                   vswap();
+#ifdef CONFIG_TCC_BCHECK
+                    if (vtop->r & VT_MUSTBOUND)
+                        gbound();
+#endif
+                    vtop->type.t = VT_PTR;
+                    gaddrof();
+#ifdef CONFIG_TCC_BCHECK
+                    if (vtop->r & VT_MUSTBOUND)
+                        gbound();
+#endif
+
+                    vpushv(vtop - 1);
+#ifdef CONFIG_TCC_BCHECK
+                    if (vtop->r & VT_MUSTBOUND)
+                        gbound();
+#endif
+                    vtop->type.t = VT_PTR;
+                    gaddrof();                  /* src dest src */
+#ifdef CONFIG_TCC_BCHECK
+                    if (vtop->r & VT_MUSTBOUND)
+                        gbound();
+#endif
+
+                    gen_struct_copy(size);
+            } else {
+#endif
             /* destination */
             vswap();
 #ifdef CONFIG_TCC_BCHECK
@@ -3510,7 +3538,9 @@ ST_FUNC void vstore(void)
             vpushi(size);
             gfunc_call(3);
         /* leave source on stack */
-
+#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
+            }
+#endif
     } else if (ft & VT_BITFIELD) {
         /* bitfield store handling */
 
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 29871d5..cad4da1 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -2282,6 +2282,56 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
     }
 }
 
+/*
+ * Assmuing the top part of the stack looks like below,
+ *  src dest src
+ */
+void gen_struct_copy(int size)
+{
+    save_reg(TREG_RSI);
+    load(TREG_RSI,vtop);
+    vtop->r = TREG_RSI;
+    vswap();                    /* dest src src */
+    save_reg(TREG_RDI);
+    load(TREG_RDI,vtop);
+    vtop->r = TREG_RDI;
+    /*  Not aligned by 8bytes   */
+    if (size & 0x04) {
+        o(0xa5);
+    }
+    if (size & 0x02) {
+        o(0xa566);
+    }
+    if (size & 0x01) {
+        o(0xa4);
+    }
+
+    size >>= 3;
+    if (!size)
+        goto done;
+    /*  Although this function is only called when the struct is smaller    */
+    /*  than 32 bytes(4 * PTR_SIZE),a common implementation is included     */
+    if (size <= 4 && size) {
+        switch (size) {
+            case 4: o(0xa548);
+            case 3: o(0xa548);
+            case 2: o(0xa548);
+            case 1: o(0xa548);
+        }
+    } else {
+        save_reg(TREG_RCX);
+        vpushi(size);
+        load(TREG_RCX,vtop);
+        vtop->r = TREG_RCX;
+        o(0xa548f3);
+        vpop();
+    }
+done:
+    vpop();
+    vpop();
+    return;
+}
+
 
 /* end of x86-64 code generator */
 /*************************************************************/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]