ccplumb@rose.waterloo.edu (Colin Plumb) (10/21/89)
(Low-priority item... I'm much more annoyed at that "tried and true" tool, dbx. GDB isn't installed properly locally, so I gotta use this abomination of a debugger the hangs when asked to print a void *. Still, it seems worth mentioning) "I am only an egg" but this annoys me... When compiling some code that includes the structure: typedef struct _node { unsigned value:30; Colour lcolour:1, rcolour:1; Pointer left, right; } Node; On a VAX running 4.3BSD plus local hacks and GCC 1.36 (presumably the detailed environment is unnecessary), gcc -O -S spits out lots of extzv instructions when accessing the fields. I was hoping it would use masks. Writing the masks code myself on some heavily-used code (enclosed below... it's traversing a 2-3-4-tree implemented as a red-black tree) results in a >20% speedup. Ideally, checking one bit should test for negative if it's the high bit and use blb, tst or bb on others. The value field should be accessed as bicl3 $0xc0000000, (r0), r1, not extzv $0, $30, (r0), r1. Also, initialising all 3 bitfields on 3 consecutive lines results in an insv and two bisb2's instead of one 32-bit assignment. All this is both with and without -O. -fforce-mem, -fstrength-reduce and -fcombine-args do not change this behaviour. I keep crowing that GCC lets one stop trying to optimise the assembler output via source code, so it's annoying to be proved wrong... -- -Colin --- sample code --- typedef enum _colour { BLACK, RED } Colour; typedef union _pointer { void *v; struct _node *n; } Pointer; typedef struct _node { unsigned value:30; Colour lcolour:1, rcolour:1; Pointer left, right; } Node; typedef struct _tree { int size; int level; Pointer p; } Tree; void **index(Tree *t, register unsigned int i) { register int level = t->level; register Pointer *cur = &t->p; if (i >= t->size) return (void **)0; while (level--) { if (i < cur->n->value) { if(!cur->n->lcolour) { cur = &cur->n->left; continue; } cur = &cur->n->left; } else { i -= cur->n->value; if(!cur->n->rcolour) { cur = &cur->n->right; continue; } cur = &cur->n->right; } if (i < cur->n->value) { cur = &cur->n->left; } else { i -= cur->n->value; cur = &cur->n->right; } } return &cur->v; }