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;
}