rjc@CS.UCLA.EDU (Robert Collins) (10/28/89)
Sun4/300, SunOS 4.0.3, g++ Oct 17
Not a bug report--just a question: This is optimized code?
I compiled with -O and -S only. The output looks *quite* sub-optimal to
my untrained eye. I would especially like to see the conditional in +=
to be evaluated at compile-time. This would allow the removal of the
test and branch of the conditional that is not used.
This sort of optimization would make me happy. This would reduce my
run-time and cut my object files to a fraction of their current size!
(I have *lots* of code that does this sort of thing) Is there any
chance for this sort of agressive optimization? Am I dreaming the
impossible dream? Do I need to declare more things const??
Sub-optimally yours,
rob collins
rjc@cs.ucla.edu
---------------------------------------------------------------------------
extern "C" {
typedef int CM_field_id_t;
CM_field_id_t CM_allocate_heap_field(unsigned);
void CM_deallocate_heap_field(CM_field_id_t);
void CM_s_add_2_1L(CM_field_id_t d, CM_field_id_t s, unsigned l);
void CM_s_add_3_3L(CM_field_id_t d, CM_field_id_t s1, CM_field_id_t s2,
unsigned dl, unsigned s1l, unsigned s2l);
};
class CM_int;
void CM_add(const CM_int& dest, const CM_int& source);
class CM_int {
private:
const CM_field_id_t the_field;
const unsigned the_length;
public:
CM_int(unsigned l);
~CM_int(void);
unsigned length(void) const;
operator CM_field_id_t() const;
void operator+=(const CM_int&);
};
inline CM_int::CM_int(unsigned l) : the_length(l),
the_field(CM_allocate_heap_field(the_length))
{
}
inline CM_int::~CM_int(void)
{
CM_deallocate_heap_field(the_field);
}
inline unsigned CM_int::length(void) const
{
return the_length;
}
inline CM_int::operator CM_field_id_t() const
{
return the_field;
}
inline void CM_int::operator+=(const CM_int& rhs)
{
//CM_add(*this, rhs);
if (length() == rhs.length()) {
CM_s_add_2_1L(*this, rhs, length());
}
else {
CM_s_add_3_3L(*this, *this, rhs, length(), length(),
rhs.length());
};
}
inline void CM_add(const CM_int& dest, const CM_int& source)
{
if (dest.length() == source.length()) {
CM_s_add_2_1L(dest, source, dest.length());
}
else {
CM_s_add_3_3L(dest, dest, source, dest.length(), dest.length(),
source.length());
};
}
main()
{
CM_int a(32), b(32);
a += b;
CM_int c(32), d(16);
c += d;
}
---------------------------------------------------------------------------
gcc_compiled.:
.text
.align 4
.global _main
.proc 1
_main:
!#PROLOGUE# 0
save %sp,-144,%sp
!#PROLOGUE# 1
call ___main,0
nop
add %fp,-24,%l0
mov 32,%l2
st %l2,[%l0+4]
call _CM_allocate_heap_field,0
mov 32,%o0
st %o0,[%l0]
add %fp,-32,%l1
mov 32,%l2
st %l2,[%l1+4]
call _CM_allocate_heap_field,0
mov 32,%o0
mov %o0,%o1
st %o1,[%l1]
mov %l0,%o2
mov %l1,%o5
ld [%o2+4],%o3
ld [%o5+4],%o0
cmp %o3,%o0
bne L75
nop
ld [%o2],%o0
call _CM_s_add_2_1L,0
mov %o3,%o2
b,a L74
L75:
ld [%o2],%o1
ld [%o2+4],%o4
mov %o1,%o0
ld [%o5],%o2
mov %o4,%o3
call _CM_s_add_3_3L,0
ld [%o5+4],%o5
L74:
add %fp,-40,%l0
mov 32,%l2
st %l2,[%l0+4]
call _CM_allocate_heap_field,0
mov 32,%o0
st %o0,[%l0]
add %fp,-48,%l1
mov 16,%l2
st %l2,[%l1+4]
call _CM_allocate_heap_field,0
mov 16,%o0
mov %o0,%o1
st %o1,[%l1]
mov %l0,%o2
mov %l1,%o5
ld [%o2+4],%o3
ld [%o5+4],%o0
cmp %o3,%o0
bne L91
nop
ld [%o2],%o0
call _CM_s_add_2_1L,0
mov %o3,%o2
b,a L90
L91:
ld [%o2],%o1
ld [%o2+4],%o4
mov %o1,%o0
ld [%o5],%o2
mov %o4,%o3
call _CM_s_add_3_3L,0
ld [%o5+4],%o5
L90:
call _CM_deallocate_heap_field,0
ld [%fp-48],%o0
call _CM_deallocate_heap_field,0
ld [%fp-40],%o0
call _CM_deallocate_heap_field,0
ld [%fp-32],%o0
call _CM_deallocate_heap_field,0
ld [%fp-24],%o0
mov 0,%i0
ret
restore
---------------------------------------------------------------------------