History

Optimize small structure copying on x86_64

Ziyao committed 4 years ago

Commit 3715f1d1 parent fe7ee115 files · +98 −2Browse files

Unified · Split

5 files
  1. lib/bcheck.c +12 −0
  2. tcc.h +2 −0
  3. tccgen.c +33 −2
  4. tcctok.h +1 −0
  5. x86_64-gen.c +50 −0
lib/bcheck.c+12−0
@@ -292,6 +292,7 @@ DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n); · 291 unmodified lines
292DLL_EXPORT char *__bound_strcat(char *dest, const char *src);292DLL_EXPORT char *__bound_strcat(char *dest, const char *src);
293DLL_EXPORT char *__bound_strchr(const char *string, int ch);293DLL_EXPORT char *__bound_strchr(const char *string, int ch);
294DLL_EXPORT char *__bound_strdup(const char *s);294DLL_EXPORT char *__bound_strdup(const char *s);
295DLL_EXPORT void __bound_struct_copy(void *dst,void *src,size_t size);
295 296
296#if defined(__arm__) && defined(__ARM_EABI__)297#if defined(__arm__) && defined(__ARM_EABI__)
297DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size);298DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size);
@@ -424,6 +425,7 @@ static unsigned long long bound_strncmp_count; · 126 unmodified lines
424static unsigned long long bound_strcat_count;425static unsigned long long bound_strcat_count;
425static unsigned long long bound_strchr_count;426static unsigned long long bound_strchr_count;
426static unsigned long long bound_strdup_count;427static unsigned long long bound_strdup_count;
428static unsigned long long bound_struct_copy_count;
427static unsigned long long bound_not_found;429static unsigned long long bound_not_found;
428#define INCR_COUNT(x) ++x430#define INCR_COUNT(x) ++x
429#else431#else
@@ -1765,6 +1767,16 @@ void *__bound_memset(void *s, int c, size_t n) · 1335 unmodified lines
1765 return memset(s, c, n);1767 return memset(s, c, n);
1766}1768}
1767 1769
1770void __bound_struct_copy(void *dst,void *src,size_t size)
1771{
1772 dprintf(stderr, "Copy struct from %p to %p,size %lx\n",
1773 src,dst,size);
1774 INCR_COUNT(bound_struct_copy_count);
1775 __bound_check(dst,size,"struct copy destination");
1776 __bound_check(src,size,"struct copy source");
1777 return;
1778}
1779
1768#if defined(__arm__) && defined(__ARM_EABI__)1780#if defined(__arm__) && defined(__ARM_EABI__)
1769void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n)1781void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n)
1770{1782{
tcc.h+2−0
@@ -1644,6 +1644,8 @@ ST_FUNC void gen_increment_tcov (SValue *sv); · 1643 unmodified lines
1644 1644
1645/* ------------ x86_64-gen.c ------------ */1645/* ------------ x86_64-gen.c ------------ */
1646#ifdef TCC_TARGET_X86_641646#ifdef TCC_TARGET_X86_64
1647#define TCC_TARGET_NATIVE_STRUCT_COPY
1648ST_FUNC void gen_struct_copy(int size);
1647ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);1649ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
1648ST_FUNC void gen_opl(int op);1650ST_FUNC void gen_opl(int op);
1649#ifdef TCC_TARGET_PE1651#ifdef TCC_TARGET_PE
tccgen.c+33−2
@@ -3474,9 +3474,38 @@ ST_FUNC void vstore(void) · 3473 unmodified lines
3474 if (sbt == VT_STRUCT) {3474 if (sbt == VT_STRUCT) {
3475 /* if structure, only generate pointer */3475 /* if structure, only generate pointer */
3476 /* structure assignment : generate memcpy */3476 /* structure assignment : generate memcpy */
3477 /* XXX: optimize if small size */
3478 size = type_size(&vtop->type, &align);3477 size = type_size(&vtop->type, &align);
3479 3478
3479#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
3480 if (size <= (PTR_SIZE << 4)) {
3481 vswap();
3482#ifdef CONFIG_TCC_BCHECK
3483 if (vtop->r & VT_MUSTBOUND)
3484 gbound();
3485#endif
3486 vtop->type.t = VT_PTR;
3487 gaddrof();
3488
3489 vpushv(vtop - 1);
3490#ifdef CONFIG_TCC_BCHECK
3491 if (vtop->r & VT_MUSTBOUND)
3492 gbound();
3493#endif
3494 vtop->type.t = VT_PTR;
3495 gaddrof(); /* src dest src */
3496#ifdef CONFIG_TCC_BCHECK
3497 if (tcc_state->do_bounds_check) {
3498 vpush_helper_func(TOK___bound_struct_copy);
3499 vpushv(vtop - 2);
3500 vpushv(vtop - 2);
3501 vpushi(size);
3502 gfunc_call(3);
3503 }
3504#endif
3505
3506 gen_struct_copy(size);
3507 } else {
3508#endif
3480 /* destination */3509 /* destination */
3481 vswap();3510 vswap();
3482#ifdef CONFIG_TCC_BCHECK3511#ifdef CONFIG_TCC_BCHECK
@@ -3510,7 +3539,9 @@ ST_FUNC void vstore(void) · 27 unmodified lines
3510 vpushi(size);3539 vpushi(size);
3511 gfunc_call(3);3540 gfunc_call(3);
3512 /* leave source on stack */3541 /* leave source on stack */
3513 3542#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
3543 }
3544#endif
3514 } else if (ft & VT_BITFIELD) {3545 } else if (ft & VT_BITFIELD) {
3515 /* bitfield store handling */3546 /* bitfield store handling */
3516 3547
tcctok.h+1−0
@@ -330,6 +330,7 @@ · 329 unmodified lines
330 DEF(TOK___bound_setjmp, "__bound_setjmp")330 DEF(TOK___bound_setjmp, "__bound_setjmp")
331 DEF(TOK___bound_longjmp, "__bound_longjmp")331 DEF(TOK___bound_longjmp, "__bound_longjmp")
332 DEF(TOK___bound_new_region, "__bound_new_region")332 DEF(TOK___bound_new_region, "__bound_new_region")
333 DEF(TOK___bound_struct_copy,"__bound_struct_copy")
333# ifdef TCC_TARGET_PE334# ifdef TCC_TARGET_PE
334# ifdef TCC_TARGET_X86_64335# ifdef TCC_TARGET_X86_64
335 DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")336 DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
x86_64-gen.c+50−0
@@ -2282,6 +2282,56 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2281 unmodified lines
2282 }2282 }
2283}2283}
2284 2284
2285/*
2286 * Assmuing the top part of the stack looks like below,
2287 * src dest src
2288 */
2289void gen_struct_copy(int size)
2290{
2291 save_reg(TREG_RSI);
2292 load(TREG_RSI,vtop);
2293 vtop->r = TREG_RSI;
2294 vswap(); /* dest src src */
2295 save_reg(TREG_RDI);
2296 load(TREG_RDI,vtop);
2297 vtop->r = TREG_RDI;
2298 /* Not aligned by 8bytes */
2299 if (size & 0x04) {
2300 o(0xa5);
2301 }
2302 if (size & 0x02) {
2303 o(0xa566);
2304 }
2305 if (size & 0x01) {
2306 o(0xa4);
2307 }
2308
2309 size >>= 3;
2310 if (!size)
2311 goto done;
2312 /* Although this function is only called when the struct is smaller */
2313 /* than 32 bytes(4 * PTR_SIZE),a common implementation is included */
2314 if (size <= 4 && size) {
2315 switch (size) {
2316 case 4: o(0xa548);
2317 case 3: o(0xa548);
2318 case 2: o(0xa548);
2319 case 1: o(0xa548);
2320 }
2321 } else {
2322 save_reg(TREG_RCX);
2323 vpushi(size);
2324 load(TREG_RCX,vtop);
2325 vtop->r = TREG_RCX;
2326 o(0xa548f3);
2327 vpop();
2328 }
2329done:
2330 vpop();
2331 vpop();
2332 return;
2333}
2334
2285 2335
2286/* end of x86-64 code generator */2336/* end of x86-64 code generator */
2287/*************************************************************/2337/*************************************************************/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t