* Performance problem: unaligned loads/stores on structure assignments on MIPS
@ 2007-02-25 21:44 Simon Kagstrom
2007-02-27 6:07 ` Ian Lance Taylor
0 siblings, 1 reply; 2+ messages in thread
From: Simon Kagstrom @ 2007-02-25 21:44 UTC (permalink / raw)
To: gcc-help
[-- Attachment #1: Type: text/plain, Size: 2711 bytes --]
Hello!
GCC 4.1 seems to sometimes generate inefficient code when doing
structure assignments directly when compiling for MIPS1. When assigning
to structure members manually, it generates regular lw/sw sequences.
When assigning to the structure, you instead get lwl/lwr and swl/swr
pairs (for no reason, since the data is aligned).
I'm translating the MIPS code to Java bytecode, so the problem is even
worse for me as I then have to read four separate bytes and or
these together to implement a lwl/lwr pair.
I've attached a preprocessed file which exhibits this behavior. The two
functions below show this, the first doing a structure assignment and
the second member assignment.
void dummy1(NavigateSegment *segments,
int count,
RoadMapPosition *src_pos,
RoadMapPosition *dst_pos) {
int i;
int group_id = 0;
NavigateSegment *segment;
for (i=0; i < count; i++) {
set_from_pos (&segments[i].from_pos);
segments[i].shape_initial_pos = segments[i].from_pos;
}
}
void dummy2(NavigateSegment *segments,
int count,
RoadMapPosition *src_pos,
RoadMapPosition *dst_pos) {
int i;
int group_id = 0;
NavigateSegment *segment;
for (i=0; i < count; i++) {
set_from_pos (&segments[i].from_pos);
segments[i].shape_initial_pos.longitude = segments[i].from_pos.longitude;
segments[i].shape_initial_pos.latitude = segments[i].from_pos.latitude;
}
}
And if you disassemble it you see that they look like
00000014 <dummy1>:
14: 00003021 move a2,zero
18: 240804d2 li t0,1234
1c: 08000014 j 50 <dummy1+0x3c>
20: 2407162e li a3,5678
24: ac88001c sw t0,28(a0)
28: ac870020 sw a3,32(a0)
2c: 8882001c lwl v0,28(a0)
30: 88830020 lwl v1,32(a0)
...
00000064 <dummy2>:
64: 00001821 move v1,zero
68: 240604d2 li a2,1234
6c: 08000022 j 88 <dummy2+0x24>
70: 2407162e li a3,5678
74: ac870020 sw a3,32(a0)
78: ac86001c sw a2,28(a0)
7c: ac86002c sw a2,44(a0)
80: ac870030 sw a3,48(a0)
....
If the loop is removed, both functions generate the same code (with
regular loads/stores). The GCC version is
mips-linux-gnu-gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Should I consider this a bug and report it to the bug tracking system?
I looked for similar problems, but couldn't find any matching bug report.
(Ehud Shabtai discovered this problem)
--
// Simon
[-- Attachment #2: main.i --]
[-- Type: application/octet-stream, Size: 31664 bytes --]
# 1 "main.c"
# 1 "/home/ska/projects/private/games/cibyl/trunk/examples/j2me-test/c//"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "main.c"
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h" 1
# 15 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h"
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/cibyl.h" 1
# 25 "/home/ska/projects/private/games/cibyl/trunk/include/cibyl.h"
typedef int bool_t;
typedef int NOPH_Exception_t;
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/cibyl-syscall_defs.h" 1
# 35 "/home/ska/projects/private/games/cibyl/trunk/include/cibyl.h" 2
register NOPH_Exception_t NOPH_exception asm("$26");
# 16 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h" 2
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h" 1
# 152 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h"
typedef int ptrdiff_t;
# 214 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h"
typedef unsigned int size_t;
# 326 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h"
typedef int wchar_t;
# 17 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h" 2
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdarg.h" 1
# 43 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdarg.h"
typedef __builtin_va_list __gnuc_va_list;
# 105 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdarg.h"
typedef __gnuc_va_list va_list;
# 18 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h" 2
static inline int __puts(const char* string) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__puts" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(string) : "memory" ); return (int) __v0; };
static inline int __putchar(int c) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__putchar" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(c) : "memory" ); return (int) __v0; };
# 35 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdio.h"
typedef int FILE;
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
static inline FILE* fopen(const char* path, const char* mode) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fopen" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(path), "r"(mode) : "memory" ); return (FILE*) __v0; };
static inline int fclose(FILE* fp) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fclose" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(fp) : "memory" ); return (int) __v0; };
static inline void clearerr(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "clearerr" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (void) __v0; };
static inline int feof(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "feof" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (int) __v0; };
static inline int ferror(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "ferror" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (int) __v0; };
static inline int favail(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "favail" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (int) __v0; };
static inline int fseek(FILE* stream, long offset, int whence) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fseek" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream), "r"(offset), "r"(whence) : "memory" ); return (int) __v0; };
static inline int fflush(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fflush" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (int) __v0; };
static inline int fgetc(FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fgetc" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(stream) : "memory" ); return (int) __v0; };
static inline char* fgets(char* s, int size, FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fgets" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s), "r"(size), "r"(stream) : "memory" ); return (char*) __v0; };
static inline int fputc(int c, FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fputc" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(c), "r"(stream) : "memory" ); return (int) __v0; };
static inline int fputs(const char* ptr, FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fputs" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(ptr), "r"(stream) : "memory" ); return (int) __v0; };
static inline size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".short 0xfefe\n" ".short %4\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fread" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(ptr), "r"(size), "r"(nmemb), "r"(stream) : "memory" ); return (size_t) __v0; };
static inline size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".short 0xfefe\n" ".short %4\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "fwrite" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(ptr), "r"(size), "r"(nmemb), "r"(stream) : "memory" ); return (size_t) __v0; };
extern int vsnprintf(char* str, unsigned int size, const char* format, va_list ap);
extern int vprintf(const char* format, va_list ap);
extern int snprintf(char *buf, size_t n, const char *fmt, ...);
extern int fprintf(FILE *fp, const char* fmt, ...);
extern int printf(const char* fmt, ...);
static inline void __setup_io(FILE* addr_stdin, FILE* addr_stdout, FILE* addr_stderr) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__setup_io" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(addr_stdin), "r"(addr_stdout), "r"(addr_stderr) : "memory" ); return (void) __v0; };
# 2 "main.c" 2
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdlib.h" 1
# 16 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdlib.h"
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h" 1
# 17 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdlib.h" 2
static inline void exit(int code) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "exit" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(code) : "memory" ); return (void) __v0; };
extern void* malloc(size_t size);
extern void free(void* ptr);
extern int isdigit(int c);
extern int isspace(int c);
extern long int strtol(const char *nptr, char **endptr, int base);
extern float atof(const char *nptr);
extern int atoi(const char *nptr);
static inline int rand(void) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "rand" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : : "memory" ); return (int) __v0; };
static inline void srand(unsigned int seed) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "srand" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(seed) : "memory" ); return (void) __v0; };
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/string.h" 1
# 16 "/home/ska/projects/private/games/cibyl/trunk/include/generated/string.h"
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stddef.h" 1
# 17 "/home/ska/projects/private/games/cibyl/trunk/include/generated/string.h" 2
static inline char* __strcpy(char* dest, const char* src) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strcpy" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(dest), "r"(src) : "memory" ); return (char*) __v0; };
static inline char* __strncpy(char* dest, const char* src, size_t n) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strncpy" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(dest), "r"(src), "r"(n) : "memory" ); return (char*) __v0; };
static inline char* __strcat(char* dest, const char* src) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strcat" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(dest), "r"(src) : "memory" ); return (char*) __v0; };
static inline char* __strncat(char* dest, const char* src, size_t n) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strncat" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(dest), "r"(src), "r"(n) : "memory" ); return (char*) __v0; };
static inline int __strcmp(const char* s1, const char* s2) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strcmp" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s1), "r"(s2) : "memory" ); return (int) __v0; };
static inline int __strncmp(const char* s1, const char* s2, size_t n) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strncmp" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s1), "r"(s2), "r"(n) : "memory" ); return (int) __v0; };
static inline size_t __strlen(const char* s) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__strlen" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s) : "memory" ); return (size_t) __v0; };
static inline void* __memset(void* s, int c, size_t n) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__memset" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s), "r"(c), "r"(n) : "memory" ); return (void*) __v0; };
static inline int __memcmp(const void* s1, const void* s2, size_t n) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".short 0xfefe\n" ".short %2\n" ".short 0xfefe\n" ".short %3\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "__memcmp" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(s1), "r"(s2), "r"(n) : "memory" ); return (int) __v0; };
extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t n);
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
extern int strcmp(const char* s1, const char* s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t n);
extern size_t strlen(const char *s);
extern void *memset(void *s, int c, size_t n);
extern void *memcpy(void *dest, const void *src, size_t n);
extern int memcmp(const void* s1, const void* s2, size_t n);
extern char *strchr(const char *s, int c);
extern char *strrchr(const char *s, int c);
extern char *strdup(const char *s);
extern char *strstr(const char *haystack, const char *needle);
static inline void *memmove(void *dest, const void *src, size_t n) {
return memcpy(dest, src, n);
}
# 34 "/home/ska/projects/private/games/cibyl/trunk/include/generated/stdlib.h" 2
static inline void *calloc(size_t nmemb, size_t size)
{
void *out = (void*)malloc(nmemb * size);
memset(out, 0, nmemb * size);
return out;
}
static inline void *realloc(void *ptr, size_t size)
{
void *out = (void*)malloc(size);
if (ptr) {
memcpy (out, ptr, size);
free(ptr);
}
return out;
}
static inline int abs(int x)
{
if (x > 0) return x;
else return -x;
}
# 3 "main.c" 2
# 1 "/home/ska/projects/private/games/cibyl/trunk/include/generated/time.h" 1
# 17 "/home/ska/projects/private/games/cibyl/trunk/include/generated/time.h"
typedef int time_t;
static inline time_t time(time_t* t) { register unsigned long __v0 asm("$2"); __asm__ volatile ( ".set push\n.set noreorder\n" ".short 0xfefe\n" ".short %1\n" ".section .cibylstrtab, \"aS\"\n" "1: .asciz \"" "time" "\"\n" ".section .text\n" ".long 1b\n" ".set\tpop\n" : "=r" (__v0) : "r"(t) : "memory" ); return (time_t) __v0; };
# 4 "main.c" 2
# 1 "navigate_main.h" 1
# 28 "navigate_main.h"
# 1 "roadmap_canvas.h" 1
# 33 "roadmap_canvas.h"
# 1 "roadmap_gui.h" 1
# 27 "roadmap_gui.h"
# 1 "roadmap_types.h" 1
# 29 "roadmap_types.h"
typedef unsigned short RoadMapZip;
typedef unsigned short RoadMapString;
typedef unsigned char LineRouteFlag;
typedef unsigned char LineRouteMax;
typedef unsigned short LineRouteTime;
typedef struct {
int longitude;
int latitude;
} RoadMapPosition;
typedef struct {
int first;
int count;
} RoadMapSortedList;
typedef struct {
int east;
int north;
int west;
int south;
} RoadMapArea;
typedef void (*RoadMapShapeItr) (int shape, RoadMapPosition *position);
# 28 "roadmap_gui.h" 2
typedef struct {
int x;
int y;
} RoadMapGuiPoint;
typedef struct {
int minx;
int miny;
int maxx;
int maxy;
} RoadMapGuiRect;
# 34 "roadmap_canvas.h" 2
enum { IMAGE_NORMAL,
IMAGE_SELECTED
};
struct roadmap_canvas_pen;
typedef struct roadmap_canvas_pen *RoadMapPen;
struct roadmap_canvas_image;
typedef struct roadmap_canvas_image *RoadMapImage;
typedef void (*RoadMapCanvasMouseHandler) (RoadMapGuiPoint *point);
typedef void (*RoadMapCanvasConfigureHandler) (void);
void roadmap_canvas_register_button_pressed_handler
(RoadMapCanvasMouseHandler handler);
void roadmap_canvas_register_button_released_handler
(RoadMapCanvasMouseHandler handler);
void roadmap_canvas_register_mouse_move_handler
(RoadMapCanvasMouseHandler handler);
void roadmap_canvas_register_configure_handler
(RoadMapCanvasConfigureHandler handler);
void roadmap_canvas_get_text_extents
(const char *text, int size, int *width,
int *ascent, int *descent, int *can_tilt);
RoadMapPen roadmap_canvas_create_pen (const char *name);
RoadMapPen roadmap_canvas_select_pen (RoadMapPen pen);
void roadmap_canvas_set_foreground (const char *color);
void roadmap_canvas_set_thickness (int thickness);
int roadmap_canvas_get_thickness (RoadMapPen pen);
void roadmap_canvas_set_opacity (int opacity);
void roadmap_canvas_erase (void);
void roadmap_canvas_erase_area (const RoadMapGuiRect *rect);
# 123 "roadmap_canvas.h"
void roadmap_canvas_draw_string (RoadMapGuiPoint *position,
int corner,
const char *text);
void roadmap_canvas_draw_string_angle (const RoadMapGuiPoint *position,
RoadMapGuiPoint *center,
int angle, int size,
const char *text);
void roadmap_canvas_draw_multiple_points (int count, RoadMapGuiPoint *points);
void roadmap_canvas_draw_multiple_lines
(int count, int *lines, RoadMapGuiPoint *points, int fast_draw);
void roadmap_canvas_draw_multiple_polygons
(int count, int *polygons, RoadMapGuiPoint *points, int filled,
int fast_draw);
void roadmap_canvas_draw_multiple_circles
(int count, RoadMapGuiPoint *centers, int *radius, int filled,
int fast_draw);
int roadmap_canvas_width (void);
int roadmap_canvas_height (void);
void roadmap_canvas_refresh (void);
void roadmap_canvas_save_screenshot (const char* filename);
int roadmap_canvas_image_width (const RoadMapImage image);
int roadmap_canvas_image_height (const RoadMapImage image);
RoadMapImage roadmap_canvas_load_image (const char *path,
const char* file_name);
void roadmap_canvas_draw_image (RoadMapImage image, const RoadMapGuiPoint *pos,
int opacity, int mode);
void roadmap_canvas_copy_image (RoadMapImage dst_image,
const RoadMapGuiPoint *pos,
const RoadMapGuiRect *rect,
RoadMapImage src_image, int mode);
void roadmap_canvas_draw_image_text (RoadMapImage image,
const RoadMapGuiPoint *position,
int size, const char *text);
void roadmap_canvas_free_image (RoadMapImage image);
# 29 "navigate_main.h" 2
# 1 "roadmap_plugin.h" 1
# 29 "roadmap_plugin.h"
# 1 "roadmap_screen.h" 1
# 30 "roadmap_screen.h"
enum { VIEW_MODE_2D = 0,
VIEW_MODE_3D
};
enum { ORIENTATION_DYNAMIC = 0,
ORIENTATION_FIXED
};
void roadmap_screen_initialize (void);
void roadmap_screen_shutdown (void);
void roadmap_screen_set_initial_position (void);
void roadmap_screen_zoom_in (void);
void roadmap_screen_zoom_out (void);
void roadmap_screen_zoom_reset (void);
void roadmap_screen_move_up (void);
void roadmap_screen_move_down (void);
void roadmap_screen_move_right (void);
void roadmap_screen_move_left (void);
void roadmap_screen_toggle_view_mode (void);
void roadmap_screen_toggle_orientation_mode (void);
void roadmap_screen_increase_horizon (void);
void roadmap_screen_decrease_horizon (void);
void roadmap_screen_rotate (int delta);
void roadmap_screen_refresh (void);
void roadmap_screen_redraw (void);
void roadmap_screen_hold (void);
void roadmap_screen_freeze (void);
void roadmap_screen_unfreeze (void);
void roadmap_screen_get_center (RoadMapPosition *center);
typedef void (*RoadMapScreenSubscriber) (void);
RoadMapScreenSubscriber roadmap_screen_subscribe_after_refresh
(RoadMapScreenSubscriber handler);
void roadmap_screen_draw_one_line (RoadMapPosition *from,
RoadMapPosition *to,
int fully_visible,
RoadMapPosition *first_shape_pos,
int first_shape,
int last_shape,
RoadMapShapeItr shape_itr,
RoadMapPen pen,
int *total_length,
RoadMapGuiPoint *middle,
int *angle);
void roadmap_screen_draw_line_direction (RoadMapPosition *from,
RoadMapPosition *to,
RoadMapPosition *first_shape_pos,
int first_shape,
int last_shape,
RoadMapShapeItr shape_itr,
int width,
int direction);
int roadmap_screen_is_dragging (void);
# 115 "roadmap_screen.h"
void dbg_time_start(int type);
void dbg_time_end(int type);
# 30 "roadmap_plugin.h" 2
# 42 "roadmap_plugin.h"
typedef struct {
int plugin_id;
int line_id;
int cfcc;
int fips;
} PluginLine;
typedef struct {
int plugin_id;
int street_id;
} PluginStreet;
typedef struct {
const char *address;
const char *street;
const char *street_t2s;
const char *city;
PluginStreet plugin_street;
} PluginStreetProperties;
struct RoadMapNeighbour_t;
int roadmap_plugin_same_line (const PluginLine *line1, const PluginLine *line2);
int roadmap_plugin_same_street (const PluginStreet *street1,
const PluginStreet *street2);
void roadmap_plugin_get_street (const PluginLine *line, PluginStreet *street);
void roadmap_plugin_line_from (const PluginLine *line, RoadMapPosition *pos);
void roadmap_plugin_line_to (const PluginLine *line, RoadMapPosition *pos);
void roadmap_plugin_get_line_points (const PluginLine *line,
RoadMapPosition *from_pos,
RoadMapPosition *to_pos,
int *first_shape,
int *last_shape,
RoadMapShapeItr *shape_itr);
int roadmap_plugin_get_id (const PluginLine *line);
int roadmap_plugin_get_fips (const PluginLine *line);
int roadmap_plugin_get_line_id (const PluginLine *line);
int roadmap_plugin_get_line_cfcc (const PluginLine *line);
int roadmap_plugin_get_street_id (const PluginStreet *street);
void roadmap_plugin_set_line (PluginLine *line,
int plugin_id,
int line_id,
int cfcc,
int fips);
void roadmap_plugin_set_street (PluginStreet *street,
int plugin_id,
int street_id);
int roadmap_plugin_activate_db (const PluginLine *line);
int roadmap_plugin_get_distance
(const RoadMapPosition *point,
const PluginLine *line,
struct RoadMapNeighbour_t *result);
typedef int (*plugin_override_line_hook) (int line, int cfcc, int fips);
typedef int (*plugin_override_pen_hook) (int line,
int cfcc,
int fips,
int pen_type,
RoadMapPen *override_pen);
typedef void (*plugin_screen_repaint_hook) (int max_pen);
typedef int (*plugin_activate_db_func) (const PluginLine *line);
typedef void (*plugin_line_pos_func)
(const PluginLine *line, RoadMapPosition *pos);
typedef int (*plugin_get_distance_func)
(const RoadMapPosition *point,
const PluginLine *line,
struct RoadMapNeighbour_t *result);
typedef void (*plugin_get_street_func)
(const PluginLine *line, PluginStreet *street);
typedef const char *(*plugin_street_full_name_func)
(const PluginLine *line);
typedef void (*plugin_street_properties_func)
(const PluginLine *line, PluginStreetProperties *props);
typedef int (*plugin_find_connected_lines_func)
(const RoadMapPosition *crossing,
PluginLine *plugin_lines,
int max);
typedef void (*plugin_adjust_layer_hook)
(int layer, int thickness, int pen_count);
typedef int (*plugin_get_closest_func)
(const RoadMapPosition *position,
int *categories, int categories_count,
struct RoadMapNeighbour_t *neighbours, int count,
int max);
typedef int (*plugin_line_route_direction) (PluginLine *line, int who);
typedef void (*plugin_shutdown) (void);
typedef struct {
plugin_line_pos_func line_from;
plugin_line_pos_func line_to;
plugin_activate_db_func activate_db;
plugin_get_distance_func get_distance;
plugin_override_line_hook override_line;
plugin_override_pen_hook override_pen;
plugin_screen_repaint_hook screen_repaint;
plugin_get_street_func get_street;
plugin_street_full_name_func get_street_full_name;
plugin_street_properties_func get_street_properties;
plugin_find_connected_lines_func find_connected_lines;
plugin_adjust_layer_hook adjust_layer;
plugin_get_closest_func get_closest;
plugin_line_route_direction route_direction;
plugin_shutdown shutdown;
} RoadMapPluginHooks;
int roadmap_plugin_register (RoadMapPluginHooks *hooks);
void roadmap_plugin_unregister (int plugin_id);
int roadmap_plugin_override_line (int line, int cfcc, int fips);
int roadmap_plugin_override_pen (int line,
int cfcc,
int fips,
int pen_type,
RoadMapPen *override_pen);
void roadmap_plugin_screen_repaint (int max_pen);
const char *roadmap_plugin_street_full_name (const PluginLine *line);
void roadmap_plugin_get_street_properties (const PluginLine *line,
PluginStreetProperties *props);
int roadmap_plugin_find_connected_lines (RoadMapPosition *crossing,
PluginLine *plugin_lines,
int max);
void roadmap_plugin_adjust_layer (int layer,
int thickness,
int pen_count);
int roadmap_plugin_get_closest
(const RoadMapPosition *position,
int *categories, int categories_count,
struct RoadMapNeighbour_t *neighbours, int count,
int max);
int roadmap_plugin_get_direction (PluginLine *line, int who);
int roadmap_plugin_calc_length (const RoadMapPosition *position,
const PluginLine *line,
int *total_length);
void roadmap_plugin_shutdown (void);
# 30 "navigate_main.h" 2
enum NavigateInstr {
TURN_LEFT = 0,
TURN_RIGHT,
KEEP_LEFT,
KEEP_RIGHT,
CONTINUE,
APPROACHING_DESTINATION,
LAST_DIRECTION
};
typedef struct {
PluginLine line;
int line_direction;
PluginStreet street;
RoadMapPosition from_pos;
RoadMapPosition to_pos;
RoadMapPosition shape_initial_pos;
int first_shape;
int last_shape;
RoadMapShapeItr shape_itr;
enum NavigateInstr instruction;
int group_id;
int distance;
int cross_time;
} NavigateSegment;
int navigate_is_enabled (void);
void navigate_main_initialize (void);
int navigate_main_reload_data (void);
void navigate_main_set (int status);
int navigate_main_calc_route (void);
void navigate_main_screen_repaint (int max_pen);
int navigate_main_override_pen (int line,
int cfcc,
int fips,
int pen_type,
RoadMapPen *override_pen);
void navigate_main_adjust_layer (int layer, int thickness, int pen_count);
# 5 "main.c" 2
void set_from_pos (RoadMapPosition *pos) {
pos->longitude = 1234;
pos->latitude = 5678;
}
void dummy1(NavigateSegment *segments,
int count,
RoadMapPosition *src_pos,
RoadMapPosition *dst_pos) {
int i;
int group_id = 0;
NavigateSegment *segment;
for (i=0; i < count; i++) {
set_from_pos (&segments[i].from_pos);
segments[i].shape_initial_pos = segments[i].from_pos;
}
}
void dummy2(NavigateSegment *segments,
int count,
RoadMapPosition *src_pos,
RoadMapPosition *dst_pos) {
int i;
int group_id = 0;
NavigateSegment *segment;
for (i=0; i < count; i++) {
set_from_pos (&segments[i].from_pos);
segments[i].shape_initial_pos.longitude = segments[i].from_pos.longitude;
segments[i].shape_initial_pos.latitude = segments[i].from_pos.latitude;
}
}
int main(int argc, char *argv[])
{
NavigateSegment segments[10];
int i;
for (i=0; i<10; i++) {
segments[i].shape_initial_pos.longitude = 999;
segments[i].shape_initial_pos.latitude = 999;
}
dummy1(segments, 10, ((void *)0), ((void *)0));
printf ("We should get pairs of: 1234, 5678\n");
for (i=0; i<10; i++) {
printf("%d,%d ", segments[i].shape_initial_pos.longitude,
segments[i].shape_initial_pos.latitude);
}
printf("\n");
dummy2(segments, 10, ((void *)0), ((void *)0));
printf ("This one seems to do it right: 1234, 5678\n");
for (i=0; i<10; i++) {
printf("%d,%d ", segments[i].shape_initial_pos.longitude,
segments[i].shape_initial_pos.latitude);
}
printf("\n");
return 0;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Performance problem: unaligned loads/stores on structure assignments on MIPS
2007-02-25 21:44 Performance problem: unaligned loads/stores on structure assignments on MIPS Simon Kagstrom
@ 2007-02-27 6:07 ` Ian Lance Taylor
0 siblings, 0 replies; 2+ messages in thread
From: Ian Lance Taylor @ 2007-02-27 6:07 UTC (permalink / raw)
To: Simon Kagstrom; +Cc: gcc-help
Simon Kagstrom <simon.kagstrom@bth.se> writes:
> GCC 4.1 seems to sometimes generate inefficient code when doing
> structure assignments directly when compiling for MIPS1. When assigning
> to structure members manually, it generates regular lw/sw sequences.
> When assigning to the structure, you instead get lwl/lwr and swl/swr
> pairs (for no reason, since the data is aligned).
...
> Should I consider this a bug and report it to the bug tracking system?
> I looked for similar problems, but couldn't find any matching bug report.
This seems like a bug to me.
Ian
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-02-27 6:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-25 21:44 Performance problem: unaligned loads/stores on structure assignments on MIPS Simon Kagstrom
2007-02-27 6:07 ` Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).